core 1.5.0
Shared MPI block decomposition, asynchronous ghost-layer exchange, SDF geometry, load balancing (header-only C++20)
Loading...
Searching...
No Matches
probe_flux.hpp
Go to the documentation of this file.
1
30#ifndef PECLET_CORE_SCHEME_PROBE_FLUX_HPP
31#define PECLET_CORE_SCHEME_PROBE_FLUX_HPP
32
33#include <cmath>
34
35#include "peclet/core/scheme/cut_cell_closure.hpp" // PECLET_CORE_CC_HD
36
37namespace peclet::core::scheme {
38
40inline constexpr int kProbeR0 = 0;
41inline constexpr int kProbeR1a = 1;
42inline constexpr int kProbeR1b = 2;
43inline constexpr int kProbeR2 = 3;
44
46inline constexpr double kProbeSigma = 1.1;
47inline constexpr double kProbeSigmaLong = 1.5;
48inline constexpr double kProbeSigmaLast = 0.5;
50inline constexpr double kProbeWeightEps = 1e-12;
52inline constexpr double kProbeClearance = 0.5;
54inline constexpr int kProbeReach = 2;
56inline constexpr double kProbeGapMin = 0.2;
58inline constexpr double kProbeMinKeptWeight = 0.5;
59
65 int rung;
66 double s;
67 int n;
68 int off[8][3];
69 double w[8];
70};
71
75PECLET_CORE_CC_HD double probeSupport(const double n[3], const double h[3]) {
76 const double ax = n[0] < 0.0 ? -n[0] : n[0];
77 const double ay = n[1] < 0.0 ? -n[1] : n[1];
78 const double az = n[2] < 0.0 ? -n[2] : n[2];
79 return 0.5 * (ax * h[0] + ay * h[1] + az * h[2]);
80}
81
82namespace detail {
83
84PECLET_CORE_CC_HD double probeFloor(double x) {
85#ifdef KOKKOS_INLINE_FUNCTION
86 return Kokkos::floor(x);
87#else
88 return std::floor(x);
89#endif
90}
91
92} // namespace detail
93
97PECLET_CORE_CC_HD void trilinearStencil(const double xi[3], int base[3], double w[8]) {
98 double f[3];
99 for (int a = 0; a < 3; ++a) {
100 const double b = detail::probeFloor(xi[a]);
101 base[a] = static_cast<int>(b);
102 f[a] = xi[a] - b;
103 }
104 for (int k = 0; k < 8; ++k) {
105 const double wx = (k & 1) ? f[0] : 1.0 - f[0];
106 const double wy = ((k >> 1) & 1) ? f[1] : 1.0 - f[1];
107 const double wz = ((k >> 2) & 1) ? f[2] : 1.0 - f[2];
108 w[k] = wx * wy * wz;
109 }
110}
111
112namespace detail {
113
114// The candidate probe at distance s: index-space point xi, its trilinear stencil, and V3.
115PECLET_CORE_CC_HD bool probeCandidate(const double xw[3], const double n[3], const double h[3],
116 double s, double xi[3], int base[3], double w[8]) {
117 for (int a = 0; a < 3; ++a)
118 xi[a] = (xw[a] + s * n[a]) / h[a];
120 for (int a = 0; a < 3; ++a)
121 if (base[a] < -kProbeReach || base[a] + 1 > kProbeReach)
122 return false; // V3
123 return true;
124}
125
126// V1: every cell with weight > kProbeWeightEps is an unknown of the phase.
127template <class Lookup>
128PECLET_CORE_CC_HD bool probeAllUnknown(const int base[3], const double w[8], const Lookup& L) {
129 for (int k = 0; k < 8; ++k)
130 if (w[k] > kProbeWeightEps &&
131 !L.unknown(base[0] + (k & 1), base[1] + ((k >> 1) & 1), base[2] + ((k >> 2) & 1)))
132 return false;
133 return true;
134}
135
136PECLET_CORE_CC_HD void probeFillAll(ProbeResult& r, int rung, double s, const int base[3],
137 const double w[8]) {
138 r.rung = rung;
139 r.s = s;
140 r.n = 8;
141 for (int k = 0; k < 8; ++k) {
142 r.off[k][0] = base[0] + (k & 1);
143 r.off[k][1] = base[1] + ((k >> 1) & 1);
144 r.off[k][2] = base[2] + ((k >> 2) & 1);
145 r.w[k] = w[k];
146 }
147}
148
149} // namespace detail
150
157template <class Lookup>
158PECLET_CORE_CC_HD ProbeResult buildProbe(const double xw[3], const double n[3], const double h[3],
159 const Lookup& L) {
160 ProbeResult r;
161 const double S = probeSupport(n, h);
162 double xi[3], w[8];
163 int base[3];
164
165 // R0: s0 = 1.1 S, trilinear, V1 ∧ V2 ∧ V3.
166 const double s0 = kProbeSigma * S;
167 const bool reach0 = detail::probeCandidate(xw, n, h, s0, xi, base, w);
168 double phi0 = 0.0;
169 if (reach0) {
170 phi0 = L.phi(xi);
171 const bool v1 = detail::probeAllUnknown(base, w, L);
172 const bool v2 = phi0 >= kProbeClearance * s0;
173 if (v1 && v2) {
175 return r;
176 }
177 // R1a: R0 failed V1 only -> a longer probe, s = 1.5 S.
178 if (v2) {
179 const double s1 = kProbeSigmaLong * S;
180 if (detail::probeCandidate(xw, n, h, s1, xi, base, w) &&
181 detail::probeAllUnknown(base, w, L) && L.phi(xi) >= kProbeClearance * s1) {
183 return r;
184 }
185 }
186 // R1b: probe the estimated gap midpoint, s = ½ w with w = s0 + φ(p0), dropping the cells
187 // that are not unknowns and renormalizing.
188 const double gap = s0 + phi0;
189 if (gap > kProbeGapMin * S) {
190 const double s1 = 0.5 * gap;
191 if (detail::probeCandidate(xw, n, h, s1, xi, base, w)) {
192 int m = 0;
193 double sum = 0.0;
194 for (int k = 0; k < 8; ++k) {
195 const int o0 = base[0] + (k & 1), o1 = base[1] + ((k >> 1) & 1), o2 = base[2] + (k >> 2);
196 if (!L.unknown(o0, o1, o2))
197 continue;
198 r.off[m][0] = o0;
199 r.off[m][1] = o1;
200 r.off[m][2] = o2;
201 r.w[m] = w[k];
202 sum += w[k];
203 ++m;
204 }
205 if (sum >= kProbeMinKeptWeight) {
206 for (int k = 0; k < m; ++k)
207 r.w[k] /= sum;
208 r.rung = kProbeR1b;
209 r.s = s1;
210 r.n = m;
211 return r;
212 }
213 }
214 }
215 }
216
217 // R2 (last resort, first order): the cell itself at s = 0.5 S.
218 r.rung = kProbeR2;
219 r.s = kProbeSigmaLast * S;
220 r.n = 1;
221 r.off[0][0] = r.off[0][1] = r.off[0][2] = 0;
222 r.w[0] = 1.0;
223 return r;
224}
225
229PECLET_CORE_CC_HD double wallConductance(double s, double L, double k) {
230 constexpr double kDoubleMax = 1.7976931348623157e308;
231 if (!(k > 0.0))
232 return 0.0;
233 if (k > kDoubleMax)
234 return L / s;
235 return 1.0 / (s / L + 1.0 / k);
236}
237
241PECLET_CORE_CC_HD double interfaceConductance(double sf, double Lf, double Rc, double ss,
242 double Ls) {
243 return 1.0 / (sf / Lf + Rc + ss / Ls);
244}
245
246} // namespace peclet::core::scheme
247
248#endif // PECLET_CORE_SCHEME_PROBE_FLUX_HPP
core — the shared cut-cell IBM boundary-distance closure polynomials (flow <-> amr).
#define PECLET_CORE_CC_HD
PECLET_CORE_CC_HD void probeFillAll(ProbeResult &r, int rung, double s, const int base[3], const double w[8])
PECLET_CORE_CC_HD bool probeAllUnknown(const int base[3], const double w[8], const Lookup &L)
PECLET_CORE_CC_HD bool probeCandidate(const double xw[3], const double n[3], const double h[3], double s, double xi[3], int base[3], double w[8])
PECLET_CORE_CC_HD double probeFloor(double x)
constexpr int kProbeReach
V3: every stencil cell within ±kProbeReach cells on each axis (the G = 2 halo).
constexpr double kProbeSigma
Probe distance factors on S(n) (§3.1, §3.3): R0 = 1.1, R1a = 1.5, R2 = 0.5.
PECLET_CORE_CC_HD double interfaceConductance(double sf, double Lf, double Rc, double ss, double Ls)
Conjugate interface conductance (§1.4): the series resistance of the fluid probe leg,...
constexpr double kProbeSigmaLong
constexpr double kProbeMinKeptWeight
... and accepted only when the kept weights sum to at least kProbeMinKeptWeight.
@ gap
two facets, fluid between two walls
PECLET_CORE_CC_HD double wallConductance(double s, double L, double k)
Wall conductance of a Robin facet (§1.4): G = 1 / (s/L + 1/k), the flux out of the fluid per area bei...
constexpr double kProbeWeightEps
V1 ignores stencil cells whose weight is at most this.
constexpr double kProbeSigmaLast
constexpr int kProbeR0
Ladder rungs, in ProbeResult::rung (flow stores them as uint8).
constexpr int kProbeR1b
constexpr int kProbeR2
PECLET_CORE_CC_HD double probeSupport(const double n[3], const double h[3])
S(n) = ½ Σ_a |n_a| h_a: the support half-width of a cell of size h along the unit normal n (§3....
constexpr double kProbeGapMin
R1b is attempted only when the estimated gap w exceeds kProbeGapMin · S(n) ...
PECLET_CORE_CC_HD ProbeResult buildProbe(const double xw[3], const double n[3], const double h[3], const Lookup &L)
Build the probe of one facet by the ladder of §3.3.
PECLET_CORE_CC_HD void trilinearStencil(const double xi[3], int base[3], double w[8])
Trilinear stencil of the index-space point ξ (cell centres at integer ξ, relative to the facet's cell...
constexpr int kProbeR1a
constexpr double kProbeClearance
V2: φ_phase(p) ≥ kProbeClearance · s.
Kokkos::View< T *, MemSpace > View
1D device array.
Definition view.hpp:26
One facet's probe: the rung, the probe distance s, and n stencil cells (lattice offsets relative to t...