如何解决调整 Tensorflow2 代码 - 模拟反应扩散孤子以包括 3 个速度场
我正在尝试调整一个程序,该程序模拟由衬底 X、Y 和 G 组成的反应扩散孤子。该程序包括 Navier-Stokes 方程,以对衬底进行涡旋运动。
目前,代码根据速度场 u 和 v 为 X、Y 和 G 提供旋转/涡旋运动,表示此 2D 模拟中 x 和 y 方向的速度矢量。 z 轴为 X、Y 和 G 浓度电位。
在 1D 中它看起来像这样:
我想更改代码,使基板 X、Y 和 G 各自具有不同的速度(不仅仅是相同的速度)。 IE。 X 速度场 --> u_X 和 v_X 等。请有人帮我调整代码吗?
这是我目前所做的:
代码使用例如:python3 render_video.py ~/tf2-model-g/nucleation_and_motion_in_fluid_2D.mp4 --params params/nucleation_and_motion_in_fluid_2D.yaml
首先,我将 fluid_model_g________1st_attempt.py#L69 更改为:
elif self.dims == 2:
#self.u = tf.constant(u[0],'float64') # original 2 lines
#self.v = tf.constant(u[1],'float64')
#BJD adaptions - 6 lines below 9.6.2021
self.u_X = tf.constant(u[0],'float64')
self.v_X = tf.constant(u[1],'float64')
self.u_Y = tf.constant(u[2],'float64')
self.v_Y = tf.constant(u[3],'float64')
self.u_G = tf.constant(u[4],'float64')
self.v_G = tf.constant(u[5],'float64')
和 def diffusion_advection_integrator
@ fluid_model_g________1st_attempt.py#L159 :
def diffusion_advection_integrator(G,X,Y,u_X,v_X,u_Y,v_Y,u_G,v_G,divergence1,divergence2,divergence3): # BJD original 10.6.2021
f_G = self.fft(tf.cast(G,'complex128'))
f_X = self.fft(tf.cast(X,'complex128'))
f_Y = self.fft(tf.cast(Y,'complex128'))
f_G *= decay_G
f_X *= decay_X
f_Y *= decay_Y
G = tf.cast(self.ifft(f_G),'float64')
X = tf.cast(self.ifft(f_X),'float64')
Y = tf.cast(self.ifft(f_Y),'float64')
G_dx = tf.cast(self.ifft(f_G * self.kernel_dx),'float64')
G_dy = tf.cast(self.ifft(f_G * self.kernel_dy),'float64')
X_dx = tf.cast(self.ifft(f_X * self.kernel_dx),'float64')
X_dy = tf.cast(self.ifft(f_X * self.kernel_dy),'float64')
Y_dx = tf.cast(self.ifft(f_Y * self.kernel_dx),'float64')
Y_dy = tf.cast(self.ifft(f_Y * self.kernel_dy),'float64')
#G -= (u*G_dx + v*G_dy + G*divergence) * self.dt # BJD original
G -= (u_G*G_dx + v_G*G_dy + G*divergence1) * self.dt # BJD change 10.6.2021
#X -= (u*X_dx + v*X_dy + X*divergence) * self.dt # BJD original
#Y -= (u*Y_dx + v*Y_dy + Y*divergence) * self.dt # BJD original
X -= (u_X*X_dx + v_X*X_dy + X*divergence2) * self.dt # BJD change 10.6.2021
Y -= (u_Y*Y_dx + v_Y*Y_dy + Y*divergence3) * self.dt # BJD change 10.6.2021
return G,Y
原始代码显示在此处:fluid_model_g.py#L57 和此处显示:fluid_model_g.py#L119
新代码中包含 3 个单独的密度:@fluid_model_g________1st_attempt.py#L297
# rho = tf.math.log(self.params['base-density'] + density_of_reactants) # BJD original here
rho1 = tf.math.log(self.params['base-density1'] + density_of_reactants) # BJD added 10.6.2021
rho2 = tf.math.log(self.params['base-density2'] + density_of_reactants) # BJD added 10.6.2021
rho3 = tf.math.log(self.params['base-density3'] + density_of_reactants) # BJD added 10.6.2021
和 base-density1
、base-density2
和 base-density3
被添加到 yaml
文件中:
#base-density: 35.0 ~ BJD original here
base-density1: 35.0 # BJD added 10.6.2021
base-density2: 36.0 # BJD added 10.6.2021
base-density3: 37.0 # BJD added 10.6.2021
在 fluid_model_g.py
的底部,更改了以下几行:
if self.dims == 2:
#u,v = self.u,self.v # Store unintegrated flow so that we're on the same timestep --- BJD original line 9.6.2021
u_X,v_X = self.u_X,self.v_X # Store unintegrated flow so that we're on the same timestep --- BJD added 9.6.2021
u_Y,v_Y = self.u_Y,self.v_Y # Store unintegrated flow so that we're on the same timestep --- BJD added 9.6.2021
u_G,v_G = self.u_G,self.v_G # Store unintegrated flow so that we're on the same timestep --- BJD added 9.6.2021
#self.u,self.v,divergence = self.flow_integrator(rho,self.u,self.v) -BJD original line 9.6.2021
self.u_X,self.v_X,divergence1 = self.flow_integrator(rho1,self.u_X,self.v_X) #--- BJD added 9.6.2021
self.u_Y,self.v_Y,divergence2 = self.flow_integrator(rho2,self.u_Y,self.v_Y) #--- BJD added 9.6.2021
self.u_G,self.v_G,divergence3 = self.flow_integrator(rho3,self.u_G,self.v_G) #--- BJD added 9.6.2021
#self.G,self.X,self.Y = self.diffusion_advection_integrator(self.G,self.Y,u,v,divergence) # BJD original line 10.6.2021
self.G,divergence3) #--- BJD added 10.6.2021
看行:fluid_model_g________1st_attempt.py#L47
#super().__init__(dx,dt,concentration_G.shape) # BJD original 13.6.2021
super().__init__(dx,concentration_G.shape,concentration_X.shape,concentration_Y.shape) # BJD change 13.6.2021
我开始在文件 pde_solver.py
@ pde_solver________1st_attempt.py#L10 和 pde_solver________1st_attempt.py#L16 和 pde_solver________1st_attempt.py#L55 中进行更改; pde_solver________1st_attempt.py#L81 和 pde_solver________1st_attempt.py#L99
def __init__(self,dx,shape_G,shape_X,shape_Y): # shape_G,shape_Y ::: put in by David J. 13.6.2021
self.dx = dx
self.dt = dt
self.t = 0
omega = []
for s in shape_G: # shape_G,shape_Y,i.e. 3 for loops made; original 1 for loop ::: put in by David J. 13.6.2021
wave_numbers = np.arange(s)
wave_numbers -= s * (2*wave_numbers > s) # Deal with TensorFlow's uncentered FFT
expected_span = 2*np.pi
actual_span = s*dx
omega.append(wave_numbers * expected_span / actual_span)
for s in shape_X:
wave_numbers = np.arange(s)
wave_numbers -= s * (2*wave_numbers > s) # Deal with TensorFlow's uncentered FFT
expected_span = 2*np.pi
actual_span = s*dx
omega.append(wave_numbers * expected_span / actual_span)
for s in shape_Y:
wave_numbers = np.arange(s)
wave_numbers -= s * (2*wave_numbers > s) # Deal with TensorFlow's uncentered FFT
expected_span = 2*np.pi
actual_span = s*dx
omega.append(wave_numbers * expected_span / actual_span)
self.omega = np.meshgrid(*omega,indexing='ij')
self.dims = len(shape_G) + len(shape_X) + len(shape_Y)
# The naming is a bit off. These are not actual 'kernels'.
# They are discrete fourier transforms of the periodic versions of the kernels
if self.dims == 1:
self.fft = tf.signal.fft
self.ifft = tf.signal.ifft
self.omega_x = self.omega[0]
elif self.dims == 2:
self.fft = tf.signal.fft2d
self.ifft = tf.signal.ifft2d
self.omega_x = self.omega[0]
self.omega_y = self.omega[1]
elif self.dims == 3:
self.fft = tf.signal.fft3d
self.ifft = tf.signal.ifft3d
self.omega_x = self.omega[0]
self.omega_y = self.omega[1]
self.omega_z = self.omega[2]
elif self.dims == 6: # With 3 fluids 2 dimensions # :::: put in by David J. 13.6.2021
self.fft = tf.signal.fft2d
self.ifft = tf.signal.ifft2d
self.omega_x = self.omega[0]
self.omega_y = self.omega[1]
self.omega_X_x = self.omega[2]
self.omega_X_y = self.omega[3]
self.omega_Y_x = self.omega[4]
self.omega_Y_y = self.omega[5]
else:
raise ValueError('{} dimensions not supported'.format(self.dims))
class PDESolverDx(PDESolver):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
if self.dims == 1:
self.kernel_dx = tf.constant(1j * self.omega_x,'complex128')
elif self.dims == 2:
self.kernel_dx = tf.constant(1j * self.omega_x,'complex128')
self.kernel_dy = tf.constant(1j * self.omega_y,'complex128')
elif self.dims == 3:
self.kernel_dx = tf.constant(1j * self.omega_x,'complex128')
self.kernel_dz = tf.constant(1j * self.omega_z,'complex128')
elif self.dims == 6: # :::: put in by David J. 13.6.2021
self.kernel_dx = tf.constant(1j * self.omega_x,'complex128')
self.kernel_X_dx = tf.constant(1j * self.omega_X_x,'complex128')
self.kernel_X_dy = tf.constant(1j * self.omega_X_y,'complex128')
self.kernel_Y_dx = tf.constant(1j * self.omega_Y_x,'complex128')
self.kernel_Y_dy = tf.constant(1j * self.omega_Y_y,'complex128')
class PDESolverDx2(PDESolverDx):
def __init__(self,**kwargs)
if self.dims == 1:
self.kernel_laplacian = tf.constant(-self.omega_x**2,'complex128')
elif self.dims == 2:
self.kernel_laplacian = tf.constant(-(self.omega_x**2 + self.omega_y**2),'complex128')
elif self.dims == 3:
self.kernel_laplacian = tf.constant(-(self.omega_x**2 + self.omega_y**2 + self.omega_z**2),'complex128')
elif self.dims == 6: # :::: put in by David J. 13.6.2021
self.kernel_laplacian = tf.constant(-(self.omega_x**2 + self.omega_y**2),'complex128')
self.kernel_laplacian_X = tf.constant(-(self.omega_X_x**2 + self.omega_X_y**2),'complex128')
self.kernel_laplacian_Y = tf.constant(-(self.omega_Y_x**2 + self.omega_Y_y**2),'complex128')
原文如下:pde_solver.py#L10
这是我得到的!谁能帮我解决这个程序更改,以便为 X、Y 和 G 基板包括单独的速度场?
解决方法
直观地,答案似乎如下所示,只需简单地为每个 rho
、G
和 X
重新定义不同的 Y
(压力项) .其中,速度场 u
和 v
每次都重新定义:
def step(self):
self.G,self.X,self.Y = self.reaction_integrator(self.G,self.Y)
density_of_reactants = (
self.params['density_G'] * self.G +
self.params['density_X'] * self.X +
self.params['density_Y'] * self.Y
)
if self.dims == 2:
u,v = self.u,self.v # Store unintegrated flow so that we're on the same timestep
rho = tf.math.log(35.0 + density_of_reactants) # rho defined for self.G
self.u,self.v,divergence = self.flow_integrator(rho,self.u,self.v)
self.G = self.diffusion_advection_integrator(self.G,self.Y,u,v,divergence) # G calculated
rho = tf.math.log(36.0 + density_of_reactants) # rho defined for self.X
self.u,self.v)
self.X = self.diffusion_advection_integrator(self.G,divergence) # X calculated
rho = tf.math.log(37.0 + density_of_reactants) # rho defined for self.Y
self.u,self.v)
self.Y = self.diffusion_advection_integrator(self.G,divergence) # Y calculated
原始代码是 here。
然而,这给出了错误信息:
Exception has occurred: ValueError
in user code:
/home/brendan/software/tf2-model-g-velocity/fluid_model_g.py:122 diffusion_advection_integrator *
f_X = self.fft(tf.cast(X,'complex128'))
/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/util/dispatch.py:201 wrapper **
return target(*args,**kwargs)
/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/ops/math_ops.py:920 cast
x = ops.convert_to_tensor(x,name="x")
/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/framework/ops.py:1499 convert_to_tensor
ret = conversion_func(value,dtype=dtype,name=name,as_ref=as_ref)
/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/ops/array_ops.py:1502 _autopacking_conversion_function
return _autopacking_helper(v,dtype,name or "packed")
/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/ops/array_ops.py:1438 _autopacking_helper
return gen_array_ops.pack(elems_as_tensors,name=scope)
/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/ops/gen_array_ops.py:6476 pack
_,_,_op,_outputs = _op_def_library._apply_op_helper(
/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/framework/op_def_library.py:742 _apply_op_helper
op = g._create_op_internal(op_type_name,inputs,dtypes=None,/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/framework/func_graph.py:591 _create_op_internal
return super(FuncGraph,self)._create_op_internal( # pylint: disable=protected-access
/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/framework/ops.py:3477 _create_op_internal
ret = Operation(
/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/framework/ops.py:1974 __init__
self._c_op = _create_c_op(self._graph,node_def,/home/brendan/.local/lib/python3.8/site-packages/tensorflow/python/framework/ops.py:1815 _create_c_op
raise ValueError(str(e))
ValueError: Shapes must be equal rank,but are 3 and 2
From merging shape 0 with other shapes. for '{{node Cast_1/x}} = Pack[N=3,T=DT_DOUBLE,axis=0](X,X_1,X_2)' with input shapes: [3,426,240],[426,240].
During handling of the above exception,another exception occurred:
File "/tmp/tmp10_g9n1p.py",line 15,in tf__diffusion_advection_integrator
f_X = ag__.converted_call(ag__.ld(self).fft,(ag__.converted_call(ag__.ld(tf).cast,(ag__.ld(X),'complex128'),None,fscope),),fscope)
During handling of the above exception,another exception occurred:
File "/home/brendan/software/tf2-model-g-velocity/fluid_model_g.py",line 282,in step
self.Y = self.diffusion_advection_integrator(self.G,divergence) # Y calculated
File "/home/brendan/software/tf2-model-g-velocity/render_video.py",line 78,in nucleation_and_motion_in_G_gradient_fluid_2D
fluid_model_g.step()
File "/home/brendan/software/tf2-model-g-velocity/render_video.py",line 292,in <module>
episodes[args.episode](writer,args)
它出现了 Shapes must be equal rank
,所以:
self.Y = self.diffusion_advection_integrator(self.G,divergence) # Y calculated
必须是:
self.G,self.Y = self.diffusion_advection_integrator(self.G,divergence)
,
问题是通过以下过程解决的。 diffusion_advection_integrator()
的 3 个独立函数在哪里制作:
def diffusion_advection_integrator1(G,divergence):
def diffusion_advection_integrator2(X,divergence):
def diffusion_advection_integrator3(Y,divergence):
每个只包含 G
、X
或 Y
组件。原始代码 here。
然后剩下的代码更新如下:
self.reaction_integrator = tf.function(reaction_integrator_curried)
self.flow_integrator = tf.function(flow_integrator)
#self.diffusion_advection_integrator = tf.function(diffusion_advection_integrator) # original
self.diffusion_advection_integrator1 = tf.function(diffusion_advection_integrator1) # BJD added 25.6.2021
self.diffusion_advection_integrator2 = tf.function(diffusion_advection_integrator2) # BJD added 25.6.2021
self.diffusion_advection_integrator3 = tf.function(diffusion_advection_integrator3) # BJD added 25.6.2021
def step(self):
self.G,self.v)
self.G = self.diffusion_advection_integrator1(self.G,self.v)
self.X = self.diffusion_advection_integrator2(self.X,self.v)
self.Y = self.diffusion_advection_integrator3(self.Y,divergence) # Y calculated
上述部分的原始代码显示为 here。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。