43 cs = np.array([0.25 * N, 0.75 * N])
44 xs = np.arange(N) + 0.5
45 X, Y, Z = np.meshgrid(xs, xs, xs, indexing=
"ij")
46 best = np.full((N, N, N), 1e30)
50 dx = X - sx; dx -= N * np.round(dx / N)
51 dy = Y - sy; dy -= N * np.round(dy / N)
52 dz = Z - sz; dz -= N * np.round(dz / N)
53 best = np.minimum(best, np.sqrt(dx * dx + dy * dy + dz * dz) - R)
54 return np.asfortranarray(best)
57def sphere_fractions(shape, R, c, sub=4):
59 off = (np.arange(sub) + 0.5) / sub
64 X, Y, Z = np.meshgrid(np.arange(n[0]) + ox, np.arange(n[1]) + oy,
65 np.arange(n[2]) + oz, indexing=
"ij")
66 out += ((X - c[0]) ** 2 + (Y - c[1]) ** 2 + (Z - c[2]) ** 2 <= R * R)
67 return np.asfortranarray(out / sub ** 3)
72 s.set_rho(1.0); s.set_mu(0.1); s.set_dt(60.0); s.set_body_force((1e-3, 0.0, 0.0))
73 s.set_advection(
False)
74 s.diagnostics.set_velocity_solver_params(80)
75 s.set_pressure_multigrid(
True, 3)
76 s.set_pressure_pcg(
True, 200, 1e-9)
77 if scheme
is not None:
78 s.set_collocated_scheme(scheme)
80 for _
in range(steps):
106 """A divergence-free (to O(h^2)) cell-centred Taylor-Green pair: a non-trivial advecting
107 field with no body force, so the hash reflects the advection + projection only."""
110 X, Y = np.meshgrid(ix, ix, indexing=
"ij")
111 u = np.repeat((U0 * np.sin(k * X) * np.cos(k * Y))[:, :,
None], nz, axis=2)
112 v = np.repeat((-U0 * np.cos(k * X) * np.sin(k * Y))[:, :,
None], nz, axis=2)
113 return (np.asfortranarray(u), np.asfortranarray(v),
114 np.asfortranarray(np.zeros((N, N, nz))))
118 """Collocated + advection, triply periodic: hasBc_ false, so advection is EXPLICIT (Koren in
119 the RHS) and the advecting velocity is the projected face field of the previous step."""
121 s = pf.SolverColocated(N, N, nz)
122 s.set_rho(1.0); s.set_mu(0.05); s.set_dt(0.5)
123 s.set_advection(
True); s.set_advection_scheme(
"koren")
124 s.diagnostics.set_velocity_solver_params(80)
125 s.set_pressure_pcg(
True, 200, 1e-9)
126 s.set_solid(np.asfortranarray(np.full((N, N, nz), 1e3)), cutcell_pressure=
True)
134 """Collocated + advection + domain BCs: hasBc_ true, so implicitAdv() holds and the IMPLICIT
135 FOU operator (buildAdvStencil) plus the explicit (SOU - FOU) deferred correction both read
136 the advecting velocity -- they must read the SAME one."""
137 nx, ny, nz = 24, 12, 8
138 s = pf.SolverColocated(nx, ny, nz)
139 s.set_rho(1.0); s.set_mu(0.05); s.set_dt(0.5)
140 s.set_advection(
True); s.set_advection_scheme(
"koren")
141 s.set_domain_bc(
"-x",
"inflow", (1.0, 0.0, 0.0))
142 s.set_domain_bc(
"+x",
"outflow")
143 s.set_domain_bc(
"-y",
"wall"); s.set_domain_bc(
"+y",
"wall")
144 s.set_pressure_geometry(np.asfortranarray(np.full((nx, ny, nz), 10.0)))
145 s.set_pressure_pcg(
True, 200, 1e-9)
152 nx, ny, nz = 24, 12, 8
153 s = pf.Solver(nx, ny, nz)
154 s.set_rho(1.0); s.set_mu(0.05); s.set_dt(0.5)
155 s.set_advection(
True); s.set_advection_scheme(
"koren")
156 s.set_domain_bc(
"-x",
"inflow", (1.0, 0.0, 0.0))
157 s.set_domain_bc(
"+x",
"outflow")
158 s.set_domain_bc(
"-y",
"wall"); s.set_domain_bc(
"+y",
"wall")
159 s.set_pressure_geometry(np.asfortranarray(np.full((nx, ny, nz), 10.0)))
160 s.set_pressure_pcg(
True, 200, 1e-9)
168 s = pf.Solver(n, n, n)
169 s.set_rho(1.0); s.set_mu(0.1)
170 s.set_pressure_geometry(np.asfortranarray(np.full((n, n, n), 10.0)))
171 s.set_pressure_pcg(
True, 500, 1e-12)
173 s.set_vof(sphere_fractions((n, n, n), R, (n / 2 + 0.13, n / 2 + 0.27, n / 2 + 0.11)))
174 s.set_property_model(
"rho",
"linear",
"C", [1.0, 0.0])
175 s.set_surface_tension(1.0)
176 s.set_dt(0.25 * s.capillary_dt())
184 s = pf.Solver(N, N, nz)
185 s.set_rho(1.0); s.set_mu(0.05); s.set_dt(8.0)
186 s.set_implicit_advection(
True); s.diagnostics.set_outer_iterations(2)
187 for f
in (
"-x",
"+x",
"-y",
"+y"):
188 s.set_domain_bc(f,
"wall", (0.0, 0.0, 0.0))
189 s.set_pressure_geometry(np.asfortranarray(np.full((N, N, nz), 10.0)))
191 s.add_scalar(
"T", diffusivity=alpha, scheme=
"koren", iters=50)
192 s.set_scalar_bc(
"T",
"-x",
"dirichlet", 1.0); s.set_scalar_bc(
"T",
"+x",
"dirichlet", 0.0)
193 s.set_scalar_bc(
"T",
"-y",
"neumann", 0.0); s.set_scalar_bc(
"T",
"+y",
"neumann", 0.0)
194 coeff = 1e4 * 0.05 ** 2 / (0.71 * N ** 3)
195 s.set_property_model(
"force_y",
"boussinesq",
"T", [1.0, coeff, 1.0, 0.5])
197 T0 = np.repeat((1.0 - (x + 0.5) / N)[:,
None,
None], N, 1).repeat(nz, 2)
198 s.set_field(
"T", np.asfortranarray(T0.astype(np.float64)))
206 s = pf.Solver(N, N, N)
207 s.set_rho(1.0); s.set_mu(1.0); s.set_dt(0.5)
208 s.set_advection(
False)
209 s.set_pressure_geometry(np.asfortranarray(np.full((N, N, N), 10.0)))
211 s.set_porous_continuity(
True)
212 s.set_field(
"eps", np.asfortranarray(np.full((N, N, N), 0.6)))
213 s.set_field(
"drag_beta", np.asfortranarray(np.full((N, N, N), 4.0)))
214 s.diagnostics.exchange_field(
"eps"); s.diagnostics.exchange_field(
"drag_beta")
216 s.set_body_force((0.0, 0.0, 0.2))
224 s = pf.Solver(N, N, N)
225 s.set_rho(1.0); s.set_mu(0.1); s.set_dt(2.0); s.set_body_force((1e-3, 0.0, 0.0))
226 s.set_advection(
False)
227 s.set_pressure_pcg(
True, 200, 1e-9)
228 node_ints = np.array([1, -1, -1], dtype=np.int32)
229 node_reals = np.zeros(16); node_reals[0] = 3.0; node_reals[14] = 1.0; node_reals[15] = 1.0
230 ii = np.array([[0, -1]], dtype=np.int32)
231 ir = np.zeros((1, 18)); ir[0, 0:3] = (N / 2, N / 2, N / 2); ir[0, 6] = 1.0; ir[0, 7] = 1.0
232 s.set_scene(node_ints, node_reals, ii.ravel(), ir.ravel(), periodic=
True)
233 s.set_instance_transform(0, [N / 2, N / 2, N / 2], [0.0, 0.0, 0.0, 1.0])
234 s.set_instance_motion(0, lin_vel=[0.02, 0.0, 0.0], ang_vel=[0.0, 0.0, 0.005])
235 s.set_solid_from_scene(
True)
238 s.set_instance_transform(0, [N / 2 + 0.1, N / 2, N / 2], [0.0, 0.0, 0.0, 1.0])
262 from mpi4py
import MPI
263 comm = MPI.COMM_WORLD
266 origin, bsize = pf.mpi_block(N, N, N)
267 ox, oy, oz = origin; lnx, lny, lnz = bsize
268 lsdf = np.asfortranarray(gsdf[ox:ox + lnx, oy:oy + lny, oz:oz + lnz])
269 s = pf.Solver(lnx, lny, lnz)
271 s.set_rho(1.0); s.set_mu(0.1); s.set_dt(60.0); s.set_body_force((1e-3, 0.0, 0.0))
272 s.set_advection(
False)
273 s.diagnostics.set_velocity_solver_params(80)
274 s.set_pressure_multigrid(
True, 3)
275 s.set_pressure_pcg(
True, 200, 1e-9)
276 s.set_solid(lsdf, cutcell_pressure=
True)
279 loc = {k: np.ascontiguousarray(v, dtype=np.float64)
for k, v
in fields(s).items()}
280 allf = comm.gather(loc, root=0)
281 if comm.Get_rank() == 0:
282 d = {k: np.concatenate([np.asarray(r[k]).ravel()
for r
in allf])
for k
in loc}
283 report(f
"mpi_np{comm.Get_size()}", d)