遍历三个变量

时间:2019-04-11 21:56:38

标签: python loops for-loop append

好吧,这将真的很长。我正在尝试在极坐标网格的分析解决方案中计算水位。它取决于r和theta以及此变量j。我要做的基本上是根据给定的方程式计算出网格中特定r,theta点的水位。该方程式的一部分对j的无限大值求和。等式的一部分在这里Equation image

其中一些代码如下:

"""
Plot idealized solution for water levels in a quarter circle domain with 
constant bathymetry  
"""
import numpy as np
import matplotlib.pyplot as plt
#from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show

# establish parameters
Ho = 300 #m
g = 9.81 #m/s2
r1 = 1000 #m
r2 = 10000 #m
rr = np.arange(r1,r2,10)
zeta = [0] * len(rr)
#radial size of domain
phi = np.pi/2
#theta is the angle in radians at a specific location within the domain
theta = np.pi/4

#converting from wind speed to wind shear stress
U = 10
Cd = (1/1000) * ((3/4) + (U/15))
Roair = 1.225 #kg/m3
Rowater = 997 #kg/m3

W = (Roair/Rowater) * Cd * (U**2)

#wind shear in m^2/s^2 in the 0 direction (W to E)
Wo = np.sqrt((W**2)/2)
#wind shear in m^2/s^2 in the phi direction 
Wphi = np.sqrt((W**2)/2)

#determines the bathymetry
n = 0
kappa = (1-n)**(0.5)
a_star = ( (np.sin(phi)) / (g*Ho*kappa* np.sin(kappa*theta)) )

#first half of equation 19 that does not depend on j 
for r in range(len(rr)):
    zeta[r] = ( a_star * (rr[r]**(1-n))*(Wo*np.cos(((1-n)**(0.5))*theta) + Wphi*np.cos(((1-n)**(0.5))*(theta-phi))) ) 

#plt.xlabel("rr")
#plt.ylabel("zeta")
###
#plt.plot(rr,zeta, label = 'LHS eq 19') 

#second half of equation 19 for j=0    
for r in range(len(rr)):
    j = 0
    Djo = np.sin(( ( (1-n)**(0.5) ) * phi ) ) / ( (1-n)**(0.5) * (phi) ) 
    Ejo = (np.sin(phi)) / (phi) 
    ajbj =  (r2**(1-n)) * (-a_star * Djo) 
    zeta[r] = zeta[r] + (ajbj)*(Wo+Wphi) 

#plt.xlabel("rr")
#plt.ylabel("zeta")
###
#plt.plot(rr,zeta, label = 'j=0') 

#second half of equation 19 for j=1,2,3 (summation) 

sj = []
tj = []
Dj = []
Ej = []
r1EogH = []
astarD = []
tjr1r2 = []
sjr2 = []
aj = []
bj = []

jj = [1,2,3]
for j in range(len(jj)):
    sj.append(- (n/2) + np.sqrt( ( (n/2)**2) + ( (jj[j]*np.pi / phi)**2) ) )
    tj.append (- (n/2) - np.sqrt( ( (n/2)**2) + ( (jj[j]*np.pi / phi)**2) ) )    
    Dj.append ( (2* ((-1)**jj[j]) * ((1-n)**(0.5)) * phi * np.sin( ((1-n)**(0.5)) * phi )) / ( (1-n) * (phi**2) - (jj[j]**2) * (np.pi**2) ) )
    Ej.append ( (2* ((-1)**jj[j]) * phi * np.sin(phi) ) / ( (phi**2) - (jj[j]**2) * (np.pi**2) ) )
    r1EogH.append ( ( (r1**(1-n)) * Ej[j] ) / ( g * Ho ) )
    astarD.append ( a_star * Dj[j] )
    tjr1r2.append ( tj[j] * (r1**tj[j]) * (r2**sj[j]) )
    sjr2.append ( sj[j] * (r2**tj[j]) )
    aj.append (   ( astarD[j] * (  ( tj[j] * (r1**tj[j]) * (r2**(1-n)) ) - ( (r2**tj[j]) * (r1**(1-n)) ) ) +  ( r1EogH[j] * r2**tj[j] ) ) / ( sjr2[j] * (r1**sj[j]) - tjr1r2[j] ) )
    bj.append (- ( astarD[j] * (  ( sj[j] * (r1**sj[j]) * (r2**(1-n)) ) - ( (r2**sj[j]) * (r1**(1-n)) ) ) -  ( r1EogH[j] * r2**sj[j] ) ) / ( sjr2[j] * (r2**sj[j]) - tjr1r2[j] ) ) 
    for r in range(len(rr)):
        zeta[r] = zeta[r] + ( ( (aj[j] * rr[r]**(sj[j])) + (bj[j] * rr[r]**(tj[j])) ) * (Wo*np.cos( (jj[j]*np.pi*theta)/phi)  +  Wphi*np.cos( (jj[j]*np.pi*(theta-phi))/phi)) )

plt.xlabel("rr")
plt.ylabel("zeta")
plt.title("Wind In at 45 degrees")
#
plt.plot(rr,zeta, label = 'Ho=100m') 

plt.legend(loc='upper right')

Solution for above 我为zeta获得的价值很大。它们应更类似于以下解决方案中theta PI / 4的值。我知道方程很复杂。我想要的是对网格中的某个点说r = 1000,theta = pi / 4,以便它计算j = 1,j = 2和j = 3的zeta值,然后将这些总和相加,然后执行相同的操作网格中每个点的东西。我想知道是否只需要以不同的方式构造循环?还是不使用.append函数?有人有建议吗?

完成THETA PI / 4

{{1}}

Solution for theta 45degrees

2 个答案:

答案 0 :(得分:1)

不幸的是,我不是数学向导。在尝试以某种方式重构之前,我试图运行您的代码以查看其输出。但是,由于提供的摘录中未定义sj中的sj.append()之类的内容,因此会出现错误。我不知道如何读懂图像中提供的方程式(数学课程是很多年前的,自大学以来就没有使用过。)

关于建议,在没有完全理解您的问题的情况下,我能为您提供的最好方法是考虑执行功能。这使您/其他人可以更清楚地看到代码。另一个优点是,当某些内容发生更改时(对于方程式来说似乎不太可能,但是也许您想在将来的某个时刻更改输入类型),更改会以较小的部分进行。

def calculate_j(point_or_other_necessary_input):
  """ do the maths for j """
  return some_equation_or_value_for_j

def calculate_t(point_or_other_necessary_input):
  """ do the maths for t """
  return some_equation_or_value_for_t

def calculate_r(point_or_other_necessary_input):
  """ do the maths for r """
  return some_equation_or_value_for_r

def process_grid(zeta_grid):
  """ process each point in the provided grid"""
  for point in zeta_grid:
    # or whatever makes sense to combine the values/equations
    calculated_sum = calculate_j(point) + calculate_t(point) + calculate_r(point)
    # store value in some reasonable way, probably another grid
  return calculated_points

print(process_grid(zeta))

经过进一步评估,并从您的编辑中获得了更多信息,我必须询问您是否真的想这样做:

jj = [1,2,3]
for j in range(len(jj)):

我不确定自己是否想让j依次为1,然后依次为23,不是吗?当前,您实际上得到了012,因为您要遍历列表的长度,而不是列表中的项目。这并不重要,这与在第一部分中使用jj[j]获取jj的值无关,而在r的部分中则使用j而不是jj[j],例如: / p>

zeta[r] = zeta[r] + ( ( (aj[j] * rr[r]**(sj[j])) + (bj[j] * rr[r]**(tj[j])) )

如上所述,这可能是您仅使用0,1,2而不是1,2,3的预期行为。关于为什么值可能太大的原因,您打算计算吗? r代表所有rr 3次?您将其嵌套在第一个for循环内,这意味着它正在for j in ...循环的每次迭代中执行。因此,它多次增加自身(zeta[r] = zeta[r] + ...)。 (再次,不是数学家)但是不是连续运行len(rr)^ 3次还是3 ^ len(rr)次?比预期的要多一些。

答案 1 :(得分:1)

建议编写一个可以用一些手工计算出的值进行测试的函数zeta(r,t,j):

def zeta(r, theta, j):
   #your complex calculations here

assert zeta(4000, pi/4, 2) == 0.00043 #This is a test to be sure your formulae 
                                      # are right (eyeballed from your graph)

然后遍历rr和theta以填充数组:

zeta_out = np.zeros((len(rr), len(Theta)))

for r in range(len(rr)):
    for t in range(len(theta)):
        zeta_out[r, t] = np.mean(zeta(rr[r], theta[t], j) for j in (1,2,3))