peclet.voro 1.0.4
Device-native moving-particle Voronoi dynamics
Loading...
Searching...
No Matches
operators.hpp
Go to the documentation of this file.
1
15#ifndef PECLET_VORO_FV_OPERATORS_HPP
16#define PECLET_VORO_FV_OPERATORS_HPP
17
18#include <functional>
19#include <Kokkos_Core.hpp>
20
22
23namespace peclet::voro::fv {
24
25template <class Real>
26using DV = Kokkos::View<Real*, peclet::core::MemSpace>;
27
29template <class Real>
30void divergence(const FaceMesh<Real>& m, const DV<Real>& u, const DV<Real>& out) {
31 using Exec = peclet::core::ExecSpace;
32 Kokkos::parallel_for(
33 "fv.div", Kokkos::RangePolicy<Exec>(0, m.nCells), KOKKOS_LAMBDA(const int i) {
34 Real acc = 0;
35 for (int q = m.cellFacesBegin(i); q < m.cellFacesEnd(i); ++q) {
36 const int f = m.cellFace(q);
37 acc += m.cellFaceSign(q) * u(f) * m.faceArea(f);
38 }
39 out(i) = acc / m.cellVolume(i);
40 });
41}
42
45template <class Real>
46void faceGradient(const FaceMesh<Real>& m, const DV<Real>& p, const DV<Real>& out,
47 const DV<Real>& pb = DV<Real>{}) {
48 using Exec = peclet::core::ExecSpace;
49 const int nI = m.nInterior;
50 const bool dir = pb.extent(0) > 0;
51 Kokkos::parallel_for(
52 "fv.gradN", Kokkos::RangePolicy<Exec>(0, m.nFaces), KOKKOS_LAMBDA(const int f) {
53 const int a = m.faceCellA(f);
54 if (f < nI) {
55 out(f) = (p(m.faceCellB(f)) - p(a)) / m.faceDist(f);
56 } else {
57 out(f) = dir ? (pb(f - nI) - p(a)) / m.faceHa(f) : Real(0);
58 }
59 });
60}
61
63template <class Real>
64void laplacian(const FaceMesh<Real>& m, const DV<Real>& p, const DV<Real>& out,
65 DV<Real>& scratchFace, const DV<Real>& pb = DV<Real>{}) {
66 if ((int)scratchFace.extent(0) != m.nFaces)
67 scratchFace = DV<Real>("fv.scratchFace", m.nFaces);
68 faceGradient(m, p, scratchFace, pb);
69 divergence(m, scratchFace, out);
70}
71
73template <class Real>
74void greenGaussGradient(const FaceMesh<Real>& m, const DV<Real>& p, const DV<Real>& out) {
75 using Exec = peclet::core::ExecSpace;
76 const int nI = m.nInterior;
77 Kokkos::parallel_for(
78 "fv.greenGauss", Kokkos::RangePolicy<Exec>(0, m.nCells), KOKKOS_LAMBDA(const int i) {
79 Real g[3] = {0, 0, 0};
80 for (int q = m.cellFacesBegin(i); q < m.cellFacesEnd(i); ++q) {
81 const int f = m.cellFace(q);
82 const int a = m.faceCellA(f);
83 Real pf;
84 if (f < nI) {
85 const int b = m.faceCellB(f);
86 const Real ha = m.faceHa(f), hb = m.faceHb(f);
87 pf = (hb * p(a) + ha * p(b)) / (ha + hb); // linear along the connector
88 } else {
89 pf = p(a);
90 }
91 const Real w = m.cellFaceSign(q) * pf * m.faceArea(f);
92 for (int c = 0; c < 3; ++c)
93 g[c] += w * m.normal(f, c);
94 }
95 const Real iv = Real(1) / m.cellVolume(i);
96 for (int c = 0; c < 3; ++c)
97 out(3 * i + c) = g[c] * iv;
98 });
99}
100
102template <class Real>
103void perotVelocity(const FaceMesh<Real>& m, const DV<Real>& u, const DV<Real>& out) {
104 using Exec = peclet::core::ExecSpace;
105 Kokkos::parallel_for(
106 "fv.perot", Kokkos::RangePolicy<Exec>(0, m.nCells), KOKKOS_LAMBDA(const int i) {
107 Real v[3] = {0, 0, 0};
108 for (int q = m.cellFacesBegin(i); q < m.cellFacesEnd(i); ++q) {
109 const int f = m.cellFace(q);
110 const Real s = m.cellFaceSign(q);
111 const Real w = s * u(f) * m.faceArea(f);
112 // the face centroid relative to THIS cell's seed: A-relative as stored, or shifted by the
113 // connector for the B side
114 for (int c = 0; c < 3; ++c) {
115 const Real cf = m.centroid(f, c) - (s < 0 ? m.conn(f, c) : Real(0));
116 v[c] += w * cf;
117 }
118 }
119 const Real iv = Real(1) / m.cellVolume(i);
120 for (int c = 0; c < 3; ++c)
121 out(3 * i + c) = v[c] * iv;
122 });
123}
124
130template <class Real>
131KOKKOS_INLINE_FUNCTION void cellSkewInverse(const FaceMesh<Real>& m, int i, Real R[9]) {
132 Real A[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; // I − S
133 const Real iv = Real(1) / m.cellVolume(i);
134 for (int q = m.cellFacesBegin(i); q < m.cellFacesEnd(i); ++q) {
135 const int f = m.cellFace(q); // all faces: the identity holds for the full polytope
136 const Real w = m.cellFaceSign(q) * m.faceArea(f) * iv, ha = m.faceHa(f);
137 for (int r = 0; r < 3; ++r) {
138 const Real t = m.centroid(f, r) - ha * m.normal(f, r);
139 for (int k = 0; k < 3; ++k)
140 A[3 * r + k] -= w * t * m.normal(f, k);
141 }
142 }
143 const Real det = A[0] * (A[4] * A[8] - A[5] * A[7]) - A[1] * (A[3] * A[8] - A[5] * A[6]) +
144 A[2] * (A[3] * A[7] - A[4] * A[6]);
145 const Real id = Real(1) / det;
146 R[0] = (A[4] * A[8] - A[5] * A[7]) * id;
147 R[1] = (A[2] * A[7] - A[1] * A[8]) * id;
148 R[2] = (A[1] * A[5] - A[2] * A[4]) * id;
149 R[3] = (A[5] * A[6] - A[3] * A[8]) * id;
150 R[4] = (A[0] * A[8] - A[2] * A[6]) * id;
151 R[5] = (A[2] * A[3] - A[0] * A[5]) * id;
152 R[6] = (A[3] * A[7] - A[4] * A[6]) * id;
153 R[7] = (A[1] * A[6] - A[0] * A[7]) * id;
154 R[8] = (A[0] * A[4] - A[1] * A[3]) * id;
155}
156
160template <class Real>
161void vectorGreenGauss(const FaceMesh<Real>& m, const DV<Real>& U, const DV<Real>& out,
162 const DV<Real>& Uwall = DV<Real>{}) {
163 using Exec = peclet::core::ExecSpace;
164 const int nI = m.nInterior;
165 const bool hasW = Uwall.extent(0) > 0;
166 Kokkos::parallel_for(
167 "fv.vgg", Kokkos::RangePolicy<Exec>(0, m.nCells), KOKKOS_LAMBDA(const int i) {
168 Real g[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
169 for (int q = m.cellFacesBegin(i); q < m.cellFacesEnd(i); ++q) {
170 const int f = m.cellFace(q);
171 const Real s = m.cellFaceSign(q);
172 const int a = m.faceCellA(f), b = m.faceCellB(f);
173 Real Uf[3];
174 if (f < nI) {
175 const Real ha = m.faceHa(f), hb = m.faceHb(f);
176 for (int c = 0; c < 3; ++c)
177 Uf[c] = (hb * U(3 * a + c) + ha * U(3 * b + c)) / (ha + hb);
178 } else {
179 for (int c = 0; c < 3; ++c)
180 Uf[c] = hasW ? Uwall(3 * (f - nI) + c) : U(3 * i + c);
181 }
182 const Real w = s * m.faceArea(f);
183 for (int c = 0; c < 3; ++c)
184 for (int k = 0; k < 3; ++k)
185 g[3 * c + k] += w * Uf[c] * m.normal(f, k);
186 }
187 Real R[9];
188 cellSkewInverse(m, i, R);
189 const Real iv = Real(1) / m.cellVolume(i);
190 for (int c = 0; c < 3; ++c)
191 for (int k = 0; k < 3; ++k) {
192 Real v = 0;
193 for (int kk = 0; kk < 3; ++kk)
194 v += R[3 * k + kk] * g[3 * c + kk];
195 out(9 * i + 3 * c + k) = v * iv;
196 }
197 });
198}
199
205template <class Real>
206void projectToFaces(const FaceMesh<Real>& m, const DV<Real>& ucell, const DV<Real>& out,
207 const DV<Real>& gradU = DV<Real>{}, const DV<Real>& ub = DV<Real>{}) {
208 using Exec = peclet::core::ExecSpace;
209 const int nI = m.nInterior;
210 const bool skew = gradU.extent(0) > 0, hasB = ub.extent(0) > 0;
211 Kokkos::parallel_for(
212 "fv.project", Kokkos::RangePolicy<Exec>(0, m.nFaces), KOKKOS_LAMBDA(const int f) {
213 const int a = m.faceCellA(f);
214 Real un = 0;
215 if (f < nI) {
216 const int b = m.faceCellB(f);
217 const Real ha = m.faceHa(f), hb = m.faceHb(f), wa = hb / (ha + hb), wb = ha / (ha + hb);
218 for (int c = 0; c < 3; ++c)
219 un += (wa * ucell(3 * a + c) + wb * ucell(3 * b + c)) * m.normal(f, c);
220 if (skew) {
221 Real t[3];
222 for (int k = 0; k < 3; ++k)
223 t[k] = m.centroid(f, k) - ha * m.normal(f, k);
224 for (int c = 0; c < 3; ++c) {
225 Real dc = 0;
226 for (int k = 0; k < 3; ++k)
227 dc += (wa * gradU(9 * a + 3 * c + k) + wb * gradU(9 * b + 3 * c + k)) * t[k];
228 un += dc * m.normal(f, c);
229 }
230 }
231 } else if (hasB) { // wall / inflow: the prescribed boundary flux
232 un = ub(f - nI);
233 } else {
234 for (int c = 0; c < 3; ++c)
235 un += ucell(3 * a + c) * m.normal(f, c);
236 }
237 out(f) = un;
238 });
239}
240
241template <class Real>
242Real dotCells(const FaceMesh<Real>& m, const DV<Real>& a, const DV<Real>& b) {
243 using Exec = peclet::core::ExecSpace;
244 Real s = 0;
245 Kokkos::parallel_reduce(
246 "fv.dotCells", Kokkos::RangePolicy<Exec>(0, m.nCells),
247 KOKKOS_LAMBDA(const int i, Real& acc) { acc += m.cellVolume(i) * a(i) * b(i); }, s);
248 return s;
249}
250template <class Real>
251Real dotFaces(const FaceMesh<Real>& m, const DV<Real>& a, const DV<Real>& b) {
252 using Exec = peclet::core::ExecSpace;
253 Real s = 0;
254 Kokkos::parallel_reduce(
255 "fv.dotFaces", Kokkos::RangePolicy<Exec>(0, m.nInterior),
256 KOKKOS_LAMBDA(const int f, Real& acc) { acc += m.faceArea(f) * m.faceDist(f) * a(f) * b(f); },
257 s);
258 return s;
259}
260
271template <class Real>
272void faceInterpTranspose(const FaceMesh<Real>& m, const DV<Real>& g, const DV<Real>& out,
273 bool skew = false, const DV<Real>& scratch9 = DV<Real>{},
274 bool wallPrescribed = false,
275 const std::function<void(const DV<Real>&, int)>& exchange = {}) {
276 using Exec = peclet::core::ExecSpace;
277 const int nI = m.nInterior;
278 Kokkos::parallel_for(
279 "fv.T0t", Kokkos::RangePolicy<Exec>(0, m.nCells), KOKKOS_LAMBDA(const int i) {
280 Real v[3] = {0, 0, 0}, M[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
281 for (int q = m.cellFacesBegin(i); q < m.cellFacesEnd(i); ++q) {
282 const int f = m.cellFace(q);
283 if (f >= nI)
284 continue;
285 const Real ha = m.faceHa(f), hb = m.faceHb(f);
286 const Real wi = (m.cellFaceSign(q) > 0 ? hb : ha) / (ha + hb);
287 const Real w = m.faceArea(f) * (ha + hb) * wi * g(f);
288 for (int c = 0; c < 3; ++c)
289 v[c] += w * m.normal(f, c);
290 if (skew) {
291 Real t[3];
292 for (int k = 0; k < 3; ++k)
293 t[k] = m.centroid(f, k) - ha * m.normal(f, k);
294 for (int c = 0; c < 3; ++c)
295 for (int k = 0; k < 3; ++k)
296 M[3 * c + k] += w * m.normal(f, c) * t[k];
297 }
298 }
299 const Real iv = Real(1) / m.cellVolume(i);
300 for (int c = 0; c < 3; ++c)
301 out(3 * i + c) = v[c] * iv;
302 if (skew) { // (M_i R_i) / V_i — the transpose of the skew correction R (row index k)
303 Real R[9];
304 cellSkewInverse(m, i, R);
305 for (int c = 0; c < 3; ++c)
306 for (int k = 0; k < 3; ++k) {
307 Real v2 = 0;
308 for (int kk = 0; kk < 3; ++kk)
309 v2 += M[3 * c + kk] * R[3 * kk + k];
310 scratch9(9 * i + 3 * c + k) = v2 * iv;
311 }
312 }
313 });
314 if (!skew)
315 return;
316 if (exchange)
317 exchange(scratch9, 9); // distributed: the neighbours' M/V (rung C5)
318 // GGᵀ: coefficient of U_c(i) = Σ_{f∈i} w_if q_fc, q_fc = Σ_k A_f n_fk (M_A/V_A − M_B/V_B)_ck
319 Kokkos::parallel_for(
320 "fv.T1t", Kokkos::RangePolicy<Exec>(0, m.nCells), KOKKOS_LAMBDA(const int i) {
321 Real v[3] = {0, 0, 0};
322 for (int q = m.cellFacesBegin(i); q < m.cellFacesEnd(i); ++q) {
323 const int f = m.cellFace(q);
324 if (f >= nI) { // vectorGreenGauss used the cell value on a boundary face (unless
325 // a wall velocity was prescribed: then the face value is a constant)
326 if (wallPrescribed)
327 continue;
328 for (int c = 0; c < 3; ++c)
329 for (int k = 0; k < 3; ++k)
330 v[c] += m.faceArea(f) * m.normal(f, k) * scratch9(9 * i + 3 * c + k);
331 continue;
332 }
333 const int a = m.faceCellA(f), b = m.faceCellB(f);
334 const Real ha = m.faceHa(f), hb = m.faceHb(f);
335 const Real wi = (m.cellFaceSign(q) > 0 ? hb : ha) / (ha + hb);
336 for (int c = 0; c < 3; ++c) {
337 Real qf = 0;
338 for (int k = 0; k < 3; ++k)
339 qf += m.faceArea(f) * m.normal(f, k) *
340 (scratch9(9 * a + 3 * c + k) - scratch9(9 * b + 3 * c + k));
341 v[c] += wi * qf;
342 }
343 }
344 const Real iv = Real(1) / m.cellVolume(i);
345 for (int c = 0; c < 3; ++c)
346 out(3 * i + c) += v[c] * iv;
347 });
348}
349
358template <class Real>
359void wallGradientLS(const FaceMesh<Real>& m, const DV<Real>& U, const DV<Real>& gradU,
360 const DV<Real>& Uwall, const DV<Real>& out) {
361 using Exec = peclet::core::ExecSpace;
362 const int nI = m.nInterior, nB = m.nFaces - nI;
363 const bool hasG = gradU.extent(0) > 0, hasW = Uwall.extent(0) > 0;
364 Kokkos::parallel_for(
365 "fv.wallLS", Kokkos::RangePolicy<Exec>(0, nB), KOKKOS_LAMBDA(const int b) {
366 const int f = nI + b, i = m.faceCellA(f);
367 const Real ha = m.faceHa(f);
368 Real n[3], Uw[3];
369 for (int c = 0; c < 3; ++c) {
370 n[c] = m.normal(f, c);
371 Uw[c] = hasW ? Uwall(3 * b + c) : Real(0);
372 }
373 // normal equations of u − U_wall = a s + b s²: [S2 S3; S3 S4] [a; b] = [R1; R2]
374 Real S2 = 0, S3 = 0, S4 = 0, R1[3] = {0, 0, 0}, R2[3] = {0, 0, 0};
375 auto add = [&](Real s, const Real du[3]) {
376 const Real s2 = s * s;
377 S2 += s2;
378 S3 += s2 * s;
379 S4 += s2 * s2;
380 for (int c = 0; c < 3; ++c) {
381 R1[c] += s * du[c];
382 R2[c] += s2 * du[c];
383 }
384 };
385 Real du[3];
386 for (int c = 0; c < 3; ++c)
387 du[c] = U(3 * i + c) - Uw[c];
388 add(ha, du);
389 for (int q = m.cellFacesBegin(i); q < m.cellFacesEnd(i); ++q) {
390 const int g = m.cellFace(q);
391 if (g >= nI)
392 continue;
393 const Real sg = m.cellFaceSign(q);
394 const int j = sg > 0 ? m.faceCellB(g) : m.faceCellA(g);
395 Real d[3], dn = 0;
396 for (int c = 0; c < 3; ++c) {
397 d[c] = sg * m.conn(g, c); // x_j − x_i
398 dn += d[c] * n[c];
399 }
400 const Real s = ha - dn; // n points toward the wall: away from it is −n
401 if (!(s > Real(0.05) * ha))
402 continue;
403 for (int c = 0; c < 3; ++c) {
404 Real tang = 0;
405 if (hasG)
406 for (int k = 0; k < 3; ++k)
407 tang += gradU(9 * i + 3 * c + k) * (d[k] - dn * n[k]);
408 du[c] = U(3 * j + c) - tang - Uw[c];
409 }
410 add(s, du);
411 }
412 const Real det = S2 * S4 - S3 * S3;
413 for (int c = 0; c < 3; ++c) {
414 Real a;
415 if (det > Real(1e-30) * S2 * S4)
416 a = (S4 * R1[c] - S3 * R2[c]) / det;
417 else
418 a = (U(3 * i + c) - Uw[c]) / ha; // no second abscissa: the two-point gradient
419 out(3 * b + c) = a;
420 }
421 });
422}
423
428template <class Real>
429int poissonCG(const FaceMesh<Real>& m, const DV<Real>& f, const DV<Real>& p, Real tol, int maxIter,
430 Real& resOut) {
431 using Exec = peclet::core::ExecSpace;
432 const int N = m.nCells;
433 DV<Real> r("cg.r", N), z("cg.z", N), q("cg.q", N), sf;
434 Real Vtot = 0, fMean = 0;
435 Kokkos::parallel_reduce(
436 "cg.vtot", Kokkos::RangePolicy<Exec>(0, N),
437 KOKKOS_LAMBDA(const int i, Real& acc) { acc += m.cellVolume(i); }, Vtot);
438 Kokkos::parallel_reduce(
439 "cg.fmean", Kokkos::RangePolicy<Exec>(0, N),
440 KOKKOS_LAMBDA(const int i, Real& acc) { acc += m.cellVolume(i) * f(i); }, fMean);
441 fMean /= Vtot;
442 Kokkos::deep_copy(p, Real(0));
443 // r = f − mean(f) − (−L p) = f − mean(f) at p = 0
444 Kokkos::parallel_for(
445 "cg.r0", Kokkos::RangePolicy<Exec>(0, N),
446 KOKKOS_LAMBDA(const int i) { r(i) = f(i) - fMean; });
447 Kokkos::deep_copy(z, r);
448 Real rr = dotCells(m, r, r);
449 const Real r0 = Kokkos::sqrt(rr);
450 if (!(r0 > Real(0))) { // zero (or NaN) right-hand side: p = 0 is the solution
451 resOut = 0;
452 return 0;
453 }
454 int it = 0;
455 for (; it < maxIter; ++it) {
456 laplacian(m, z, q, sf);
457 Kokkos::parallel_for(
458 "cg.negq", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(const int i) { q(i) = -q(i); });
459 const Real zq = dotCells(m, z, q);
460 if (!(zq > Real(0))) // z in the null space (converged to round-off)
461 break;
462 const Real alpha = rr / zq;
463 Kokkos::parallel_for(
464 "cg.upd", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(const int i) {
465 p(i) += alpha * z(i);
466 r(i) -= alpha * q(i);
467 });
468 const Real rrn = dotCells(m, r, r);
469 resOut = Kokkos::sqrt(rrn) / (r0 > Real(0) ? r0 : Real(1));
470 if (resOut < tol) {
471 ++it;
472 break;
473 }
474 const Real beta = rrn / rr;
475 rr = rrn;
476 Kokkos::parallel_for(
477 "cg.z", Kokkos::RangePolicy<Exec>(0, N),
478 KOKKOS_LAMBDA(const int i) { z(i) = r(i) + beta * z(i); });
479 }
480 // pin the mean of p to zero
481 Real pMean = 0;
482 Kokkos::parallel_reduce(
483 "cg.pmean", Kokkos::RangePolicy<Exec>(0, N),
484 KOKKOS_LAMBDA(const int i, Real& acc) { acc += m.cellVolume(i) * p(i); }, pMean);
485 pMean /= Vtot;
486 Kokkos::parallel_for(
487 "cg.pin", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(const int i) { p(i) -= pMean; });
488 return it;
489}
490
491} // namespace peclet::voro::fv
492
493#endif // PECLET_VORO_FV_OPERATORS_HPP
Track C, rung C1 (Voronoi methods plan): the FACE mesh of a published tessellation — one record per g...
Definition collocated.hpp:38
void laplacian(const FaceMesh< Real > &m, const DV< Real > &p, const DV< Real > &out, DV< Real > &scratchFace, const DV< Real > &pb=DV< Real >{})
L p = div(grad p): the two-point Laplacian (Neumann on boundary faces unless pb is given).
Definition operators.hpp:64
Real dotCells(const FaceMesh< Real > &m, const DV< Real > &a, const DV< Real > &b)
Definition operators.hpp:242
void vectorGreenGauss(const FaceMesh< Real > &m, const DV< Real > &U, const DV< Real > &out, const DV< Real > &Uwall=DV< Real >{})
Definition operators.hpp:161
void faceInterpTranspose(const FaceMesh< Real > &m, const DV< Real > &g, const DV< Real > &out, bool skew=false, const DV< Real > &scratch9=DV< Real >{}, bool wallPrescribed=false, const std::function< void(const DV< Real > &, int)> &exchange={})
Definition operators.hpp:272
void projectToFaces(const FaceMesh< Real > &m, const DV< Real > &ucell, const DV< Real > &out, const DV< Real > &gradU=DV< Real >{}, const DV< Real > &ub=DV< Real >{})
Definition operators.hpp:206
Kokkos::View< Real *, peclet::core::MemSpace > DV
Definition operators.hpp:26
KOKKOS_INLINE_FUNCTION void cellSkewInverse(const FaceMesh< Real > &m, int i, Real R[9])
Definition operators.hpp:131
void divergence(const FaceMesh< Real > &m, const DV< Real > &u, const DV< Real > &out)
(div u)_i from face-normal fluxes u (nFaces; boundary faces included, along the outward normal).
Definition operators.hpp:30
void faceGradient(const FaceMesh< Real > &m, const DV< Real > &p, const DV< Real > &out, const DV< Real > &pb=DV< Real >{})
Definition operators.hpp:46
void perotVelocity(const FaceMesh< Real > &m, const DV< Real > &u, const DV< Real > &out)
Perot reconstruction of the cell velocity (3N) from face-normal fluxes.
Definition operators.hpp:103
void wallGradientLS(const FaceMesh< Real > &m, const DV< Real > &U, const DV< Real > &gradU, const DV< Real > &Uwall, const DV< Real > &out)
Definition operators.hpp:359
void greenGaussGradient(const FaceMesh< Real > &m, const DV< Real > &p, const DV< Real > &out)
Green–Gauss cell gradient (3N): distance-weighted face values, boundary faces use p_A.
Definition operators.hpp:74
Real dotFaces(const FaceMesh< Real > &m, const DV< Real > &a, const DV< Real > &b)
Definition operators.hpp:251
int poissonCG(const FaceMesh< Real > &m, const DV< Real > &f, const DV< Real > &p, Real tol, int maxIter, Real &resOut)
Definition operators.hpp:429
Definition mesh.hpp:33
Kokkos::View< int *, Mem > cellFace
Definition mesh.hpp:49
Kokkos::View< Real *, Mem > faceHb
Definition mesh.hpp:45
int nInterior
Definition mesh.hpp:35
Kokkos::View< int *, Mem > faceCellB
Definition mesh.hpp:40
KOKKOS_INLINE_FUNCTION Real conn(int f, int c) const
Definition mesh.hpp:57
Kokkos::View< Real *, Mem > faceDist
Definition mesh.hpp:44
KOKKOS_INLINE_FUNCTION Real normal(int f, int c) const
Definition mesh.hpp:55
Kokkos::View< int *, Mem > faceCellA
Definition mesh.hpp:40
int nCells
Definition mesh.hpp:35
KOKKOS_INLINE_FUNCTION Real centroid(int f, int c) const
Definition mesh.hpp:56
KOKKOS_INLINE_FUNCTION int cellFacesBegin(int i) const
Definition mesh.hpp:53
Kokkos::View< Real *, Mem > cellFaceSign
Definition mesh.hpp:50
KOKKOS_INLINE_FUNCTION int cellFacesEnd(int i) const
Definition mesh.hpp:54
Kokkos::View< Real *, Mem > cellVolume
Definition mesh.hpp:51
int nFaces
Definition mesh.hpp:35
Kokkos::View< Real *, Mem > faceArea
Definition mesh.hpp:42
Kokkos::View< Real *, Mem > faceHa
Definition mesh.hpp:45