关于autodiff 在LBM中的应用

菜鸟求助autodiff在LBM的应用, 问题是这样的:
求解水流过一个隧道, 即Poiseuille’s flow. 左右边界各自施加一个固定pressure, 左边界pressure已知, 右边界未知, 设右边pressure为需要求导的变量p. 左右两边的pressure是固定的, 不会随着step变化.
目标是在3000个step后使得流体速度场的大小达到目标值, 故

@ti.kernel
def compute_loss(): 
      for i,j in ti.ndrange(lx,ly):
            loss += (v[i,j].norm()-target_v[i,j].norm())**2

到这里都能converge, 能返回正确的求导结果.

但是我发现,当求解速度场并不包括右边界时, 得到的p.grad[None]恒为0,

@ti.kernel
def compute_loss(): 
      for i,j in ti.ndrange(lx-1,ly):
            loss += (v[i,j].norm()-target_v[i,j].norm())**2

这是为什么呢?

相关代码如下:

learning_rate =  0.1
for iteration in range(100):
    initialization()
    for step in range(3000):
        with ti.ad.Tape(loss):
            collision()
            streaming()
            boundary_condition()
            compute_loss()
    p[None] -= p.grad[None] * learning_rate

这里是不是有边界的pressure只有在求解右边界的速度时才会用到呢?

1 Like

感谢!是的,右边界的pressure先是求解右边界的密度分布,进而直接求解右边界的速度;但是右边界的密度也会传递给左边区域,从而影响左边的速度。这种情况下,我无法以左边速度场为目标场求导右边界的pressure吗?

导数为0的话我怀疑是求导的链没有连起来,根据你的描述,我的理解除去右边速度后,计算的过程大概是:右边pressure → 右边密度 → 左边密度 → 左边速度 → loss,如果是这样的话 感觉是不应该为0的,可以麻烦分享一个最小可复现代码吗?

1 Like

太感谢您了! 我尽量把多余的方程都删掉了,耽误您的时间了!
example.ipynb (11.2 KB)