1"""Layer 3 rung 1 gate (flow side): every CUT cell's owner is the brute-force nearest sphere.
3A cut cell is a fluid cell (sdf>0) with at least one solid face-neighbour -- the cells whose
4stencils the IBM overlay modifies, and therefore the only cells whose ownership a moving wall
5velocity (R2) or a CFD-DEM force integration (L4-R2) ever reads.
7Coordinates: the solver samples the scene at INTEGER cell coordinates (cell (i,j,k) at (i,j,k)),
8so the reference lattice here is arange(N) -- not the i+0.5 convention scene_check.py uses for
9its own sampled-array reference.
12from peclet
import flow
as sdflow
16CEN = [(0.25*N, 0.25*N, 0.25*N), (0.75*N, 0.75*N, 0.25*N),
17 (0.75*N, 0.25*N, 0.75*N), (0.25*N, 0.75*N, 0.75*N)]
19KN_R, KI_I, KI_R = 16, 2, 17
20node_ints = np.array([1, -1, -1], dtype=np.int32)
21node_reals = np.zeros(KN_R); node_reals[0] = R
22node_reals[14] = 1.0; node_reals[15] = 1.0
23inst_ints = np.zeros((len(CEN), KI_I), dtype=np.int32)
24inst_reals = np.zeros((len(CEN), KI_R))
25for m, c
in enumerate(CEN):
26 inst_ints[m] = (0, -1)
27 inst_reals[m, 0:3] = c
28 inst_reals[m, 6] = 1.0
29 inst_reals[m, 7] = 1.0
31s = sdflow.Solver(N, N, N)
32s.set_rho(1.0); s.set_mu(1.0); s.set_dt(50.0)
33s.set_scene(node_ints, node_reals, inst_ints.ravel(), inst_reals.ravel(), periodic=
True)
34s.set_solid_from_scene(
True)
35owner = np.asarray(s.get_cut_owner())
37g = np.arange(N).astype(float)
38X, Y, Z = np.meshgrid(g, g, g, indexing=
"ij")
39d = np.empty((len(CEN), N, N, N))
40for k, (cx, cy, cz)
in enumerate(CEN):
41 dx = np.abs(X-cx); dx = np.minimum(dx, N-dx)
42 dy = np.abs(Y-cy); dy = np.minimum(dy, N-dy)
43 dz = np.abs(Z-cz); dz = np.minimum(dz, N-dz)
44 d[k] = np.sqrt(dx*dx+dy*dy+dz*dz) - R
45ref_owner = np.argmin(d, axis=0)
46ref_sdf = d.min(axis=0)
50nbr_solid = np.zeros_like(solid)
53 nbr_solid |= np.roll(solid, sh, axis=ax)
54cut = fluid & nbr_solid
56srt = np.sort(d, axis=0)
57tied = int(((srt[1] - srt[0]) == 0.0).sum())
58bad_cut = int((owner[cut] != ref_owner[cut]).sum())
59bad_all = int((owner != ref_owner).sum())
60print(
"cut cells %d of %d" % (int(cut.sum()), owner.size))
61print(
"exact ties on lattice %d" % tied)
62print(
"owner mismatches cut=%d all-cells=%d" % (bad_cut, bad_all))
63print(
"GATE %s" % (
"PASS" if bad_cut == 0
and bad_all == 0
else "FAIL"))