1 #ifndef ERF_NODAL_RECONSTRUCTION_H_
2 #define ERF_NODAL_RECONSTRUCTION_H_
12 #include "AMReX_Array4.H"
13 #include "AMReX_BLassert.H"
14 #include "AMReX_Box.H"
15 #include "AMReX_FArrayBox.H"
16 #include "AMReX_GpuDevice.H"
17 #include "AMReX_Geometry.H"
18 #include "AMReX_MultiFab.H"
19 #include "AMReX_ParallelDescriptor.H"
20 #include "AMReX_Print.H"
21 #include "AMReX_REAL.H"
147 amrex::Geometry
const& geom)
149 m_ilo(w_face_slice_box.smallEnd(0)),
150 m_ihi(w_face_slice_box.bigEnd(0)),
151 m_jlo(w_face_slice_box.smallEnd(1)),
152 m_jhi(w_face_slice_box.bigEnd(1))
156 if (!w_face_slice_box.ok()) {
157 amrex::Abort(
"NodalReconstruction: w_face_slice_box is empty; the input "
158 "heights were probably never read.");
160 if (w_face_slice_box.length(2) != 1) {
161 amrex::Abort(
"NodalReconstruction: w_face_slice_box must contain exactly one z cell.");
163 if (w_face_slice_box.smallEnd(2) != 0) {
164 amrex::Abort(
"NodalReconstruction: w_face_slice_box must be a slab at k = 0; "
165 "all fabs are indexed at k = 0.");
168 m_nodal_box = amrex::surroundingNodes(w_face_slice_box);
180 Real const dx = geom.CellSizeArray()[0];
181 Real const dy = geom.CellSizeArray()[1];
183 amrex::Abort(
"NodalReconstruction: cell sizes must be positive.");
196 [[nodiscard]] amrex::Box
const&
nodalBox () const noexcept {
211 amrex::FArrayBox
R(
m_nodal_box,1,amrex::The_Managed_Arena());
212 auto const T_arr =
T.const_array();
213 auto const R_arr =
R.array();
216 int const jm = std::max(
m_jlo, std::min(j-1,
m_jhi));
217 int const jp = std::max(
m_jlo, std::min(j ,
m_jhi));
219 int const im = std::max(
m_ilo, std::min(i-1,
m_ihi));
220 int const ip = std::max(
m_ilo, std::min(i ,
m_ihi));
221 R_arr(i,j,0) =
fourth * ( T_arr(im,jm,0) + T_arr(ip,jm,0)
222 + T_arr(im,jp,0) + T_arr(ip,jp,0) );
240 [[nodiscard]] std::pair<amrex::FArrayBox,SolveInfo>
242 amrex::FArrayBox
const& reference,
244 Real relative_tolerance =
Real(1.e-10),
246 Real min_regularization =
Real(2.5e-4),
247 int max_iterations = 1000)
249 if (!(smoothing >
zero)) {
250 amrex::Abort(
"NodalReconstruction: smoothing weight must be positive.");
252 if (!(min_regularization >
zero)) {
256 amrex::Abort(
"NodalReconstruction: regularization must be positive.");
278 Real t_min = std::numeric_limits<Real>::max();
279 Real t_max = -std::numeric_limits<Real>::max();
282 auto const T_arr =
T.const_array();
283 auto const m_arr = misfit.array();
286 m_arr(i,j,0) = T_arr(i,j,0) - m_arr(i,j,0);
287 misfit_max = std::max(misfit_max, std::abs(m_arr(i,j,0)));
288 t_min = std::min(t_min, T_arr(i,j,0));
289 t_max = std::max(t_max, T_arr(i,j,0));
301 amrex::FArrayBox rhs(
m_nodal_box,1,amrex::The_Managed_Arena());
307 amrex::FArrayBox E(
m_nodal_box,1,amrex::The_Managed_Arena());
311 amrex::FArrayBox
S(
m_nodal_box,1,amrex::The_Managed_Arena());
313 m_mu = min_regularization;
314 bool accepted =
false;
329 auto const S_arr =
S.array();
330 auto const r_arr = reference.const_array();
331 auto const E_arr = E.const_array();
334 S_arr(i,j,0) = r_arr(i,j,0) + E_arr(i,j,0);
340 S.copy<amrex::RunOn::Host>(reference,0,0,1);
346 return {std::move(
S),info};
351 amrex::FArrayBox
const&
S)
const
353 auto const T_arr =
T.const_array();
354 auto const S_arr =
S.const_array();
358 Real const avg =
fourth * ( S_arr(i ,j ,0) + S_arr(i+1,j ,0)
359 + S_arr(i ,j+1,0) + S_arr(i+1,j+1,0) );
360 err = std::max(err, std::abs(avg - T_arr(i,j,0)));
368 auto const S_arr =
S.const_array();
373 Real const d = S_arr(i+1,j,0) - S_arr(i,j,0);
379 Real const d = S_arr(i,j+1,0) - S_arr(i,j,0);
429 amrex::FArrayBox&
T)
const
431 auto const S_arr =
S.const_array();
432 auto const T_arr =
T.array();
435 T_arr(i,j,0) =
fourth * ( S_arr(i ,j ,0) + S_arr(i+1,j ,0)
436 + S_arr(i ,j+1,0) + S_arr(i+1,j+1,0) );
448 amrex::FArrayBox&
R)
const
450 R.setVal<amrex::RunOn::Host>(
zero);
451 auto const T_arr =
T.const_array();
452 auto const R_arr =
R.array();
457 R_arr(i+1,j ,0) +=
q;
458 R_arr(i ,j+1,0) +=
q;
459 R_arr(i+1,j+1,0) +=
q;
471 amrex::FArrayBox& difx,
472 amrex::FArrayBox& dify)
const
474 difx.setVal<amrex::RunOn::Host>(
zero);
475 dify.setVal<amrex::RunOn::Host>(
zero);
477 auto const S_arr =
S.const_array();
478 auto const difx_arr = difx.array();
479 auto const dify_arr = dify.array();
483 difx_arr(i, j, 0) =
m_gx * ( S_arr(i+1, j, 0) - S_arr(i, j, 0) );
489 dify_arr(i, j, 0) =
m_gy * ( S_arr(i, j+1, 0) - S_arr(i, j, 0) );
501 amrex::FArrayBox
const& dify,
502 amrex::FArrayBox&
R)
const
504 R.setVal<amrex::RunOn::Host>(
zero);
506 auto const qx_arr = difx.const_array();
507 auto const qy_arr = dify.const_array();
508 auto const R_arr =
R.array();
512 R_arr(i , j, 0) -=
m_gx * qx_arr(i, j, 0);
513 R_arr(i+1, j, 0) +=
m_gx * qx_arr(i, j, 0);
519 R_arr(i, j , 0) -=
m_gy * qy_arr(i, j, 0);
520 R_arr(i, j+1, 0) +=
m_gy * qy_arr(i, j, 0);
531 amrex::FArrayBox&
R)
const
545 amrex::FArrayBox& lap)
const
547 lap.setVal<amrex::RunOn::Host>(
zero);
549 auto const S_arr =
S.const_array();
550 auto const lap_arr = lap.array();
554 lap_arr(i, j, 0) =
m_gxx * ( S_arr(i+1, j , 0)
555 -
two * S_arr(i , j , 0)
556 + S_arr(i-1, j , 0) )
557 +
m_gyy * ( S_arr(i , j+1, 0)
558 -
two * S_arr(i , j , 0)
559 + S_arr(i , j-1, 0) );
570 amrex::FArrayBox&
R)
const
572 R.setVal<amrex::RunOn::Host>(
zero);
574 auto const q_arr = lap.const_array();
575 auto const R_arr =
R.array();
580 R_arr(i-1, j , 0) +=
m_gxx * val;
581 R_arr(i+1, j , 0) +=
m_gxx * val;
582 R_arr(i , j-1, 0) +=
m_gyy * val;
583 R_arr(i , j+1, 0) +=
m_gyy * val;
595 amrex::FArrayBox&
R)
const
600 R.setVal<amrex::RunOn::Host>(
zero);
614 amrex::FArrayBox&
R)
const
626 amrex::Abort(
"NodalReconstruction: unsupported variation operator.");
637 amrex::FArrayBox&
R)
const
643 auto const R_arr =
R.array();
645 auto const S_arr =
S.const_array();
648 R_arr(i,j,0) +=
m_lambda * v_arr(i,j,0) +
m_mu * S_arr(i,j,0);
659 diag.setVal<amrex::RunOn::Host>(
m_mu);
660 auto const d_arr = diag.array();
666 d_arr(i ,j ,0) +=
qa;
667 d_arr(i+1,j ,0) +=
qa;
668 d_arr(i ,j+1,0) +=
qa;
669 d_arr(i+1,j+1,0) +=
qa;
680 d_arr(i+1,j,0) += qx;
686 d_arr(i,j+1,0) += qy;
695 d_arr(i-1,j ,0) += qx;
696 d_arr(i+1,j ,0) += qx;
697 d_arr(i ,j-1,0) += qy;
698 d_arr(i ,j+1,0) += qy;
699 d_arr(i ,j ,0) +=
qc;
712 amrex::FArrayBox
const&
S,
715 auto const S_arr =
S.const_array();
716 Real smin = std::numeric_limits<Real>::max();
717 Real smax = -std::numeric_limits<Real>::max();
720 smin = std::min(smin, S_arr(i,j,0));
721 smax = std::max(smax, S_arr(i,j,0));
731 auto const F_arr = F.const_array();
735 v = std::max(v, std::abs(F_arr(i,j,0)));
746 Real relative_tolerance,
747 int max_iterations)
const
752 amrex::FArrayBox diag(
m_nodal_box,1,amrex::The_Managed_Arena());
758 amrex::FArrayBox r (
m_nodal_box,1,amrex::The_Managed_Arena());
762 amrex::FArrayBox
z (
m_nodal_box,1,amrex::The_Managed_Arena());
766 amrex::FArrayBox
p (
m_nodal_box,1,amrex::The_Managed_Arena());
770 amrex::FArrayBox Mp(
m_nodal_box,1,amrex::The_Managed_Arena());
772 x.setVal<amrex::RunOn::Host>(
zero);
773 r.copy<amrex::RunOn::Host>(rhs,0,0,1);
775 p.copy<amrex::RunOn::Host>(
z,0,0,1);
778 Real const initial = std::sqrt(
dot(r,r));
779 Real const tol = relative_tolerance * std::max({initial,
one});
783 if (initial <= tol) {
784 info.converged =
true;
788 for (
int it=0; it<max_iterations; ++it) {
791 if (!(pMp >
zero) || !std::isfinite(pMp)) {
792 amrex::Abort(
"NodalReconstruction: CG curvature failure.");
797 auto const x_arr =
x.array();
798 auto const r_arr = r.array();
799 auto const p_arr =
p.const_array();
800 auto const Mp_arr = Mp.const_array();
803 x_arr(i,j,0) +=
alpha * p_arr(i,j,0);
804 r_arr(i,j,0) -=
alpha * Mp_arr(i,j,0);
809 info.iterations = it+1;
810 info.final_residual = std::sqrt(
dot(r,r));
811 if (info.final_residual <= tol) {
812 info.converged =
true;
820 auto const p_arr =
p.array();
821 auto const z_arr =
z.const_array();
824 p_arr(i,j,0) = z_arr(i,j,0) +
beta * p_arr(i,j,0);
840 amrex::FArrayBox
const& r,
841 amrex::FArrayBox&
z)
const
843 auto const d_arr = diag.const_array();
844 auto const r_arr = r.const_array();
845 auto const z_arr =
z.array();
848 z_arr(i,j,0) = r_arr(i,j,0) / d_arr(i,j,0);
853 [[nodiscard]]
Real dot (amrex::FArrayBox
const& a,
854 amrex::FArrayBox
const& b)
const
856 auto const a_arr = a.const_array();
857 auto const b_arr = b.const_array();
861 v += a_arr(i,j,0) * b_arr(i,j,0);
893 for (
int k(0); k<n; ++k) { s[k+1] =
two*
t[k] - s[k]; }
899 for (
int k(0); k<n; ++k) { acc += sgn * (s[k+1] - s[k]); sgn = -sgn; }
900 Real const s0 = acc / (
two *
static_cast<Real>(n));
903 for (
int k(0); k<=n; ++k) { s[k] += sgn * s0; sgn = -sgn; }
932 inline std::pair<amrex::FArrayBox,SolveInfo>
934 amrex::FArrayBox
const& z_w_face,
935 amrex::FArrayBox
const& z_ref)
939 amrex::Box nd_box = amrex::surroundingNodes(w_face_box);
940 nd_box.setSmall(2,0);
943 amrex::FArrayBox
S(nd_box, 1, amrex::The_Managed_Arena());
945 int const ilo = w_face_box.smallEnd(0), ihi = w_face_box.bigEnd(0);
946 int const jlo = w_face_box.smallEnd(1), jhi = w_face_box.bigEnd(1);
947 int const nx = ihi - ilo + 1;
948 int const ny = jhi - jlo + 1;
950 auto const T_arr = z_w_face.const_array();
951 auto const R_arr = z_ref.const_array();
952 auto const S_arr =
S.array();
955 std::vector<Real>
U(
static_cast<std::size_t
>(
nx) *
static_cast<std::size_t
>(
ny+1));
956 std::vector<Real> tline(
static_cast<std::size_t
>(std::max(
nx,
ny)));
957 std::vector<Real> sline(
static_cast<std::size_t
>(std::max(
nx,
ny)+1));
960 for (
int i(0); i<
nx; ++i) {
961 for (
int j(0); j<
ny; ++j) { tline[
static_cast<std::size_t
>(j)] = T_arr(ilo+i,jlo+j,0); }
963 for (
int j(0); j<=
ny; ++j) {
964 U[
static_cast<std::size_t
>(i)*
static_cast<std::size_t
>(
ny+1) +
965 static_cast<std::size_t
>(j)] = sline[
static_cast<std::size_t
>(j)];
970 for (
int j(0); j<=
ny; ++j) {
971 for (
int i(0); i<
nx; ++i) {
972 tline[
static_cast<std::size_t
>(i)] =
973 U[
static_cast<std::size_t
>(i)*
static_cast<std::size_t
>(
ny+1) +
974 static_cast<std::size_t
>(j)];
977 for (
int i(0); i<=
nx; ++i) { S_arr(ilo+i,jlo+j,0) = sline[
static_cast<std::size_t
>(i)]; }
986 info.
min_value = std::numeric_limits<Real>::max();
987 info.
max_value = -std::numeric_limits<Real>::max();
989 for (
int j(jlo); j<=jhi+1; ++j) {
990 for (
int i(ilo); i<=ihi+1; ++i) {
991 Real const v = S_arr(i,j,0);
997 for (
int j(jlo); j<=jhi; ++j) {
998 for (
int i(ilo); i<=ihi; ++i) {
999 Real const a4 =
fourth * ( S_arr(i,j,0) + S_arr(i+1,j,0)
1000 + S_arr(i,j+1,0) + S_arr(i+1,j+1,0) );
1001 Real const r4 =
fourth * ( R_arr(i,j,0) + R_arr(i+1,j,0)
1002 + R_arr(i,j+1,0) + R_arr(i+1,j+1,0) );
1004 std::abs(
a4 - T_arr(i,j,0)));
1006 std::abs(r4 - T_arr(i,j,0)));
1011 return {std::move(
S), info};
1040 inline amrex::FArrayBox
1042 amrex::Geometry
const& geom,
1043 amrex::FArrayBox
const& z_w_face_slice,
1045 std::string
const& src_name)
1051 "reconstruct_nodal_height_slice: the input slice is empty "
1052 "or spans more than one z level -- check that the source "
1053 "heights were read successfully.");
1057 amrex::Gpu::streamSynchronize();
1059 amrex::Box nd_box = amrex::surroundingNodes(w_face_slice_box);
1060 nd_box.setSmall(2, 0);
1061 nd_box.setBig(2, 0);
1064 amrex::FArrayBox z_nd_slice(nd_box, 1, amrex::The_Managed_Arena());
1066 int const ioproc = amrex::ParallelDescriptor::IOProcessorNumber();
1071 int bad_reconstruction = 0;
1073 if (amrex::ParallelDescriptor::IOProcessor())
1079 amrex::Real src_min = std::numeric_limits<amrex::Real>::max();
1080 amrex::Real src_max = -std::numeric_limits<amrex::Real>::max();
1082 auto const src_arr = z_w_face_slice.const_array();
1083 amrex::LoopOnCpu(w_face_slice_box, [=,&src_min,&src_max] (
int i,
int j,
int ) noexcept
1085 src_min = std::min(src_min, src_arr(i,j,0));
1086 src_max = std::max(src_max, src_arr(i,j,0));
1092 auto in_range = [=] (
SolveInfo const& si) noexcept ->
bool
1094 return std::isfinite(si.min_value) && std::isfinite(si.max_value) &&
1095 (si.min_value >= src_min - slack) && (si.max_value <= src_max + slack);
1099 amrex::FArrayBox z_ref = NR_solver.
makeReference(z_w_face_slice);
1114 z_w_face_slice, z_ref);
1116 bool const exact_usable = in_range(info);
1119 amrex::Print() <<
"Nodal reconstruction at k = " << klev <<
": exact de-averaging"
1121 <<
"] m vs " << src_name <<
" in [" << src_min <<
", " << src_max <<
"] m"
1124 <<
"\n max deviation from direct interpolation = " << info.
deviation
1125 <<
" m" << std::endl;
1130 amrex::Print() <<
"WARNING: exact de-averaging at k = " << klev
1132 <<
"] m, outside the range of the " << src_name <<
" ["
1133 << src_min <<
", " << src_max <<
"] m.\n"
1134 <<
" Falling back to the regularized least-squares fit, which "
1135 "does NOT reproduce the " << src_name <<
" exactly; the w-face "
1136 "heights will differ from the source by the error reported below.\n";
1140 info = result.second;
1143 amrex::Print() <<
"WARNING: Nodal reconstruction did not converge at k = " << klev
1145 <<
" and requested tolerance was: " << tol <<
"\n";
1148 amrex::Print() <<
"Nodal reconstruction at k = " << klev <<
": "
1152 <<
"] m vs " << src_name <<
" in [" << src_min <<
", " << src_max <<
"] m"
1155 <<
"\n max deviation from direct interpolation = " << info.
deviation
1158 if (!in_range(info)) { bad_reconstruction = 1; }
1161 z_nd_slice.copy<amrex::RunOn::Host>(result.first, nd_box, 0, nd_box, 0, 1);
1164 amrex::ParallelDescriptor::Bcast(&bad_reconstruction, 1, ioproc);
1165 if (bad_reconstruction) {
1166 amrex::Abort(
"Nodal reconstruction produced heights far outside the range of the "
1167 + src_name +
"; the reconstruction is not usable as terrain.");
1170 amrex::ParallelDescriptor::Bcast(z_nd_slice.dataPtr(), z_nd_slice.size(), ioproc);
1186 amrex::FArrayBox
const& z_nd_slice)
1188 amrex::Box
const& nd_box = z_nd_slice.box();
1189 int const ilo = nd_box.smallEnd(0);
int const ihi = nd_box.bigEnd(0);
1190 int const jlo = nd_box.smallEnd(1);
int const jhi = nd_box.bigEnd(1);
1192 auto const z_slice_arr = z_nd_slice.const_array();
1194 for ( amrex::MFIter mfi(z_phys_nd); mfi.isValid(); ++mfi ) {
1195 amrex::Box gbx = mfi.growntilebox();
1199 if (klev < gbx.smallEnd(2) || klev > gbx.bigEnd(2)) {
continue; }
1201 amrex::Box sbx = amrex::makeSlab(gbx, 2, klev);
1202 auto const z_arr = z_phys_nd.array(mfi);
1205 int const ii = amrex::max(amrex::min(i,ihi),ilo);
1206 int const jj = amrex::max(amrex::min(j,jhi),jlo);
1207 z_arr(i,j,k) = z_slice_arr(ii,jj,0);
1214 amrex::Gpu::streamSynchronize();
const int nx
Definition: ERF_InitCustomPertVels_CloudChamber.H:14
const int ny
Definition: ERF_InitCustomPertVels_CloudChamber.H:15
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")
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);})
void deaverage_line(amrex::Real const *t, int n, amrex::Real *s)
Definition: ERF_NodalReconstruction.H:887
VariationOperator
Definition: ERF_NodalReconstruction.H:26
std::pair< amrex::FArrayBox, SolveInfo > deaverage_nodal_slice(amrex::Box const &w_face_box, amrex::FArrayBox const &z_w_face, amrex::FArrayBox const &z_ref)
Definition: ERF_NodalReconstruction.H:933
amrex::FArrayBox reconstruct_nodal_height_slice(amrex::Box const &w_face_slice_box, amrex::Geometry const &geom, amrex::FArrayBox const &z_w_face_slice, int klev, std::string const &src_name)
Definition: ERF_NodalReconstruction.H:1041
void fill_nodal_level_from_slice(amrex::MultiFab &z_phys_nd, int klev, amrex::FArrayBox const &z_nd_slice)
Definition: ERF_NodalReconstruction.H:1184
Dimensionless numeric literals and pure mathematical constants.
constexpr amrex::Real four
Definition: ERF_NumericalConstants.H:40
constexpr amrex::Real two
Definition: ERF_NumericalConstants.H:38
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:37
constexpr amrex::Real fourth
Definition: ERF_NumericalConstants.H:42
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_NodalReconstruction.H:130
amrex::Real m_gyy
Definition: ERF_NodalReconstruction.H:409
amrex::Box m_x_edge_box
Definition: ERF_NodalReconstruction.H:399
void applyLTL(amrex::FArrayBox const &S, amrex::FArrayBox &R) const
Apply the product of the Laplacian operator and its adjoint.
Definition: ERF_NodalReconstruction.H:594
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:500
SolveInfo conjugateGradient(amrex::FArrayBox const &rhs, amrex::FArrayBox &x, Real relative_tolerance, int max_iterations) const
Definition: ERF_NodalReconstruction.H:744
amrex::Real m_lambda
Definition: ERF_NodalReconstruction.H:410
int m_ihi
Definition: ERF_NodalReconstruction.H:403
void applyAT(amrex::FArrayBox const &T, amrex::FArrayBox &R) const
Adjoint of applyA: scatter each w-face value to its four nodes.
Definition: ERF_NodalReconstruction.H:447
Real maxAverageError(amrex::FArrayBox const &T, amrex::FArrayBox const &S) const
max_ij | avg4(S) - T |
Definition: ERF_NodalReconstruction.H:350
amrex::Box const & nodalBox() const noexcept
Definition: ERF_NodalReconstruction.H:196
VariationOperator m_var_op
Definition: ERF_NodalReconstruction.H:412
void applyJacobi(amrex::FArrayBox const &diag, amrex::FArrayBox const &r, amrex::FArrayBox &z) const
Apply the Jacobi preconditioner.
Definition: ERF_NodalReconstruction.H:839
int m_ilo
Definition: ERF_NodalReconstruction.H:402
void computeDiagonal(amrex::FArrayBox &diag) const
Definition: ERF_NodalReconstruction.H:657
Real totalSquaredVariation(amrex::FArrayBox const &S) const
Definition: ERF_NodalReconstruction.H:366
amrex::FArrayBox makeReference(amrex::FArrayBox const &T) const
Definition: ERF_NodalReconstruction.H:206
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:636
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:428
NodalReconstruction(amrex::Box const &w_face_slice_box, amrex::Geometry const &geom)
Construct a nodal reconstruction object for one horizontal slice.
Definition: ERF_NodalReconstruction.H:146
static constexpr amrex::Real relief_factor
... nor than this fraction of the relief of the data.
Definition: ERF_NodalReconstruction.H:391
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:470
amrex::Real m_gxx
Definition: ERF_NodalReconstruction.H:408
amrex::FArrayBox m_nd_scratch
Definition: ERF_NodalReconstruction.H:415
amrex::FArrayBox m_w_face_scratch
Definition: ERF_NodalReconstruction.H:414
amrex::Box m_y_edge_box
Definition: ERF_NodalReconstruction.H:400
Real maxAbs(amrex::FArrayBox const &F) const
Definition: ERF_NodalReconstruction.H:729
void applyLT(amrex::FArrayBox const &lap, amrex::FArrayBox &R) const
Apply the adjoint of the Laplacian operator.
Definition: ERF_NodalReconstruction.H:569
static constexpr amrex::Real mu_growth
Definition: ERF_NodalReconstruction.H:394
amrex::Box m_nodal_box
Definition: ERF_NodalReconstruction.H:398
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:241
amrex::Box m_interior_nodal_box
Definition: ERF_NodalReconstruction.H:401
amrex::FArrayBox m_difx
Definition: ERF_NodalReconstruction.H:418
amrex::Real m_mu
Definition: ERF_NodalReconstruction.H:411
int m_jlo
Definition: ERF_NodalReconstruction.H:404
static constexpr amrex::Real deviation_factor
Definition: ERF_NodalReconstruction.H:389
void applyVariationOperator(amrex::FArrayBox const &S, amrex::FArrayBox &R) const
Apply the selected variation operator (first derivative or Laplacian).
Definition: ERF_NodalReconstruction.H:613
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:711
amrex::Real m_gx
Definition: ERF_NodalReconstruction.H:406
amrex::Box m_w_face_slice_box
Definition: ERF_NodalReconstruction.H:397
Real dot(amrex::FArrayBox const &a, amrex::FArrayBox const &b) const
Definition: ERF_NodalReconstruction.H:853
amrex::Real m_gy
Definition: ERF_NodalReconstruction.H:407
void applyL(amrex::FArrayBox const &S, amrex::FArrayBox &lap) const
Apply the Laplacian operator to a nodal field.
Definition: ERF_NodalReconstruction.H:544
amrex::Real Real
Definition: ERF_NodalReconstruction.H:132
amrex::FArrayBox m_dify
Definition: ERF_NodalReconstruction.H:419
int m_jhi
Definition: ERF_NodalReconstruction.H:405
void applyDTD(amrex::FArrayBox const &S, amrex::FArrayBox &R) const
Apply the product of the derivative operator and its adjoint.
Definition: ERF_NodalReconstruction.H:530
static constexpr int max_attempts
Definition: ERF_NodalReconstruction.H:395
amrex::FArrayBox m_lap
Definition: ERF_NodalReconstruction.H:420
@ qc
Definition: ERF_SatAdj.H:42
@ R
Definition: ERF_IndexDefines.H:133
@ U
Definition: ERF_IndexDefines.H:129
@ T
Definition: ERF_IndexDefines.H:131
@ beta
Definition: ERF_SLM.H:152
@ alpha
Definition: ERF_SLM.H:151
constexpr int S
Definition: ERF_TwoStreamColumn.H:604
@ qa
Definition: ERF_AdvanceWDM6.cpp:276
@ q
Definition: ERF_WSM6.H:273
@ t
Definition: ERF_WSM6.H:272
@ p
Definition: ERF_WSM6.H:280
real(c_double), parameter a4
Definition: ERF_module_model_constants.F90:97
Convergence and diagnostic information for the reconstruction solve.
Definition: ERF_NodalReconstruction.H:34
amrex::Real final_residual
CG residual of the accepted solve.
Definition: ERF_NodalReconstruction.H:36
int iterations
total CG iterations, summed over attempts
Definition: ERF_NodalReconstruction.H:35
amrex::Real max_average_error
max |avg4(S) - T|
Definition: ERF_NodalReconstruction.H:44
amrex::Real max_value
max over nodes of S
Definition: ERF_NodalReconstruction.H:47
amrex::Real min_value
min over nodes of S
Definition: ERF_NodalReconstruction.H:46
bool converged
Definition: ERF_NodalReconstruction.H:37
int refinements
times the regularization had to be raised
Definition: ERF_NodalReconstruction.H:38
amrex::Real deviation
max |S - S_ref|
Definition: ERF_NodalReconstruction.H:42
amrex::Real deviation_cap
bound imposed on the above
Definition: ERF_NodalReconstruction.H:43
amrex::Real interp_average_error
max |avg4(S_ref) - T|, for comparison
Definition: ERF_NodalReconstruction.H:45
amrex::Real regularization
accepted value of mu
Definition: ERF_NodalReconstruction.H:39