1 #ifndef ERF_NODAL_RECONSTRUCTION_H_
2 #define ERF_NODAL_RECONSTRUCTION_H_
11 #include "AMReX_Array4.H"
12 #include "AMReX_BLassert.H"
13 #include "AMReX_Box.H"
14 #include "AMReX_FArrayBox.H"
15 #include "AMReX_GpuDevice.H"
16 #include "AMReX_Geometry.H"
17 #include "AMReX_MultiFab.H"
18 #include "AMReX_ParallelDescriptor.H"
19 #include "AMReX_Print.H"
20 #include "AMReX_REAL.H"
146 amrex::Geometry
const& geom)
148 m_ilo(cc_slice_box.smallEnd(0)),
149 m_ihi(cc_slice_box.bigEnd(0)),
150 m_jlo(cc_slice_box.smallEnd(1)),
151 m_jhi(cc_slice_box.bigEnd(1))
155 if (!cc_slice_box.ok()) {
156 amrex::Abort(
"NodalReconstruction: cc_slice_box is empty; the input "
157 "heights were probably never read.");
159 if (cc_slice_box.length(2) != 1) {
160 amrex::Abort(
"NodalReconstruction: cc_slice_box must contain exactly one z cell.");
162 if (cc_slice_box.smallEnd(2) != 0) {
163 amrex::Abort(
"NodalReconstruction: cc_slice_box must be a slab at k = 0; "
164 "all fabs are indexed at k = 0.");
167 m_nodal_box = amrex::surroundingNodes(cc_slice_box);
179 Real const dx = geom.CellSizeArray()[0];
180 Real const dy = geom.CellSizeArray()[1];
182 amrex::Abort(
"NodalReconstruction: cell sizes must be positive.");
195 [[nodiscard]] amrex::Box
const&
nodalBox () const noexcept {
210 amrex::FArrayBox
R(
m_nodal_box,1,amrex::The_Managed_Arena());
211 auto const T_arr =
T.const_array();
212 auto const R_arr =
R.array();
215 int const jm = std::max(
m_jlo, std::min(j-1,
m_jhi));
216 int const jp = std::max(
m_jlo, std::min(j ,
m_jhi));
218 int const im = std::max(
m_ilo, std::min(i-1,
m_ihi));
219 int const ip = std::max(
m_ilo, std::min(i ,
m_ihi));
220 R_arr(i,j,0) =
fourth * ( T_arr(im,jm,0) + T_arr(ip,jm,0)
221 + T_arr(im,jp,0) + T_arr(ip,jp,0) );
239 [[nodiscard]] std::pair<amrex::FArrayBox,SolveInfo>
241 amrex::FArrayBox
const& reference,
243 Real relative_tolerance =
Real(1.e-10),
245 Real min_regularization =
Real(2.5e-4),
246 int max_iterations = 1000)
248 if (!(smoothing >
zero)) {
249 amrex::Abort(
"NodalReconstruction: smoothing weight must be positive.");
251 if (!(min_regularization >
zero)) {
255 amrex::Abort(
"NodalReconstruction: regularization must be positive.");
275 amrex::FArrayBox misfit(
m_cc_slice_box,1,amrex::The_Managed_Arena());
277 Real t_min = std::numeric_limits<Real>::max();
278 Real t_max = -std::numeric_limits<Real>::max();
281 auto const T_arr =
T.const_array();
282 auto const m_arr = misfit.array();
285 m_arr(i,j,0) = T_arr(i,j,0) - m_arr(i,j,0);
286 misfit_max = std::max(misfit_max, std::abs(m_arr(i,j,0)));
287 t_min = std::min(t_min, T_arr(i,j,0));
288 t_max = std::max(t_max, T_arr(i,j,0));
300 amrex::FArrayBox rhs(
m_nodal_box,1,amrex::The_Managed_Arena());
306 amrex::FArrayBox E(
m_nodal_box,1,amrex::The_Managed_Arena());
310 amrex::FArrayBox S(
m_nodal_box,1,amrex::The_Managed_Arena());
312 m_mu = min_regularization;
313 bool accepted =
false;
328 auto const S_arr = S.array();
329 auto const r_arr = reference.const_array();
330 auto const E_arr = E.const_array();
333 S_arr(i,j,0) = r_arr(i,j,0) + E_arr(i,j,0);
339 S.copy<amrex::RunOn::Host>(reference,0,0,1);
345 return {std::move(S),info};
350 amrex::FArrayBox
const& S)
const
352 auto const T_arr =
T.const_array();
353 auto const S_arr = S.const_array();
357 Real const avg =
fourth * ( S_arr(i ,j ,0) + S_arr(i+1,j ,0)
358 + S_arr(i ,j+1,0) + S_arr(i+1,j+1,0) );
359 err = std::max(err, std::abs(avg - T_arr(i,j,0)));
367 auto const S_arr = S.const_array();
372 Real const d = S_arr(i+1,j,0) - S_arr(i,j,0);
378 Real const d = S_arr(i,j+1,0) - S_arr(i,j,0);
428 amrex::FArrayBox&
T)
const
430 auto const S_arr = S.const_array();
431 auto const T_arr =
T.array();
434 T_arr(i,j,0) =
fourth * ( S_arr(i ,j ,0) + S_arr(i+1,j ,0)
435 + S_arr(i ,j+1,0) + S_arr(i+1,j+1,0) );
447 amrex::FArrayBox&
R)
const
449 R.setVal<amrex::RunOn::Host>(
zero);
450 auto const T_arr =
T.const_array();
451 auto const R_arr =
R.array();
456 R_arr(i+1,j ,0) +=
q;
457 R_arr(i ,j+1,0) +=
q;
458 R_arr(i+1,j+1,0) +=
q;
470 amrex::FArrayBox& difx,
471 amrex::FArrayBox& dify)
const
473 difx.setVal<amrex::RunOn::Host>(
zero);
474 dify.setVal<amrex::RunOn::Host>(
zero);
476 auto const S_arr = S.const_array();
477 auto const difx_arr = difx.array();
478 auto const dify_arr = dify.array();
482 difx_arr(i, j, 0) =
m_gx * ( S_arr(i+1, j, 0) - S_arr(i, j, 0) );
488 dify_arr(i, j, 0) =
m_gy * ( S_arr(i, j+1, 0) - S_arr(i, j, 0) );
500 amrex::FArrayBox
const& dify,
501 amrex::FArrayBox&
R)
const
503 R.setVal<amrex::RunOn::Host>(
zero);
505 auto const qx_arr = difx.const_array();
506 auto const qy_arr = dify.const_array();
507 auto const R_arr =
R.array();
511 R_arr(i , j, 0) -=
m_gx * qx_arr(i, j, 0);
512 R_arr(i+1, j, 0) +=
m_gx * qx_arr(i, j, 0);
518 R_arr(i, j , 0) -=
m_gy * qy_arr(i, j, 0);
519 R_arr(i, j+1, 0) +=
m_gy * qy_arr(i, j, 0);
530 amrex::FArrayBox&
R)
const
544 amrex::FArrayBox& lap)
const
546 lap.setVal<amrex::RunOn::Host>(
zero);
548 auto const S_arr = S.const_array();
549 auto const lap_arr = lap.array();
553 lap_arr(i, j, 0) =
m_gxx * ( S_arr(i+1, j , 0)
554 -
two * S_arr(i , j , 0)
555 + S_arr(i-1, j , 0) )
556 +
m_gyy * ( S_arr(i , j+1, 0)
557 -
two * S_arr(i , j , 0)
558 + S_arr(i , j-1, 0) );
569 amrex::FArrayBox&
R)
const
571 R.setVal<amrex::RunOn::Host>(
zero);
573 auto const q_arr = lap.const_array();
574 auto const R_arr =
R.array();
579 R_arr(i-1, j , 0) +=
m_gxx * val;
580 R_arr(i+1, j , 0) +=
m_gxx * val;
581 R_arr(i , j-1, 0) +=
m_gyy * val;
582 R_arr(i , j+1, 0) +=
m_gyy * val;
594 amrex::FArrayBox&
R)
const
599 R.setVal<amrex::RunOn::Host>(
zero);
613 amrex::FArrayBox&
R)
const
625 amrex::Abort(
"NodalReconstruction: unsupported variation operator.");
636 amrex::FArrayBox&
R)
const
642 auto const R_arr =
R.array();
644 auto const S_arr = S.const_array();
647 R_arr(i,j,0) +=
m_lambda * v_arr(i,j,0) +
m_mu * S_arr(i,j,0);
658 diag.setVal<amrex::RunOn::Host>(
m_mu);
659 auto const d_arr = diag.array();
665 d_arr(i ,j ,0) +=
qa;
666 d_arr(i+1,j ,0) +=
qa;
667 d_arr(i ,j+1,0) +=
qa;
668 d_arr(i+1,j+1,0) +=
qa;
679 d_arr(i+1,j,0) += qx;
685 d_arr(i,j+1,0) += qy;
694 d_arr(i-1,j ,0) += qx;
695 d_arr(i+1,j ,0) += qx;
696 d_arr(i ,j-1,0) += qy;
697 d_arr(i ,j+1,0) += qy;
698 d_arr(i ,j ,0) +=
qc;
711 amrex::FArrayBox
const& S,
714 auto const S_arr = S.const_array();
715 Real smin = std::numeric_limits<Real>::max();
716 Real smax = -std::numeric_limits<Real>::max();
719 smin = std::min(smin, S_arr(i,j,0));
720 smax = std::max(smax, S_arr(i,j,0));
730 auto const F_arr = F.const_array();
734 v = std::max(v, std::abs(F_arr(i,j,0)));
745 Real relative_tolerance,
746 int max_iterations)
const
751 amrex::FArrayBox diag(
m_nodal_box,1,amrex::The_Managed_Arena());
757 amrex::FArrayBox r (
m_nodal_box,1,amrex::The_Managed_Arena());
761 amrex::FArrayBox
z (
m_nodal_box,1,amrex::The_Managed_Arena());
765 amrex::FArrayBox
p (
m_nodal_box,1,amrex::The_Managed_Arena());
769 amrex::FArrayBox Mp(
m_nodal_box,1,amrex::The_Managed_Arena());
771 x.setVal<amrex::RunOn::Host>(
zero);
772 r.copy<amrex::RunOn::Host>(rhs,0,0,1);
774 p.copy<amrex::RunOn::Host>(
z,0,0,1);
777 Real const initial = std::sqrt(
dot(r,r));
778 Real const tol = relative_tolerance * std::max({initial,
one});
782 if (initial <= tol) {
783 info.converged =
true;
787 for (
int it=0; it<max_iterations; ++it) {
790 if (!(pMp >
zero) || !std::isfinite(pMp)) {
791 amrex::Abort(
"NodalReconstruction: CG curvature failure.");
796 auto const x_arr =
x.array();
797 auto const r_arr = r.array();
798 auto const p_arr =
p.const_array();
799 auto const Mp_arr = Mp.const_array();
802 x_arr(i,j,0) +=
alpha * p_arr(i,j,0);
803 r_arr(i,j,0) -=
alpha * Mp_arr(i,j,0);
808 info.iterations = it+1;
809 info.final_residual = std::sqrt(
dot(r,r));
810 if (info.final_residual <= tol) {
811 info.converged =
true;
819 auto const p_arr =
p.array();
820 auto const z_arr =
z.const_array();
823 p_arr(i,j,0) = z_arr(i,j,0) +
beta * p_arr(i,j,0);
839 amrex::FArrayBox
const& r,
840 amrex::FArrayBox&
z)
const
842 auto const d_arr = diag.const_array();
843 auto const r_arr = r.const_array();
844 auto const z_arr =
z.array();
847 z_arr(i,j,0) = r_arr(i,j,0) / d_arr(i,j,0);
852 [[nodiscard]]
Real dot (amrex::FArrayBox
const& a,
853 amrex::FArrayBox
const& b)
const
855 auto const a_arr = a.const_array();
856 auto const b_arr = b.const_array();
860 v += a_arr(i,j,0) * b_arr(i,j,0);
893 inline amrex::FArrayBox
895 amrex::Geometry
const& geom,
896 amrex::FArrayBox
const& z_cc_slice,
898 std::string
const& src_name)
904 "reconstruct_nodal_height_slice: the input slice is empty "
905 "or spans more than one z level -- check that the source "
906 "heights were read successfully.");
910 amrex::Gpu::streamSynchronize();
912 amrex::Box nd_box = amrex::surroundingNodes(cc_slice_box);
913 nd_box.setSmall(2, 0);
917 amrex::FArrayBox z_nd_slice(nd_box, 1, amrex::The_Managed_Arena());
919 int const ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
924 int bad_reconstruction = 0;
926 if (amrex::ParallelDescriptor::IOProcessor())
937 amrex::FArrayBox z_ref = NR_solver.
makeReference(z_cc_slice);
938 std::pair<amrex::FArrayBox,SolveInfo> result = NR_solver.
solve(z_cc_slice, z_ref,
943 amrex::Print() <<
"WARNING: Nodal reconstruction did not converge at k = " << klev
945 <<
" and requested tolerance was: " << tol <<
"\n";
951 amrex::Real src_min = std::numeric_limits<amrex::Real>::max();
952 amrex::Real src_max = -std::numeric_limits<amrex::Real>::max();
954 auto const src_arr = z_cc_slice.const_array();
955 amrex::LoopOnCpu(cc_slice_box, [=,&src_min,&src_max] (
int i,
int j,
int ) noexcept
957 src_min = std::min(src_min, src_arr(i,j,0));
958 src_max = std::max(src_max, src_arr(i,j,0));
962 amrex::Print() <<
"Nodal reconstruction at k = " << klev <<
": "
966 <<
"] m vs " << src_name <<
" in [" << src_min <<
", " << src_max <<
"] m"
969 <<
"\n max deviation from direct interpolation = " << info.
deviation
980 bad_reconstruction = 1;
983 z_nd_slice.copy<amrex::RunOn::Host>(result.first, nd_box, 0, nd_box, 0, 1);
986 amrex::ParallelDescriptor::Bcast(&bad_reconstruction, 1, ioproc);
987 if (bad_reconstruction) {
988 amrex::Abort(
"Nodal reconstruction produced heights far outside the range of the "
989 + src_name +
"; the reconstruction is not usable as terrain.");
992 amrex::ParallelDescriptor::Bcast(z_nd_slice.dataPtr(), z_nd_slice.size(), ioproc);
1008 amrex::FArrayBox
const& z_nd_slice)
1010 amrex::Box
const& nd_box = z_nd_slice.box();
1011 int const ilo = nd_box.smallEnd(0);
int const ihi = nd_box.bigEnd(0);
1012 int const jlo = nd_box.smallEnd(1);
int const jhi = nd_box.bigEnd(1);
1014 auto const z_slice_arr = z_nd_slice.const_array();
1016 for ( amrex::MFIter mfi(z_phys_nd); mfi.isValid(); ++mfi ) {
1017 amrex::Box gbx = mfi.growntilebox();
1021 if (klev < gbx.smallEnd(2) || klev > gbx.bigEnd(2)) {
continue; }
1023 amrex::Box sbx = amrex::makeSlab(gbx, 2, klev);
1024 auto const z_arr = z_phys_nd.array(mfi);
1027 int const ii = amrex::max(amrex::min(i,ihi),ilo);
1028 int const jj = amrex::max(amrex::min(j,jhi),jlo);
1029 z_arr(i,j,k) = z_slice_arr(ii,jj,0);
1036 amrex::Gpu::streamSynchronize();
constexpr amrex::Real four
Definition: ERF_Constants.H:12
constexpr amrex::Real two
Definition: ERF_Constants.H:10
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real fourth
Definition: ERF_Constants.H:14
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
const Real dy
Definition: ERF_InitCustomPert_ABL.H:45
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
amrex::Real beta
Definition: ERF_InitCustomPert_DataAssimilation_ISV.H:10
ParallelFor(fab_box, [=] AMREX_GPU_DEVICE(int i, int j, int k) { qrcuten_arr(i, j, k)=Real(0);qscuten_arr(i, j, k)=Real(0);qicuten_arr(i, j, k)=Real(0);})
amrex::FArrayBox reconstruct_nodal_height_slice(amrex::Box const &cc_slice_box, amrex::Geometry const &geom, amrex::FArrayBox const &z_cc_slice, int klev, std::string const &src_name)
Definition: ERF_NodalReconstruction.H:894
VariationOperator
Definition: ERF_NodalReconstruction.H:25
void fill_nodal_level_from_slice(amrex::MultiFab &z_phys_nd, int klev, amrex::FArrayBox const &z_nd_slice)
Definition: ERF_NodalReconstruction.H:1006
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_NodalReconstruction.H:129
amrex::Real m_gyy
Definition: ERF_NodalReconstruction.H:408
amrex::Box m_x_edge_box
Definition: ERF_NodalReconstruction.H:398
void applyLTL(amrex::FArrayBox const &S, amrex::FArrayBox &R) const
Apply the product of the Laplacian operator and its adjoint.
Definition: ERF_NodalReconstruction.H:593
void applyDT(amrex::FArrayBox const &difx, amrex::FArrayBox const &dify, amrex::FArrayBox &R) const
Apply the adjoint of the derivative operator.
Definition: ERF_NodalReconstruction.H:499
SolveInfo conjugateGradient(amrex::FArrayBox const &rhs, amrex::FArrayBox &x, Real relative_tolerance, int max_iterations) const
Definition: ERF_NodalReconstruction.H:743
amrex::Real m_lambda
Definition: ERF_NodalReconstruction.H:409
int m_ihi
Definition: ERF_NodalReconstruction.H:402
void applyAT(amrex::FArrayBox const &T, amrex::FArrayBox &R) const
Adjoint of applyA: scatter each cell value to its four nodes.
Definition: ERF_NodalReconstruction.H:446
Real maxAverageError(amrex::FArrayBox const &T, amrex::FArrayBox const &S) const
max_ij | avg4(S) - T |
Definition: ERF_NodalReconstruction.H:349
amrex::Box const & nodalBox() const noexcept
Definition: ERF_NodalReconstruction.H:195
VariationOperator m_var_op
Definition: ERF_NodalReconstruction.H:411
void applyJacobi(amrex::FArrayBox const &diag, amrex::FArrayBox const &r, amrex::FArrayBox &z) const
Apply the Jacobi preconditioner.
Definition: ERF_NodalReconstruction.H:838
int m_ilo
Definition: ERF_NodalReconstruction.H:401
void computeDiagonal(amrex::FArrayBox &diag) const
Definition: ERF_NodalReconstruction.H:656
Real totalSquaredVariation(amrex::FArrayBox const &S) const
Definition: ERF_NodalReconstruction.H:365
amrex::FArrayBox makeReference(amrex::FArrayBox const &T) const
Definition: ERF_NodalReconstruction.H:205
void applyM(amrex::FArrayBox const &S, amrex::FArrayBox &R) const
R = ( A^T A + lambda V^T V + mu I ) S.
Definition: ERF_NodalReconstruction.H:635
void applyA(amrex::FArrayBox const &S, amrex::FArrayBox &T) const
(A S)(i,j) = 1/4 [ S(i,j) + S(i+1,j) + S(i,j+1) + S(i+1,j+1) ]
Definition: ERF_NodalReconstruction.H:427
NodalReconstruction(amrex::Box const &cc_slice_box, amrex::Geometry const &geom)
Construct a nodal reconstruction object for one horizontal slice.
Definition: ERF_NodalReconstruction.H:145
static constexpr amrex::Real relief_factor
... nor than this fraction of the relief of the data.
Definition: ERF_NodalReconstruction.H:390
void applyD(amrex::FArrayBox const &S, amrex::FArrayBox &difx, amrex::FArrayBox &dify) const
Compute the first derivatives of the nodal field.
Definition: ERF_NodalReconstruction.H:469
amrex::Real m_gxx
Definition: ERF_NodalReconstruction.H:407
amrex::FArrayBox m_nd_scratch
Definition: ERF_NodalReconstruction.H:414
amrex::Box m_y_edge_box
Definition: ERF_NodalReconstruction.H:399
Real maxAbs(amrex::FArrayBox const &F) const
Definition: ERF_NodalReconstruction.H:728
void applyLT(amrex::FArrayBox const &lap, amrex::FArrayBox &R) const
Apply the adjoint of the Laplacian operator.
Definition: ERF_NodalReconstruction.H:568
static constexpr amrex::Real mu_growth
Definition: ERF_NodalReconstruction.H:393
amrex::Box m_nodal_box
Definition: ERF_NodalReconstruction.H:397
std::pair< amrex::FArrayBox, SolveInfo > solve(amrex::FArrayBox const &T, amrex::FArrayBox const &reference, VariationOperator var_op, Real relative_tolerance=Real(1.e-10), Real smoothing=Real(1.e-2), Real min_regularization=Real(2.5e-4), int max_iterations=1000)
Definition: ERF_NodalReconstruction.H:240
amrex::Box m_interior_nodal_box
Definition: ERF_NodalReconstruction.H:400
amrex::FArrayBox m_cc_scratch
Definition: ERF_NodalReconstruction.H:413
amrex::FArrayBox m_difx
Definition: ERF_NodalReconstruction.H:417
amrex::Real m_mu
Definition: ERF_NodalReconstruction.H:410
int m_jlo
Definition: ERF_NodalReconstruction.H:403
static constexpr amrex::Real deviation_factor
Definition: ERF_NodalReconstruction.H:388
void applyVariationOperator(amrex::FArrayBox const &S, amrex::FArrayBox &R) const
Apply the selected variation operator (first derivative or Laplacian).
Definition: ERF_NodalReconstruction.H:612
void computeDiagnostics(amrex::FArrayBox const &T, amrex::FArrayBox const &S, SolveInfo &info) const
Compute diagnostic metrics for the reconstructed nodal field.
Definition: ERF_NodalReconstruction.H:710
amrex::Real m_gx
Definition: ERF_NodalReconstruction.H:405
amrex::Box m_cc_slice_box
Definition: ERF_NodalReconstruction.H:396
Real dot(amrex::FArrayBox const &a, amrex::FArrayBox const &b) const
Definition: ERF_NodalReconstruction.H:852
amrex::Real m_gy
Definition: ERF_NodalReconstruction.H:406
void applyL(amrex::FArrayBox const &S, amrex::FArrayBox &lap) const
Apply the Laplacian operator to a nodal field.
Definition: ERF_NodalReconstruction.H:543
amrex::Real Real
Definition: ERF_NodalReconstruction.H:131
amrex::FArrayBox m_dify
Definition: ERF_NodalReconstruction.H:418
int m_jhi
Definition: ERF_NodalReconstruction.H:404
void applyDTD(amrex::FArrayBox const &S, amrex::FArrayBox &R) const
Apply the product of the derivative operator and its adjoint.
Definition: ERF_NodalReconstruction.H:529
static constexpr int max_attempts
Definition: ERF_NodalReconstruction.H:394
amrex::FArrayBox m_lap
Definition: ERF_NodalReconstruction.H:419
@ qc
Definition: ERF_SatAdj.H:41
@ R
Definition: ERF_IndexDefines.H:130
@ T
Definition: ERF_IndexDefines.H:128
@ qa
Definition: ERF_AdvanceWDM6.cpp:274
@ q
Definition: ERF_WSM6.H:184
@ p
Definition: ERF_WSM6.H:191
real(kind=kind_phys), parameter, private alpha
Definition: ERF_module_mp_wdm6.F90:62
Convergence and diagnostic information for the reconstruction solve.
Definition: ERF_NodalReconstruction.H:33
amrex::Real final_residual
CG residual of the accepted solve.
Definition: ERF_NodalReconstruction.H:35
int iterations
total CG iterations, summed over attempts
Definition: ERF_NodalReconstruction.H:34
amrex::Real max_average_error
max |avg4(S) - T|
Definition: ERF_NodalReconstruction.H:43
amrex::Real max_value
max over nodes of S
Definition: ERF_NodalReconstruction.H:46
amrex::Real min_value
min over nodes of S
Definition: ERF_NodalReconstruction.H:45
bool converged
Definition: ERF_NodalReconstruction.H:36
int refinements
times the regularization had to be raised
Definition: ERF_NodalReconstruction.H:37
amrex::Real deviation
max |S - S_ref|
Definition: ERF_NodalReconstruction.H:41
amrex::Real deviation_cap
bound imposed on the above
Definition: ERF_NodalReconstruction.H:42
amrex::Real interp_average_error
max |avg4(S_ref) - T|, for comparison
Definition: ERF_NodalReconstruction.H:44
amrex::Real regularization
accepted value of mu
Definition: ERF_NodalReconstruction.H:38