34 box = np.asarray(pk[
"box"], float)
36 c = np.asarray(pk[
"centers"]) * Rc
37 r = np.asarray(pk[
"scales"]) * Rc
38 ax = np.arange(N) + 0.5
39 S = np.full((N, N, N), 1e30)
40 for sh
in np.stack(np.meshgrid(*[[-1., 0., 1.]] * 3, indexing=
"ij"), -1).reshape(-1, 3):
42 keep = np.all((cs + (r + 3)[:,
None] > 0) & (cs - (r + 3)[:,
None] < N), axis=1)
43 for (cx, cy, cz), rr
in zip(cs[keep], r[keep]):
44 i0, i1 = np.searchsorted(ax, [cx - rr - 3, cx + rr + 3])
45 j0, j1 = np.searchsorted(ax, [cy - rr - 3, cy + rr + 3])
46 k0, k1 = np.searchsorted(ax, [cz - rr - 3, cz + rr + 3])
47 if i0 >= i1
or j0 >= j1
or k0 >= k1:
49 d = np.sqrt((ax[i0:i1,
None,
None] - cx) ** 2 + (ax[
None, j0:j1,
None] - cy) ** 2
50 + (ax[
None,
None, k0:k1] - cz) ** 2) - rr
51 np.minimum(S[i0:i1, j0:j1, k0:k1], d, out=S[i0:i1, j0:j1, k0:k1])
52 return np.asfortranarray(np.clip(S, -1e3, 1e3)), Rc
60 s = (flow.Solver
if KIND ==
"stag" else flow.SolverColocated)(N, N, N)
61 s.set_rho(1.0); s.set_mu(MU); s.set_dt(DT)
62 s.set_body_force(F0, 0, 0); s.set_advection(
False)
63 s.set_velocity_solver_params(150)
64 s.set_pressure_multigrid(
True, max(2, int(np.log2(N)) - 2))
65 s.set_pressure_pcg(
True, 300, 1e-8)
67 if hasattr(s,
"set_collocated_scheme"):
68 s.set_collocated_scheme(KIND)
70 s.set_face_interp({
"gauge-exact": 9,
"plain": 0}[KIND])
71 s.set_solid(sdf, cutcell_pressure=
True, pressure_coarse=
"rediscretized")
88 U = [np.asarray(s.get_u()), np.asarray(s.get_v()), np.asarray(s.get_w())]
89 us = float(np.abs(U[0][fluid]).mean()) + 1e-300
90 kc = float(U[0].mean()) * MU / F0 / R ** 2
93 UF = [np.asarray(s.get_uf()), np.asarray(s.get_vf()), np.asarray(s.get_wf())]
94 OX = [np.asarray(s.get_ox()), np.asarray(s.get_oy()), np.asarray(s.get_oz())]
97 half = 0.5 * (U[a] + np.roll(U[a], 1, axis=a))
99 m1sq += float(((UF[a] - half)[op] ** 2).sum()); cnt += int(op.sum())
100 m1 = np.sqrt(m1sq / cnt) / us
101 print(f
"[{tag}] steps={steps} k_cell/R2={kc:.7e} m1={m1:.3e}", flush=
True)