def center_G2P(self, grid_v: ti.template(), dx: ti.f32, dt: ti.f32): inv_dx = 1 / dx for p in self.px: xp = self.px[p] base = (xp * inv_dx - 0.5).cast(ti.i32) fx = xp * inv_dx - base.cast(ti.f32) w = [0.5 * (1.5 - fx)**2, 0.75 - (fx - 1)**2, 0.5 * (fx - 0.5)**2] # Bspline new_v = ti.Vector.zero(ti.f32, 3) new_C = ti.Matrix.zero(ti.f32, 3, 3) for i in ti.static(range(3)): for j in ti.static(range(3)): for k in ti.static(range(3)): dpos = vec3(i, j, k) - fx g_v = grid_v[base + vec3(i, j, k)] weight = w[i][0] * w[j][1] * w[k][2] new_v += weight * g_v new_C += 4 * weight * g_v.outer_product(dpos) * inv_dx self.pv[p] = new_v self.px[p] += dt * self.pv[p] self.J[p] *= 1 + dt * new_C.trace() self.C[p] = new_C
def init_properties(self): # init particles for p in self.px: self.pv[p] = vec3(0.0, 0.0, 0.0) if ti.static(self.sim_algo == 'MPM'): self.C[p] = ti.Matrix.zero(ti.f32, 3, 3) self.J[p] = 1.0 elif ti.static(self.sim_algo == 'APIC'): self.c_x[p] = vec3(0.0, 0.0, 0.0) self.c_y[p] = vec3(0.0, 0.0, 0.0) self.c_z[p] = vec3(0.0, 0.0, 0.0) # init field if ti.static(self.sim_algo != 'MPM'): for i, j, k in self.u: self.u[i, j, k] = 0.0 self.u_weight[i, j, k] = 0.0 for i, j, k in self.v: self.v[i, j, k] = 0.0 self.v_weight[i, j, k] = 0.0 for i, j, k in self.w: self.w[i, j, k] = 0.0 self.w_weight[i, j, k] = 0.0 for i, j, k in self.p: self.p[i, j, k] = 0.0
def voxelize(self, px: ti.template(), world: ti.f32, n_grid: ti.i32, bound_grid: ti.i32, npar: ti.i32): dx = world / n_grid bound = bound_grid * dx space_x = dx / npar for i, j, k in ti.ndrange(n_grid, n_grid, n_grid): x = (i + 0.5) * dx y = (j + 0.5) * dx z = (k + 0.5) * dx if (x - self.c_x)**2 + (y - self.c_y)**2 + ( z - self.c_z)**2 - self.r**2 < 0: for ix in range(npar): for jx in range(npar): for kx in range(npar): xp = clamp( i * dx + (ix + random.random()) * space_x, bound + 1e-4, world - bound - 1e-4) yp = clamp( j * dx + (jx + random.random()) * space_x, bound + 1e-4, world - bound - 1e-4) zp = clamp( k * dx + (kx + random.random()) * space_x, bound + 1e-4, world - bound - 1e-4) px[particle_idx(i, j, k, ix, jx, kx, n_grid, npar)] = vec3(xp, yp, zp)
def voxelize(self, px: ti.template(), world: ti.f32, n_grid: ti.i32, bound_grid: ti.i32, npar: ti.i32): dx = world / n_grid bound = bound_grid * dx space_x = dx / npar for i, j, k in ti.ndrange(n_grid, n_grid, n_grid): x = (i + 0.5) * dx y = (j + 0.5) * dx z = (k + 0.5) * dx if self.x_start < x < self.x_end and self.y_start < y < self.y_end and self.z_start < z < self.z_end: for ix in range(npar): for jx in range(npar): for kx in range(npar): xp = clamp( i * dx + (ix + random.random()) * space_x, bound + 1e-4, world - bound - 1e-4) yp = clamp( j * dx + (jx + random.random()) * space_x, bound + 1e-4, world - bound - 1e-4) zp = clamp( k * dx + (kx + random.random()) * space_x, bound + 1e-4, world - bound - 1e-4) px[particle_idx(i, j, k, ix, jx, kx, n_grid, npar)] = vec3(xp, yp, zp)
def map_color(c): return vec3(bwrR.map(c), bwrG.map(c), bwrB.map(c))