flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
gperf.py
Go to the documentation of this file.
1#!/usr/bin/env python
2"""§11 G-perf, the Python half (WO-9; an instrument — it prints, it never fails on a number).
3
4 advance the scalar advance against the pressure projection of the same step, on a 128^3 bed
5 (G5b's simple-cubic sphere, solid fraction 0.3, one period; Stokes under G9b's body
6 force) at dt D / h^2 = 1: one cut-cell scalar (koren, Dirichlet spheres c = 0, c0 = 1)
7 carried by step(); per step the step's own 'projection' timer and a standalone
8 advance_scalars() at the same face field (both device-fenced: the budget read after it
9 reduces on the device).
10 gadvb the steady G-adv(b) closure solve at 64^3 (Neumann spheres, mean-gradient mode), Pe_h 1
11 and 10: wall time of the gated solve (the one after the Pe rescale).
12
13The other G-perf rows are tests/kokkos/bench_scalar_cutcell (triad, memory, matvec) and the
14`scalar_mg` ctest (the advective V-cycle against the symmetric one).
15
16Run: OMP_NUM_THREADS=4 PYTHONPATH=<build> python tests/study/scalar_ibm/gperf.py [advance] [gadvb]
17"""
18import math
19import os
20import sys
21import time
22
23import numpy as np
24import peclet.flow as pf
25
26sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../python"))
27import test_scalar_cutcell_gates as g
28
29
30def advance(n=128, warm=5, steps=5):
31 s = pf.Solver((n, n, n), extent=(1.0, 1.0, 1.0))
32 s.set_rho(1.0)
33 s.set_mu(1.0)
34 dt = 0.01
35 s.set_dt(dt)
36 R = (0.3 * 3.0 / (4.0 * math.pi)) ** (1.0 / 3.0)
37 X, Y, Z = g.grid(s)
38 s.set_solid(np.asfortranarray(np.sqrt((X - 0.513) ** 2 + (Y - 0.479) ** 2 + (Z - 0.507) ** 2) - R),
39 cutcell_pressure=True)
40 s.set_body_force((30.0, 9.0, 0.0))
41 for _ in range(warm):
42 s.step()
43 h = 1.0 / n
44 s.add_scalar("c", diffusivity=h * h / dt, scheme="koren", cutcell=True) # dt D / h^2 = 1
45 s.set_scalar_wall("c", "dirichlet", 0.0)
46 geo = s.diagnostics.scalar_geometry("c")
47 s.set_field("c", np.asfortranarray(np.where(geo["unknown"] > 0.5, 1.0, 0.0)))
48 rows = []
49 for _ in range(steps):
50 s.step()
51 tm = s.diagnostics.last_step_timers()
52 t0 = time.perf_counter()
53 s.advance_scalars()
54 s.diagnostics.scalar_budget("c")
55 ta = time.perf_counter() - t0
56 it = s.diagnostics.scalar_census("c")["krylov_iterations"]
57 rows.append((tm["step"], tm["projection"], ta, it))
58 print(f"advance {n}^3 bed, dt D/h^2 = 1 (koren, Dirichlet spheres), per step:")
59 for st, pr, ta, it in rows:
60 print(f" step {st * 1e3:8.1f} ms projection {pr * 1e3:8.1f} ms advance_scalars "
61 f"{ta * 1e3:8.1f} ms ({it} it) advance/projection {ta / pr:5.2f}")
62 med = np.median([r[2] / r[1] for r in rows])
63 print(f" median advance/projection {med:.2f} (red flag > 1)")
64
65
66def gadvb(n=64):
67 made, times = [], []
68
69 class Timed(pf.Solver):
70 def __init__(self, *a, **k):
71 super().__init__(*a, **k)
72 made.append(self)
73
74 def solve_scalar_steady(self, *a, **k):
75 t0 = time.perf_counter()
76 r = super().solve_scalar_steady(*a, **k)
77 self.diagnostics.scalar_budget("c") # a device reduction: fences
78 times.append(time.perf_counter() - t0)
79 return r
80
81 g.pf.Solver = Timed
82 for pe in (1.0, 10.0):
83 times.clear()
84 g.gadv_b_case(n, pe, "neumann")
85 it = made[-1].diagnostics.scalar_census("c")["krylov_iterations"]
86 print(f"gadvb {n}^3 Pe_h {pe:g}: gated solve {times[-1]:.3f} s ({it} it); the probe solve "
87 f"before the rescale (assembly + MG build) {times[0]:.3f} s")
88
89
90if __name__ == "__main__":
91 which = sys.argv[1:] or ["advance", "gadvb"]
92 if "advance" in which:
93 advance()
94 if "gadvb" in which:
95 gadvb()
advance(n=128, warm=5, steps=5)
Definition gperf.py:30
gadvb(n=64)
Definition gperf.py:66