1"""Layer 2: the in-solver analytic scene must reproduce the geometry flow has always been handed
2as a sampled array -- on a CONVERGED periodic sphere packing, not a diverged one."""
4from peclet
import flow
as sdflow
8CEN = [(0.25*N, 0.25*N, 0.25*N), (0.75*N, 0.75*N, 0.25*N),
9 (0.75*N, 0.25*N, 0.75*N), (0.25*N, 0.75*N, 0.75*N)]
13X, Y, Z = np.meshgrid(g, g, g, indexing=
"ij")
14ref = np.full((N, N, N), 1e30)
15for (cx, cy, cz)
in CEN:
16 dx = np.abs(X-cx); dx = np.minimum(dx, N-dx)
17 dy = np.abs(Y-cy); dy = np.minimum(dy, N-dy)
18 dz = np.abs(Z-cz); dz = np.minimum(dz, N-dz)
19 ref = np.minimum(ref, np.sqrt(dx*dx+dy*dy+dz*dz) - R)
24KN_R, KI_I, KI_R = 16, 2, 17
25node_ints = np.array([1, -1, -1], dtype=np.int32)
26node_reals = np.zeros(KN_R); node_reals[0] = R
30for (cx, cy, cz)
in CEN:
34 inst.append((cx - 0.5 + ix*N, cy - 0.5 + iy*N, cz - 0.5 + iz*N))
35inst_ints = np.zeros((len(inst), KI_I), dtype=np.int32)
36inst_reals = np.zeros((len(inst), KI_R))
37for m, (cx, cy, cz)
in enumerate(inst):
38 inst_ints[m] = (0, -1)
39 inst_reals[m, 0:3] = (cx, cy, cz)
40 inst_reals[m, 6] = 1.0
41 inst_reals[m, 7] = 1.0
42print(
" scene: 1 node, %d instances (4 spheres x 27 images)" % len(inst))
45 s = sdflow.Solver(N, N, N)
48 s.set_rho(1.0); s.set_mu(1.0); s.set_dt(50.0)
50 s.set_body_force(1.0, 0.0, 0.0)
51 for _
in range(40): s.step()
52 return s, np.asarray(s.get_u())
54s1, u1 =
run(
lambda s: (s.set_scene(node_ints, node_reals, inst_ints.ravel(), inst_reals.ravel()),
55 s.set_solid_from_scene(
True)))
56s2, u2 =
run(
lambda s: s.set_solid(np.asfortranarray(ref), cutcell_pressure=
True))
59base_ints = np.zeros((len(CEN), KI_I), dtype=np.int32)
60base_reals = np.zeros((len(CEN), KI_R))
61for m, (cx, cy, cz)
in enumerate(CEN):
62 base_ints[m] = (0, -1)
63 base_reals[m, 0:3] = (cx - 0.5, cy - 0.5, cz - 0.5)
64 base_reals[m, 6] = 1.0
65 base_reals[m, 7] = 1.0
66s4, u4 =
run(
lambda s: (s.set_scene(node_ints, node_reals, base_ints.ravel(), base_reals.ravel(),
68 s.set_solid_from_scene(
True)))
70den = max(np.abs(u2).max(), 1e-300)
71rel = np.abs(u1-u2).max()/den
72print(
" CONVERGED? u_absmax array = %.6e (a diverged run is ~1e35)" % np.abs(u2).max())
73print(
" 108-image scene vs sampled array: max rel diff = %.3e" % rel)
74rel4 = np.abs(u4-u2).max()/den
75print(
" NATIVE periodic (4 inst) vs array: max rel diff = %.3e" % rel4)
76ok = rel < 1e-12
and rel4 < 1e-12
and np.abs(u2).max() < 1e3
78s3, u3 =
run(
lambda s: (s.set_scene(node_ints, node_reals, base_ints.ravel(), base_reals.ravel(),
80 s.set_exact_crossings_from_scene(),
81 s.set_solid_from_scene(
True)))
82print(
" with EXACT scene crossings: u_absmax %.6e (vs %.6e)" % (np.abs(u3).max(), np.abs(u1).max()))
83print(
" changed the solution: %s finite: %s" %
84 (
not np.array_equal(u3, u1), bool(np.isfinite(u3).all())))
85print(
"SCENE OK" if ok
and np.isfinite(u3).all()
and np.abs(u3).max() < 1e3
else "SCENE FAIL")