Exactly de-average one horizontal slice: find nodal S with avg4(S) = T to round-off, rather than the closest such field a smoothness prior will allow.
The four-node averaging operator is a tensor product of two one-dimensional two-point averages, A = Ax (x) Ay. Each of those is surjective – the line recursion above always solves – so A is surjective and an exact solution always exists; the system is underdetermined, not inconsistent, with (nx+1)(ny+1) unknowns against nx*ny equations. Separability means it can be solved in two sweeps: first Ay U = T for U (cell-centered in x, nodal in y), then Ax S = U. Both are O(N) and non-iterative.
What cannot be removed is grid-scale structure. The null space is spanned by (-1)^i a(j) + (-1)^j b(i), in which a does not vary with i, so the amplitude of the sawtooth cannot be varied along a line; rough terrain anywhere on a line leaves a signature everywhere on it. Minimizing the first-difference energy line by line, as deaverage_line does, exhausts that freedom – a globally coupled optimization over the whole null space was measured to give no further improvement. The caller is therefore responsible for deciding whether the result is usable as terrain, and for falling back if it is not.
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};
const int nx
Definition: ERF_InitCustomPertVels_CloudChamber.H:14
const int ny
Definition: ERF_InitCustomPertVels_CloudChamber.H:15
void deaverage_line(amrex::Real const *t, int n, amrex::Real *s)
Definition: ERF_NodalReconstruction.H:887
constexpr amrex::Real fourth
Definition: ERF_NumericalConstants.H:42
@ U
Definition: ERF_IndexDefines.H:129
constexpr int S
Definition: ERF_TwoStreamColumn.H:604
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