flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
csg_wall_velocity_gate.py
Go to the documentation of this file.
1"""Does a MOVING CSG instance carry its wall velocity? A plug flow at U inside a square duct whose
2walls translate at +U has zero shear everywhere and must keep its mean velocity EXACTLY; the same
3plug against walls at rest loses momentum to the growing wall layers (~45% in 100 steps at these
4numbers). Three ducts: a box-DIFFERENCE instance moving, the same at rest (control), and four
5plain box-leaf instances moving.
6
7Usage: PYTHONPATH=<flow build> python csg_wall_velocity_gate.py
8"""
9import numpy as np
10from peclet import flow as sdflow
11from peclet import geom
12
13L, NY = 64, 32
14U, NU, DT = 0.02, 0.1067, 3.2
15KI_I, KI_R = 2, 17
16OFF, WX = 0.3, 5.335
17STEPS = 100
18HW = (L - 2 * WX) / 2 # cavity half-width
19
20
21def solver():
22 s = sdflow.Solver(L, NY, L)
23 s.set_rho(1.0); s.set_mu(NU); s.set_dt(DT); s.set_advection(True)
24 s.set_velocity_solver_params(60); s.set_pressure_solver_params(20)
25 s.set_pressure_multigrid(True, levels=3)
26 return s
27
28
29def run(kind, moving):
30 b = geom.SceneBuilder()
31 x0 = 0.5 * L + OFF
32 if kind == "difference":
33 slab = b.add_leaf("box", [L * 0.7, NY * 2.0, L * 0.7])
34 cav = b.add_leaf("box", [HW, NY * 2.0, HW])
35 node = b.add_difference(slab, cav)
36 ni, nr, _, _ = b.encode()
37 ii = np.zeros((1, KI_I), dtype=np.int32); ir = np.zeros((1, KI_R))
38 ii[0] = (node, -1); ir[0, 0:3] = (x0, 0.5 * NY, x0); ir[0, 6] = 1.0; ir[0, 7] = 1.0
39 ninst = 1
40 elif kind in ("sphere0+duct1", "duct0+sphere1"):
41 slab = b.add_leaf("box", [L * 0.7, NY * 2.0, L * 0.7])
42 cav = b.add_leaf("box", [HW, NY * 2.0, HW])
43 node = b.add_difference(slab, cav)
44 sph = b.add_leaf("sphere", [4.0])
45 ni, nr, _, _ = b.encode()
46 ii = np.zeros((2, KI_I), dtype=np.int32); ir = np.zeros((2, KI_R))
47 d, p = (1, 0) if kind == "sphere0+duct1" else (0, 1)
48 ii[d] = (node, -1); ir[d, 0:3] = (x0, 0.5 * NY, x0)
49 ii[p] = (sph, -1); ir[p, 0:3] = (x0, 0.5 * NY + OFF, x0)
50 ir[:, 6] = 1.0; ir[:, 7] = 1.0
51 ninst = 2
52 MOVE = [d] # only the duct moves; the sphere is a fixed obstacle
53 else: # four box leaves: slabs outside the cavity in x and z
54 thick = (L - 2 * HW) / 2 + 2.0
55 bx = b.add_leaf("box", [thick / 2, NY * 2.0, L * 0.7])
56 bz = b.add_leaf("box", [L * 0.7, NY * 2.0, thick / 2])
57 ni, nr, _, _ = b.encode()
58 ii = np.zeros((4, KI_I), dtype=np.int32); ir = np.zeros((4, KI_R))
59 cen = [(x0 - HW - thick / 2, bx), (x0 + HW + thick / 2, bx)]
60 ii[0] = (bx, -1); ir[0, 0:3] = (x0 - HW - thick / 2, 0.5 * NY, x0)
61 ii[1] = (bx, -1); ir[1, 0:3] = (x0 + HW + thick / 2, 0.5 * NY, x0)
62 ii[2] = (bz, -1); ir[2, 0:3] = (x0, 0.5 * NY, x0 - HW - thick / 2)
63 ii[3] = (bz, -1); ir[3, 0:3] = (x0, 0.5 * NY, x0 + HW + thick / 2)
64 for i in range(4):
65 ir[i, 6] = 1.0; ir[i, 7] = 1.0
66 ninst = 4
67 s = solver()
68 s.set_scene(np.asarray(ni, np.int32), np.asarray(nr, float), ii.ravel(), ir.ravel(),
69 periodic=True)
70 if moving:
71 for i in (MOVE if kind in ("sphere0+duct1", "duct0+sphere1") else range(ninst)):
72 s.set_instance_motion(i, lin_vel=[0.0, U, 0.0])
73 s.set_solid_from_scene(True)
74 s.set_velocity(1, np.full((L, NY, L), U, dtype=np.float64, order="F"))
75 v0 = float(np.asarray(s.get_v()).sum())
76 out = []
77 for k in range(STEPS):
78 s.step()
79 if k in (0, 9, 49, STEPS - 1):
80 out.append((k + 1, float(np.asarray(s.get_v()).sum()) / v0))
81 return out
82
83
84import sys
85CASES = (("sphere0+duct1", True), ("duct0+sphere1", True)) if len(sys.argv) > 1 else (("difference", True), ("difference", False), ("four-box", True))
86for kind, moving in CASES:
87 r = run(kind, moving)
88 print(" %-11s walls %-6s : momentum fraction " % (kind, "moving" if moving else "AT REST")
89 + " ".join("k=%d:%.4f" % t for t in r))