调整 Tensorflow2 代码 - 模拟反应扩散孤子以包含 3 个速度场
Adapting Tensorflow2 code - simulating a reaction-diffusion soliton to include 3 velocity fields
我正在尝试修改一个程序来模拟由 X、Y 和 G 基板组成的反应扩散孤子。该程序包括 Navier-Stokes 方程,以便为基板提供涡旋运动。
目前,代码根据速度场 u 和 v 为 X、Y 和 G 提供 rotational/vortical 运动,表示此 2D 模拟中 x 和 y 方向上的速度矢量。 z 轴为 X、Y 和 G 浓度势。
在 1D 中它看起来像这样:
我想更改代码,使基板 X、Y 和 G 各自具有不同的速度(不仅仅是相同的速度)。 IE。 X velocity field --> u_X 和 v_X 等。有人可以帮我修改代码吗?
这是我到目前为止所做的:
显示了为单独的速度场更改的代码 here。
代码是 运行 例如: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, X, Y
原始代码显示在这里:fluid_model_g.py#L57 and here: 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.X, self.Y, u, v, divergence) # BJD original line 10.6.2021
self.G, self.X, self.Y = self.diffusion_advection_integrator(self.G, self.X, self.Y, u_X, v_X, u_Y, v_Y, u_G, v_G, divergence1, divergence2, 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, dt, concentration_G.shape, concentration_X.shape, concentration_Y.shape) # BJD change 13.6.2021
我开始更改文件 pde_solver.py
@ pde_solver________1st_attempt.py#L10 and pde_solver________1st_attempt.py#L16 and pde_solver________1st_attempt.py#L55; pde_solver________1st_attempt.py#L81 and pde_solver________1st_attempt.py#L99
def __init__(self, dx, dt, shape_G, shape_X, shape_Y): # shape_G, shape_X, 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_X, 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_dy = tf.constant(1j * self.omega_y, '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_dy = tf.constant(1j * self.omega_y, '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, *args, **kwargs):
super().__init__(*args, **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 基板的单独速度场?
直觉上,答案似乎如下所示,只需为每个 G
、X
和 [=17 重新定义不同的 rho
(压力项) =].其中,速度场u
和v
,每次都重新定义:
def step(self):
self.G, self.X, self.Y = self.reaction_integrator(self.G, self.X, 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.X, 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, divergence = self.flow_integrator(rho, self.u, self.v)
self.X = self.diffusion_advection_integrator(self.G, self.X, self.Y, u, v, divergence) # X calculated
rho = tf.math.log(37.0 + density_of_reactants) # rho defined for self.Y
self.u, self.v, divergence = self.flow_integrator(rho, self.u, self.v)
self.Y = self.diffusion_advection_integrator(self.G, self.X, self.Y, u, v, 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, inputs,
/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], [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),), None, 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, self.X, self.Y, u, v, 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, self.X, self.Y, u, v, divergence) # Y calculated
必须是:
self.G, self.X, self.Y = self.diffusion_advection_integrator(self.G, self.X, self.Y, u, v, divergence)
问题已通过以下过程解决。 diffusion_advection_integrator()
的 3 个独立函数制作位置:
def diffusion_advection_integrator1(G, u, v, divergence):
def diffusion_advection_integrator2(X, u, v, divergence):
def diffusion_advection_integrator3(Y, u, v, 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.X, self.Y = self.reaction_integrator(self.G, self.X, 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_integrator1(self.G, u, v, divergence) # G calculated
rho = tf.math.log(36.0 + density_of_reactants) # rho defined for self.X
self.u, self.v, divergence = self.flow_integrator(rho, self.u, self.v)
self.X = self.diffusion_advection_integrator2(self.X, u, v, divergence) # X calculated
rho = tf.math.log(37.0 + density_of_reactants) # rho defined for self.Y
self.u, self.v, divergence = self.flow_integrator(rho, self.u, self.v)
self.Y = self.diffusion_advection_integrator3(self.Y, u, v, divergence) # Y calculated
上面部分的原始代码显示在here.
我正在尝试修改一个程序来模拟由 X、Y 和 G 基板组成的反应扩散孤子。该程序包括 Navier-Stokes 方程,以便为基板提供涡旋运动。
目前,代码根据速度场 u 和 v 为 X、Y 和 G 提供 rotational/vortical 运动,表示此 2D 模拟中 x 和 y 方向上的速度矢量。 z 轴为 X、Y 和 G 浓度势。
在 1D 中它看起来像这样:
我想更改代码,使基板 X、Y 和 G 各自具有不同的速度(不仅仅是相同的速度)。 IE。 X velocity field --> u_X 和 v_X 等。有人可以帮我修改代码吗?
这是我到目前为止所做的:
显示了为单独的速度场更改的代码 here。
代码是 运行 例如: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, X, Y
原始代码显示在这里:fluid_model_g.py#L57 and here: 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.X, self.Y, u, v, divergence) # BJD original line 10.6.2021
self.G, self.X, self.Y = self.diffusion_advection_integrator(self.G, self.X, self.Y, u_X, v_X, u_Y, v_Y, u_G, v_G, divergence1, divergence2, 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, dt, concentration_G.shape, concentration_X.shape, concentration_Y.shape) # BJD change 13.6.2021
我开始更改文件 pde_solver.py
@ pde_solver________1st_attempt.py#L10 and pde_solver________1st_attempt.py#L16 and pde_solver________1st_attempt.py#L55; pde_solver________1st_attempt.py#L81 and pde_solver________1st_attempt.py#L99
def __init__(self, dx, dt, shape_G, shape_X, shape_Y): # shape_G, shape_X, 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_X, 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_dy = tf.constant(1j * self.omega_y, '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_dy = tf.constant(1j * self.omega_y, '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, *args, **kwargs):
super().__init__(*args, **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 基板的单独速度场?
直觉上,答案似乎如下所示,只需为每个 G
、X
和 [=17 重新定义不同的 rho
(压力项) =].其中,速度场u
和v
,每次都重新定义:
def step(self):
self.G, self.X, self.Y = self.reaction_integrator(self.G, self.X, 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.X, 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, divergence = self.flow_integrator(rho, self.u, self.v)
self.X = self.diffusion_advection_integrator(self.G, self.X, self.Y, u, v, divergence) # X calculated
rho = tf.math.log(37.0 + density_of_reactants) # rho defined for self.Y
self.u, self.v, divergence = self.flow_integrator(rho, self.u, self.v)
self.Y = self.diffusion_advection_integrator(self.G, self.X, self.Y, u, v, 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, inputs,
/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], [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),), None, 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, self.X, self.Y, u, v, 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, self.X, self.Y, u, v, divergence) # Y calculated
必须是:
self.G, self.X, self.Y = self.diffusion_advection_integrator(self.G, self.X, self.Y, u, v, divergence)
问题已通过以下过程解决。 diffusion_advection_integrator()
的 3 个独立函数制作位置:
def diffusion_advection_integrator1(G, u, v, divergence):
def diffusion_advection_integrator2(X, u, v, divergence):
def diffusion_advection_integrator3(Y, u, v, 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.X, self.Y = self.reaction_integrator(self.G, self.X, 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_integrator1(self.G, u, v, divergence) # G calculated
rho = tf.math.log(36.0 + density_of_reactants) # rho defined for self.X
self.u, self.v, divergence = self.flow_integrator(rho, self.u, self.v)
self.X = self.diffusion_advection_integrator2(self.X, u, v, divergence) # X calculated
rho = tf.math.log(37.0 + density_of_reactants) # rho defined for self.Y
self.u, self.v, divergence = self.flow_integrator(rho, self.u, self.v)
self.Y = self.diffusion_advection_integrator3(self.Y, u, v, divergence) # Y calculated
上面部分的原始代码显示在here.