微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

调整 Tensorflow2 代码 - 模拟反应扩散孤子以包括 3 个速度场

如何解决调整 Tensorflow2 代码 - 模拟反应扩散孤子以包括 3 个速度场

我正在尝试调整一个程序,该程序模拟由衬底 X、Y 和 G 组成的反应扩散孤子。该程序包括 Navier-Stokes 方程,以对衬底进行涡旋运动。

目前,代码根据速度场 u 和 v 为 X、Y 和 G 提供旋转/涡旋运动,表示此 2D 模拟中 x 和 y 方向的速度矢量。 z 轴为 X、Y 和 G 浓度电位。

在 1D 中它看起来像这样:

enter image description here

我想更改代码,使基板 X、Y 和 G 各自具有不同的速度(不仅仅是相同的速度)。 IE。 X 速度场 --> u_X 和 v_X 等。请有人帮我调整代码吗?

这是我目前所做的:

原始 code:以及代码所基于的 theory

为单独的速度场更改的代码显示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,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-density1base-density2base-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#L10pde_solver________1st_attempt.py#L16pde_solver________1st_attempt.py#L55 中进行更改; pde_solver________1st_attempt.py#L81pde_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 基板包括单独的速度场?

解决方法

直观地,答案似乎如下所示,只需简单地为每个 rhoGX 重新定义不同的 Y(压力项) .其中,速度场 uv 每次都重新定义:

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): 

每个只包含 GXY 组件。原始代码 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 举报,一经查实,本站将立刻删除。