Reconstruct one horizontal slice of nodal heights from heights that live at cell centers in (x,y), reporting diagnostics and aborting if the result is unusable as terrain.
Both NetCDF initialization paths need exactly this operation and differ only in how the cell-centered slice is assembled (geopotential from PH + PHB for wrfinput, HGT_M for metgrid) and in what they do with the answer, so the solve and its checks live here and are called from both.
The solve is serial and covers the whole domain, so it runs on the I/O rank only and the resulting nodal slice is broadcast. Running it redundantly on every rank would cost a full-domain CG solve and several full-domain managed allocations per rank, i.e. a startup stall and a memory spike that grow with the rank count rather than with the decomposition. z_cc_slice must be host-accessible and must hold the global slice on the I/O rank.
This is collective: every rank must call it.
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);
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_NodalReconstruction.H:129
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