Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
AMReX_algoim_K.H
Go to the documentation of this file.
1/*
2 * This file contains a modified version of Algoim developed by
3 * R. Saye, SIAM J. Sci. Comput., Vol. 37, No. 2, pp. A993-A1019,
4 * http://dx.doi.org/10.1137/140966290, https://algoim.github.io/.
5 *
6 * Algoim Copyright (c) 2018, The Regents of the University of
7 * California, through Lawrence Berkeley National Laboratory (subject
8 * to receipt of any required approvals from the U.S. Dept. of
9 * Energy). All rights reserved.
10 */
11
12#ifndef AMREX_ALGOIM_K_H_
13#define AMREX_ALGOIM_K_H_
14#include <AMReX_Config.H>
15
16#include <AMReX_algoim.H>
17#include <AMReX_Array.H>
18#include <limits>
19#include <cfloat>
20
21namespace amrex::algoim {
22
23struct EBPlane
24{
27
28 EBPlane () = default;
29
31 constexpr
32 EBPlane (GpuArray<Real,3> const& c, GpuArray<Real,3> const n) noexcept
33 : cent(c), norm(n)
34 {}
35
37 constexpr
38 EBPlane (Real cx, Real cy, Real cz, Real nx, Real ny, Real nz) noexcept
39 : cent{cx,cy,cz}, norm{nx,ny,nz}
40 {}
41
43 Real operator() (Real x, Real y, Real z) const noexcept
44 {
45 return (x-cent[0])*norm[0] + (y-cent[1])*norm[1] + (z-cent[2])*norm[2];
46 }
47
49 Real operator() (GpuArray<Real,3> const& p) const noexcept
50 {
51 return (p[0]-cent[0])*norm[0] + (p[1]-cent[1])*norm[1]
52 + (p[2]-cent[2])*norm[2];
53 }
54
56 Real grad (int d) const noexcept
57 {
58 return norm[d];
59 }
60};
61
63{
64 struct Node
65 {
66 Real x, y, z, w;
67 };
68 int nnodes = 0;
70
71 template<typename F>
73 Real
74 operator() (const F& f) const noexcept
75 {
76 Real r = 0;
77 for (int i = 0; i < nnodes; ++i) {
78 r += f(nodes[i].x,nodes[i].y,nodes[i].z) * nodes[i].w;
79 }
80 return r;
81 }
82
83 template<typename F>
85 Real
86 eval (const F& f) const noexcept
87 {
88 Real r = 0;
89 for (int i = 0; i < nnodes; ++i) {
90 r += f(nodes[i].x,nodes[i].y,nodes[i].z) * nodes[i].w;
91 }
92 return r;
93 }
94
95 // evalIntegrand records quadrature nodes when it is invoked by
96 // ImplicitIntegral
98 void
99 evalIntegrand (const GpuArray<Real,3>& x_, Real w_) noexcept
100 {
101 nodes[nnodes].x = x_[0];
102 nodes[nnodes].y = x_[1];
103 nodes[nnodes].z = x_[2];
104 nodes[nnodes].w = w_;
105 ++nnodes;
106 }
107};
108
109namespace detail
110{
111 template <class T>
113 void swap (T& a, T& b) noexcept {
114 T c(a); a=b; b=c;
115 }
116
117 // Determines the sign conditions for restricting a (possibly
118 // already restricted) level set function, i.e., sgn_L and sgn_U
119 // in [R. Saye, High-Order Quadrature Methods for Implicitly
120 // Defined Surfaces and Volumes in Hyperrectangles, SIAM
121 // J. Sci. Comput., Vol. 37, No. 2, pp. A993-A1019,
122 // http://dx.doi.org/10.1137/140966290].
123 template<bool S>
125 void
126 determineSigns (bool positiveAbove, int sign, int& bottomSign, int& topSign) noexcept
127 {
128 // When evaluating a volume integral:
129 // If 0 integrating over the positive part:
130 // if positive above the height function: bottom = +/-, top = +
131 // if positive below the height function: bottom = +, top = +/-
132 // If integrating over the negative part:
133 // if positive above the height function: bottom = -, top = +/-
134 // if positive below the height function: bottom = +/-, top = -
135 // If integrating over both the positive and negative part (i.e. unrestricted in sign), keep it alive
136 if (S)
137 {
138 // When evaluating a surface integral,
139 // if the function is positive above the height function, then
140 // the bottom side must be negative and the top side must be positive;
141 // if the function is positive below the height function,
142 // then the bottom side must be positive and the top side must be negative.
143 bottomSign = positiveAbove? -1 : 1;
144 topSign = positiveAbove? 1 : -1;
145 } else {
146 if (sign == 1)
147 {
148 bottomSign = positiveAbove? 0 : 1;
149 topSign = positiveAbove? 1 : 0;
150 }
151 else if (sign == -1)
152 {
153 bottomSign = positiveAbove? -1 : 0;
154 topSign = positiveAbove? 0 : -1;
155 }
156 else {
157 bottomSign = topSign = 0;
158 }
159 }
160 }
161} // namespace detail
162
163// PsiCode encodes sign information of restricted level set functions
164// on particular sides of a hyperrectangle in a packed array of
165// bits. The first N bits encodes side information, the N+1st bit is
166// true iff the sign == 0, while the N+2nd bit stores the sign if sign
167// != 0.
168template<int N>
170{
171 unsigned char bits = 0;
172
174 PsiCode () noexcept = default;
175
177 PsiCode (const GpuArray<int,N>& sides, int sign) noexcept
178 {
179 static_assert(N <= 3, "algoim::PsiCode: N must be <= 3");
180 for (int dim = 0; dim < N; ++dim) {
181 if (sides[dim] == 1) {
182 bits |= (1 << dim);
183 }
184 }
185 if (sign == 0) {
186 bits |= (1 << N);
187 } else {
188 bits &= ~(1 << N);
189 if (sign == 1) {
190 bits |= (1 << (N+1));
191 }
192 }
193 }
194
195 // Modify an existing code by restriction in a particular dimension.
197 PsiCode (const PsiCode& i, int dim, int side, int sign) noexcept
198 : bits(i.bits)
199 {
200 if (side == 1) {
201 bits |= (1 << dim);
202 }
203 if (sign == 0) {
204 bits |= (1 << N);
205 } else {
206 bits &= ~(1 << N);
207 if (sign == 1) {
208 bits |= (1 << (N+1));
209 }
210 }
211 }
212
214 int side (int dim) const noexcept
215 {
216 return bits & (1 << dim);
217 }
218
220 int sign () const noexcept
221 {
222 return (bits & (1 << N)) ? 0 : ((bits & (1 << (N+1))) ? 1 : -1);
223 }
224};
225
226template <int N>
228{
229 static constexpr Real min (int /*dim*/) noexcept { return -0.5_rt; }
230
231 static constexpr Real max (int /*dim*/) noexcept { return 0.5_rt; }
232
233 static constexpr Real extent (int /*dim*/) noexcept { return 1.0_rt; }
234
235 static constexpr GpuArray<Real,N> midpoint () noexcept {
236 return GpuArray<Real,N>{};
237 }
238
239 static constexpr Real midpoint (int /*dim*/) noexcept { return 0.0_rt; }
240
241 constexpr Real operator() (int side, int /*dim*/) const noexcept {
242 return (side == 0) ? -0.5_rt : 0.5_rt;
243 }
244};
245
247{
248 Real alpha = std::numeric_limits<Real>::lowest();
249};
250
251// M-dimensional integral of an N-dimensional function restricted to
252// given implicitly defined domains
253template<int M, int N, typename Phi, typename F, bool S>
255{
256 const Phi* phi;
257 F* f;
262 int e0 = -1;
264 static constexpr int p = 4;
265
266 // Prune the given set of functions by checking for the existence
267 // of the interface. If a function is uniformly positive or
268 // negative and is consistent with specified sign, it can be
269 // removed. If a function is uniformly positive or negative but
270 // inconsistent with specified sign, the domain of integration is
271 // empty.
273 bool prune () noexcept
274 {
275 static constexpr Real eps = std::numeric_limits<Real>::epsilon();
276 static constexpr Real almostone = 1.0-10.*eps;
277
278 for (int i = 0; i < psiCount; )
279 {
280 GpuArray<Real,N> mid = xrange.midpoint();
281 Real dphi_max = 0.0_rt;
282 for (int dim = 0; dim < N; ++dim) {
283 if (free[dim]) {
284 dphi_max += std::abs(phi->grad(dim));
285 } else {
286 mid[dim] = xrange(psi[i].side(dim),dim);
287 }
288 }
289 dphi_max *= 0.5*almostone;
290 const Real phi_0 = (*phi)(mid);
291 bool uniform_sign = (phi_0 > dphi_max) || (phi_0 < -dphi_max);
292 if (uniform_sign)
293 {
294 if ((phi_0 >= 0.0 && psi[i].sign() >= 0) ||
295 (phi_0 <= 0.0 && psi[i].sign() <= 0) )
296 {
297 --psiCount;
299 }
300 else {
301 return false;
302 }
303 }
304 else {
305 ++i;
306 }
307 }
308 return true;
309 }
310
311 // Gaussian quadrature for when the domain of integration is
312 // determined to be the entire M-dimensional cube.
314 void tensorProductIntegral () noexcept
315 {
316 constexpr Real gauss_x[4]={0.069431844202973712388026755553595247452_rt,
317 0.33000947820757186759866712044837765640_rt,
318 0.66999052179242813240133287955162234360_rt,
319 0.93056815579702628761197324444640475255_rt};
320 constexpr Real gauss_w[4]={0.173927422568726928686531974610999703618_rt,
321 0.326072577431273071313468025389000296382_rt,
322 0.326072577431273071313468025389000296382_rt,
323 0.173927422568726928686531974610999703618_rt};
324
325 int nloops = 1;
326 for (int i = 0; i < M; ++i) {
327 nloops *= p;
328 }
329 GpuArray<int,M> i{}; // i is initialized to zero.
330 for (int iloop = 0; iloop < nloops; ++iloop)
331 {
333 Real w = 1.0_rt;
334 for (int dim = 0, k = 0; dim < N; ++dim) {
335 if (free[dim]) {
336 x[dim] = xrange.min(dim) + xrange.extent(dim) * gauss_x[i[k]];
337 w *= xrange.extent(dim) * gauss_w[i[k]];
338 ++k;
339 }
340 }
341 f->evalIntegrand(x, w);
342
343 for (int m = M-1; m >= 0; --m) {
344 ++(i[m]);
345 if (i[m] < p) {
346 break;
347 } else {
348 i[m] = 0;
349 }
350 }
351 }
352 }
353
354 // Given x, valid in all free variables barring e0, root find in
355 // the e0 direction on each of the implicit functions, and apply
356 // Gaussian quadrature to each segment. Weights are multiplied
357 // upon going back up the tree of recursive calls.
359 void evalIntegrand (GpuArray<Real,N> x, Real w) const noexcept
360 {
361 constexpr Real gauss_x[4]={0.069431844202973712388026755553595247452_rt,
362 0.33000947820757186759866712044837765640_rt,
363 0.66999052179242813240133287955162234360_rt,
364 0.93056815579702628761197324444640475255_rt};
365 constexpr Real gauss_w[4]={0.173927422568726928686531974610999703618_rt,
366 0.326072577431273071313468025389000296382_rt,
367 0.326072577431273071313468025389000296382_rt,
368 0.173927422568726928686531974610999703618_rt};
369
370 // Each thread has its own storage for computing roots. These
371 // are not corrupted by the recursive chain of evalIntegrand()
372 // calls since each call is in a different templated
373 // namespace. Moreover, if using OpenMP tasking, each task is
374 // assumed tied and so one thread can only execute
375 // "evalIntegrand" from start to end uninterrupted.
376 GpuArray<Real,4> roots;
377
378 // Surface integral
379 if (S)
380 {
381 AMREX_ASSERT(M == N && N >= 2); // x is thus valid in all variables except e0
382
383 Real x_min = xrange.min(e0);
384 Real x_max = xrange.max(e0);
385 int nroots = 0;
386
387 x[e0] = x_min;
388 Real phi_lo = (*phi)(x);
389 Real xroot = x[e0] - phi_lo / phi->grad(e0);
390 if (xroot > x_min && xroot < x_max) {
391 roots[nroots++] = xroot;
392 }
393
394 AMREX_ASSERT(nroots <= 1);
395
396 for (int i = 0; i < nroots; ++i)
397 {
398 x[e0] = roots[i];
399 Real mag = 0._rt;
400 for (int dim = 0; dim < N; ++dim) {
401 mag += phi->grad(dim)*phi->grad(dim);
402 }
403 mag = std::sqrt(mag);
404 f->evalIntegrand(x, (mag/std::abs(phi->grad(e0)))*w);
405 }
406
407 return;
408 }
409
410 // Partition [xmin(e0), xmax(e0)] by roots found
411 Real x_min = xrange.min(e0);
412 Real x_max = xrange.max(e0);
413 roots[0] = x_min;
414 int nroots = 1;
415 if (phi->grad(e0) != Real(0.0)) {
416 for (int i = 0; i < psiCount; ++i)
417 {
418 for (int dim = 0; dim < N; ++dim) {
419 if (!free[dim]) {
420 x[dim] = xrange(psi[i].side(dim),dim);
421 }
422 }
423 // x is now valid in all variables except e0
424 x[e0] = x_min;
425 Real phi_lo = (*phi)(x);
426 Real xroot = x[e0] - phi_lo / phi->grad(e0);
427 if (xroot > x_min && xroot < x_max) {
428 roots[nroots++] = xroot;
429 }
430 }
431 AMREX_ASSERT(nroots <= 3);
432 }
433 if (nroots == 3 && roots[1] > roots[2]) {
434 detail::swap(roots[1],roots[2]);
435 }
436 roots[nroots++] = x_max;
437
438 // In rare cases, degenerate segments can be found, filter out with a tolerance
439 static constexpr Real eps = std::numeric_limits<Real>::epsilon();
440 constexpr Real tol = 50.0*eps;
441
442 // Loop over segments of divided interval
443 for (int i = 0; i < nroots - 1; ++i)
444 {
445 if (roots[i+1] - roots[i] < tol) { continue; }
446
447 // Evaluate sign of phi within segment and check for consistency with psi
448 bool okay = true;
449 x[e0] = (roots[i] + roots[i+1])*0.5;
450 for (int j = 0; j < psiCount && okay; ++j)
451 {
452 for (int dim = 0; dim < N; ++dim) {
453 if (!free[dim]) {
454 x[dim] = xrange(psi[j].side(dim), dim);
455 }
456 }
457 bool new_ok = ((*phi)(x) > 0.0) ? (psi[j].sign() >= 0) : (psi[j].sign() <= 0);
458 okay = okay && new_ok;
459 }
460 if (!okay) { continue; }
461
462 for (int j = 0; j < p; ++j)
463 {
464 x[e0] = roots[i] + (roots[i+1] - roots[i]) * gauss_x[j];
465 Real gw = (roots[i+1] - roots[i]) * gauss_w[j];
466 f->evalIntegrand(x, w * gw);
467 }
468 }
469 }
470
471 // Main calling engine; parameters with underscores are copied
472 // upon entry but modified internally in the ctor
473 template <int K = M, std::enable_if_t<K==1,int> = 0>
475 ImplicitIntegral (const Phi& phi_, F& f_, const GpuArray<bool,N>& free_,
476 const GpuArray<PsiCode<N>,1 << (N-1)>& psi_,
477 int psiCount_) noexcept
478 : phi(&phi_), f(&f_), free(free_), psi(psi_), psiCount(psiCount_),
479 xrange()
480 {
481 // For the one-dimensional base case, evaluate the
482 // bottom-level integral.
483 for (int dim = 0; dim < N; ++dim) {
484 if (free[dim]) {
485 e0 = dim;
486 }
487 }
489 }
490
491 // Main calling engine; parameters with underscores are copied
492 // upon entry but modified internally in the ctor
493 template <int K = M, std::enable_if_t<(K>1),int> = 0>
495 ImplicitIntegral (const Phi& phi_, F& f_, const GpuArray<bool,N>& free_,
496 const GpuArray<PsiCode<N>,1 << (N-1)>& psi_,
497 int psiCount_) noexcept
498 : phi(&phi_), f(&f_), free(free_), psi(psi_), psiCount(psiCount_),
499 xrange()
500 {
501 // Establish interval bounds for prune() and remaining part of ctor.
502 for (int dim = 0; dim < N; ++dim)
503 {
504 if (free[dim])
505 {
506 xint[dim].alpha = xrange.midpoint(dim);
507 }
508 else
509 {
510 xint[dim].alpha = 0.0_rt;
511 }
512 }
513
514 // Prune list of psi functions: if prune procedure returns
515 // false, then the domain of integration is empty.
516 if (!prune()) {
517 return;
518 }
519
520 // If all psi functions were pruned, then the volumetric
521 // integral domain is the entire hyperrectangle.
522 if (psiCount == 0)
523 {
524 if (!S) {
526 }
527 return;
528 }
529
530 // Among all monotone height function directions, choose the
531 // one that makes the associated height function look as flat
532 // as possible. This is a modification to the criterion
533 // presented in [R. Saye, High-Order Quadrature Methods for
534 // Implicitly Defined Surfaces and Volumes in Hyperrectangles,
535 // SIAM J. Sci. Comput., Vol. 37, No. 2, pp. A993-A1019,
536 // http://dx.doi.org/10.1137/140966290].
537 e0 = -1;
538 {
539 Real gmax = -1.;
540 for (int dim = 0; dim < N; ++dim) {
541 if (free[dim] && std::abs(phi->grad(dim)) > gmax) {
542 gmax = std::abs(phi->grad(dim));
543 e0 = dim;
544 }
545 }
546 }
547
548 // Check compatibility with all implicit functions whilst
549 // simultaneously constructing new implicit functions.
550 GpuArray<PsiCode<N>,1 << (N-1)> newPsi;
551 int newPsiCount = 0;
552 for (int i = 0; i < psiCount; ++i)
553 {
554 // Evaluate gradient in an interval
555 for (int dim = 0; dim < N; ++dim) {
556 if (!free[dim]) {
557 xint[dim].alpha = xrange(psi[i].side(dim), dim);
558 }
559 }
560
561 // w.z. We assume grad does not change.
562 int bottomSign, topSign;
563 detail::determineSigns<S>(phi->grad(e0) > 0.0, psi[i].sign(),
564 bottomSign, topSign);
565 // w.z. There are sides 0 and 1.
566 newPsi[newPsiCount++] = PsiCode<N>(psi[i], e0, 0, bottomSign);
567 newPsi[newPsiCount++] = PsiCode<N>(psi[i], e0, 1, topSign);
568 }
569
570 // Dimension reduction call
571 GpuArray<bool,N> new_free = free;
572 new_free[e0] = false;
574 (*phi, *this, new_free, newPsi, newPsiCount);
575 }
576};
577
578// Partial specialisation on M=0 as a dummy base case for the compiler
579template<int N, typename Phi, typename F, bool S>
580struct ImplicitIntegral<0,N,Phi,F,S>
581{
583 ImplicitIntegral (const Phi&, F&, const GpuArray<bool,N>&,
584 const GpuArray<PsiCode<N>,1 << (N-1)>&,
585 int) noexcept {}
586};
587
589QuadratureRule
590quadGen (EBPlane const& phi) noexcept
591{
593 GpuArray<bool,3> free{true,true,true};
594 GpuArray<PsiCode<3>,4> psi;
595 psi[0] = PsiCode<3>({0,0,0}, -1);
597 return q;
598}
599
601QuadratureRule
602quadGenSurf (EBPlane const& phi) noexcept
603{
605 GpuArray<bool,3> free{true,true,true};
606 GpuArray<PsiCode<3>,4> psi;
607 psi[0] = PsiCode<3>({0,0,0}, -1);
609 return q;
610}
611
613void set_regular (int i, int j, int k, Array4<Real> const& intg) noexcept
614{
615 constexpr Real twelfth = 1._rt/12._rt;
616 constexpr Real offth = 1._rt/144._rt;
617 intg(i,j,k,i_S_x ) = 0.0_rt;
618 intg(i,j,k,i_S_y ) = 0.0_rt;
619 intg(i,j,k,i_S_z ) = 0.0_rt;
620 intg(i,j,k,i_S_x2 ) = twelfth;
621 intg(i,j,k,i_S_y2 ) = twelfth;
622 intg(i,j,k,i_S_z2 ) = twelfth;
623 intg(i,j,k,i_S_x_y ) = 0.0_rt;
624 intg(i,j,k,i_S_x_z ) = 0.0_rt;
625 intg(i,j,k,i_S_y_z ) = 0.0_rt;
626 intg(i,j,k,i_S_x2_y ) = 0.0_rt;
627 intg(i,j,k,i_S_x2_z ) = 0.0_rt;
628 intg(i,j,k,i_S_x_y2 ) = 0.0_rt;
629 intg(i,j,k,i_S_y2_z ) = 0.0_rt;
630 intg(i,j,k,i_S_x_z2 ) = 0.0_rt;
631 intg(i,j,k,i_S_y_z2 ) = 0.0_rt;
632 intg(i,j,k,i_S_x2_y2) = offth;
633 intg(i,j,k,i_S_x2_z2) = offth;
634 intg(i,j,k,i_S_y2_z2) = offth;
635 intg(i,j,k,i_S_xyz ) = 0.0_rt;
636}
637
639void set_regular_surface (int i, int j, int k, Array4<Real> const& sintg) noexcept
640{
641 sintg(i,j,k,i_B_x ) = 0.0_rt;
642 sintg(i,j,k,i_B_y ) = 0.0_rt;
643 sintg(i,j,k,i_B_z ) = 0.0_rt;
644 sintg(i,j,k,i_B_x_y ) = 0.0_rt;
645 sintg(i,j,k,i_B_x_z ) = 0.0_rt;
646 sintg(i,j,k,i_B_y_z ) = 0.0_rt;
647 sintg(i,j,k,i_B_xyz ) = 0.0_rt;
648}
649
650}
651
652#endif
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
#define AMREX_GPU_HOST
Definition AMReX_GpuQualifiers.H:17
void free(void *)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void swap(T &a, T &b) noexcept
Definition AMReX_algoim_K.H:113
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void determineSigns(bool positiveAbove, int sign, int &bottomSign, int &topSign) noexcept
Definition AMReX_algoim_K.H:126
Definition AMReX_algoim.cpp:6
static constexpr int i_B_xyz
Definition AMReX_algoim.H:42
static constexpr int i_S_y_z2
Definition AMReX_algoim.H:26
static constexpr int i_S_y_z
Definition AMReX_algoim.H:20
AMREX_GPU_HOST_DEVICE QuadratureRule quadGen(EBPlane const &phi) noexcept
Definition AMReX_algoim_K.H:590
static constexpr int i_S_x2
Definition AMReX_algoim.H:15
static constexpr int i_S_x_y
Definition AMReX_algoim.H:18
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void set_regular_surface(int i, int j, int k, Array4< Real > const &sintg) noexcept
Definition AMReX_algoim_K.H:639
static constexpr int i_S_y
Definition AMReX_algoim.H:13
static constexpr int i_S_x_z
Definition AMReX_algoim.H:19
static constexpr int i_B_z
Definition AMReX_algoim.H:38
static constexpr int i_S_x_y2
Definition AMReX_algoim.H:23
static constexpr int i_S_xyz
Definition AMReX_algoim.H:30
static constexpr int i_S_y2_z2
Definition AMReX_algoim.H:29
static constexpr int i_B_x_y
Definition AMReX_algoim.H:39
static constexpr int i_B_x_z
Definition AMReX_algoim.H:40
static constexpr int i_S_x2_y2
Definition AMReX_algoim.H:27
static constexpr int i_S_x2_z2
Definition AMReX_algoim.H:28
static constexpr int i_S_x
Definition AMReX_algoim.H:12
static constexpr int i_S_y2_z
Definition AMReX_algoim.H:24
static constexpr int i_S_x2_y
Definition AMReX_algoim.H:21
static constexpr int i_B_y_z
Definition AMReX_algoim.H:41
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void set_regular(int i, int j, int k, Array4< Real > const &intg) noexcept
Definition AMReX_algoim_K.H:613
static constexpr int i_B_x
Definition AMReX_algoim.H:36
static constexpr int i_S_z
Definition AMReX_algoim.H:14
static constexpr int i_S_z2
Definition AMReX_algoim.H:17
static constexpr int i_S_x_z2
Definition AMReX_algoim.H:25
static constexpr int i_S_x2_z
Definition AMReX_algoim.H:22
AMREX_GPU_HOST_DEVICE QuadratureRule quadGenSurf(EBPlane const &phi) noexcept
Definition AMReX_algoim_K.H:602
static constexpr int i_B_y
Definition AMReX_algoim.H:37
static constexpr int i_S_y2
Definition AMReX_algoim.H:16
Definition AMReX_FabArrayCommI.H:896
Definition AMReX_Array4.H:61
Definition AMReX_Array.H:34
Definition AMReX_algoim_K.H:228
static constexpr Real min(int) noexcept
Definition AMReX_algoim_K.H:229
static constexpr GpuArray< Real, N > midpoint() noexcept
Definition AMReX_algoim_K.H:235
static constexpr Real max(int) noexcept
Definition AMReX_algoim_K.H:231
constexpr Real operator()(int side, int) const noexcept
Definition AMReX_algoim_K.H:241
static constexpr Real midpoint(int) noexcept
Definition AMReX_algoim_K.H:239
static constexpr Real extent(int) noexcept
Definition AMReX_algoim_K.H:233
Definition AMReX_algoim_K.H:24
GpuArray< Real, 3 > cent
Definition AMReX_algoim_K.H:25
AMREX_GPU_HOST_DEVICE constexpr EBPlane(GpuArray< Real, 3 > const &c, GpuArray< Real, 3 > const n) noexcept
Definition AMReX_algoim_K.H:32
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Real grad(int d) const noexcept
Definition AMReX_algoim_K.H:56
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Real operator()(Real x, Real y, Real z) const noexcept
Definition AMReX_algoim_K.H:43
AMREX_GPU_HOST_DEVICE constexpr EBPlane(Real cx, Real cy, Real cz, Real nx, Real ny, Real nz) noexcept
Definition AMReX_algoim_K.H:38
GpuArray< Real, 3 > norm
Definition AMReX_algoim_K.H:26
AMREX_GPU_HOST_DEVICE ImplicitIntegral(const Phi &, F &, const GpuArray< bool, N > &, const GpuArray< PsiCode< N >, 1<<(N-1)> &, int) noexcept
Definition AMReX_algoim_K.H:583
Definition AMReX_algoim_K.H:255
static constexpr int p
Definition AMReX_algoim_K.H:264
BoundingBox< N > xrange
Definition AMReX_algoim_K.H:261
F * f
Definition AMReX_algoim_K.H:257
const Phi * phi
Definition AMReX_algoim_K.H:256
AMREX_GPU_HOST_DEVICE ImplicitIntegral(const Phi &phi_, F &f_, const GpuArray< bool, N > &free_, const GpuArray< PsiCode< N >, 1<<(N-1)> &psi_, int psiCount_) noexcept
Definition AMReX_algoim_K.H:475
int e0
Definition AMReX_algoim_K.H:262
AMREX_GPU_HOST_DEVICE void evalIntegrand(GpuArray< Real, N > x, Real w) const noexcept
Definition AMReX_algoim_K.H:359
int psiCount
Definition AMReX_algoim_K.H:260
GpuArray< bool, N > free
Definition AMReX_algoim_K.H:258
GpuArray< Interval, N > xint
Definition AMReX_algoim_K.H:263
AMREX_GPU_HOST_DEVICE bool prune() noexcept
Definition AMReX_algoim_K.H:273
AMREX_GPU_HOST_DEVICE void tensorProductIntegral() noexcept
Definition AMReX_algoim_K.H:314
GpuArray< PsiCode< N >, 1<<(N - 1)> psi
Definition AMReX_algoim_K.H:259
Definition AMReX_algoim_K.H:247
Real alpha
Definition AMReX_algoim_K.H:248
Definition AMReX_algoim_K.H:170
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int side(int dim) const noexcept
Definition AMReX_algoim_K.H:214
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int sign() const noexcept
Definition AMReX_algoim_K.H:220
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE PsiCode(const PsiCode &i, int dim, int side, int sign) noexcept
Definition AMReX_algoim_K.H:197
unsigned char bits
Definition AMReX_algoim_K.H:171
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr PsiCode() noexcept=default
Definition AMReX_algoim_K.H:65
Real w
Definition AMReX_algoim_K.H:66
Real z
Definition AMReX_algoim_K.H:66
Real y
Definition AMReX_algoim_K.H:66
Real x
Definition AMReX_algoim_K.H:66
Definition AMReX_algoim_K.H:63
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void evalIntegrand(const GpuArray< Real, 3 > &x_, Real w_) noexcept
Definition AMReX_algoim_K.H:99
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Real operator()(const F &f) const noexcept
Definition AMReX_algoim_K.H:74
AMREX_GPU_HOST AMREX_FORCE_INLINE Real eval(const F &f) const noexcept
Definition AMReX_algoim_K.H:86
int nnodes
Definition AMReX_algoim_K.H:68
GpuArray< Node, 256 > nodes
Definition AMReX_algoim_K.H:69