各位专家好,我是一名LBM(格子玻尔兹曼方法)和taichi语言的初学者,最近的业余时间在试着做一个算例。
算例中需要在多次迭代中更新边界条件,在第一次(初始化)循环中该步骤很慢,大概需要2~3min,初始化后后续的循环该步骤的耗时基本为0,我怀疑可能是循环嵌套有点多(最多4层)。
下面附上代码,请各位专家帮我看看,为什么第一个迭代步会运行得很慢。
@ti.kernel
def apply_bc2(self):
for jbc in ti.ndrange((self.ini_lv, self.ny)):
self.apply_bc_bound(0, jbc, 1, jbc, self.bc_type[0], 0) # inlet
self.apply_bc_bound(self.nx-1, jbc, self.nx-2, jbc, self.bc_type[2], 2) # outflow
for ibc in ti.ndrange(self.nx):
self.apply_bc_bound(ibc, 0, ibc, 1, self.bc_type[1], 1) # bottom
self.apply_bc_bound(ibc, self.ny-1, ibc, self.ny-2, self.bc_type[3], 3) # top
for inb, jnb in ti.ndrange(self.nx, self.ny):
if (self.mask[inb,jnb] == 0):
for k in ti.ndrange(9):
ibc = self.e[k, 0]+inb
jbc = self.e[k, 1]+jnb
if (self.mask[ibc,jbc] == 1):
self.rho[ibc, jbc] = self.rho[inb, jnb]
self.u[ibc,jbc][0] = self.u[ibc,jbc][1] = 0
self.bound(ibc, jbc, inb, jnb, 0)
if (self.mask[ibc,jbc] == 2):
self.rho[ibc, jbc] = self.rho[inb, jnb]
self.u[ibc,jbc][0] = self.u[ibc,jbc][1] = 0
self.bound(ibc, jbc, inb, jnb, 2) # 动网格表面
else: self.u[inb,jnb][0] = self.u[inb,jnb][1] = 0
@ti.func
def bound(self, ibc, jbc, inb, jnb, type):
if type == 0:
for k in ti.static(range(9)):
self.f_old[ibc, jbc][k] = self.f_eq(ibc, jbc, k) + \
self.f_old[inb, jnb][k] - self.f_eq(inb, jnb, k)
elif type == 1: # 镜面反射
for k in ti.static(range(9)):
a = [0, 3, 2, 1, 4, 7, 8, 5, 6]
self.f_old[ibc, jbc][k] = self.f_eq(ibc, jbc, k) + \
self.f_old[inb, jnb][a[k]] - self.f_eq(inb, jnb, a[k])
elif type == 2: # 动网格表面
self.u[ibc, jbc][0] = self.u[ibc, jbc][1] = 0
for k in ti.static(range(9)):
self.f_old[ibc, jbc][k] = self.f_eq(ibc, jbc, k) + \
self.f_old[inb, jnb][k] - self.f_eq(inb, jnb, k) + 2*self.w[k]*self.rho[inb, jnb]*3*self.dz[inb]
@ti.func
def apply_bc_bound(self, ibc, jbc, inb, jnb, type, dr):
self.rho[ibc, jbc] = self.rho[inb, jnb]
if type == 0: # 狄利克雷边界
self.u[ibc, jbc][0] = self.bc_value[dr, 0]
self.u[ibc, jbc][1] = self.bc_value[dr, 1]
self.bound(ibc, jbc, inb, jnb, 0)
elif type == 1: # 黎曼边界
self.u[ibc, jbc][0] = self.u[inb, jnb][0]
self.u[ibc, jbc][1] = self.u[inb, jnb][1]
self.bound(ibc, jbc, inb, jnb, 0)
elif type == 2: # 对数流入口
self.u[ibc, jbc][0] = self.cal_in_u()[jbc]
self.u[ibc, jbc][1] = self.u[inb, jnb][1]
self.bound(ibc, jbc, inb, jnb, 0)
elif type == 3: # 镜面边界
self.u[ibc, jbc][0] = self.u[inb, jnb][0]
self.u[ibc, jbc][1] = self.bc_value[dr, 1]
self.bound(ibc, jbc, inb, jnb, 1)
部分代码参考:
Homework0 计算流体力学视角的流体求解器 - GAMES201 高级物理引擎课程专区 - Taichi 中文论坛 (taichi-lang.cn)
此外,由于我是从实践案例入手学的,LBM的壁面设置可能也存在问题,如果有专家发现并愿意帮我纠正错误,也是不胜感激!