ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_Interpolation_1D.H
Go to the documentation of this file.
1 #ifndef Initialization_1D_H
2 #define Initialization_1D_H
3 
4 #include <AMReX_REAL.H>
5 #include "ERF_Constants.H"
6 
7 /**
8  * Interpolates 1D array beta at the location alpha_interp in the array alpha
9  * requiring 1D arrays alpha and beta to be the same size alpha_size.
10  * This routine assumes the alpha data are monotonic from lowest to highest.
11  */
12 
13 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
15  const amrex::Real alpha_interp, const int alpha_size)
16 {
17  // We put this value here so beta_interp is initialized but the logic
18  // below is such that it will always be assigned some other value.
19  amrex::Real beta_interp = bogus_large_value;
20 
21  // If the interpolation point already exists in the array,
22  // just return it
23  for (int i = 0; i < alpha_size; ++i) {
24  if (alpha[i] == alpha_interp) {
25  beta_interp = beta[i];
26  return beta_interp;
27  }
28  }
29 
30  // We didn't find an exact match for alpha_interp in alpha,
31  // so we need linear interpolation/extrapolation
32  amrex::Real alpha_min = alpha[0];
33  amrex::Real alpha_max = alpha[alpha_size-1];
34  if (alpha_interp >= alpha_min && alpha_interp <= alpha_max) //interpolate
35  {
36  for (int i = 0; i < alpha_size; ++i)
37  {
38  if (alpha_interp >= alpha[i] && alpha_interp <= alpha[i + 1])
39  {
40  //y = y0 + (y1-y0)*(x-x0)/(x1-x0);
41  amrex::Real y0 = beta[i];
42  amrex::Real y1 = beta[i + 1];
43  amrex::Real x = alpha_interp;
44  amrex::Real x0 = alpha[i];
45  amrex::Real x1 = alpha[i + 1];
46  beta_interp = y0 + (y1 - y0)*(x - x0) / (x1 - x0);
47  return beta_interp;
48  }
49  }
50  }
51  else //extrapolate
52  {
53  // y = y0 + ((x - x0) / (x1 - x0)) * (y1 - y0)
54  int i = 0;
55  if (alpha_interp > alpha_max)
56  {
57  i = alpha_size-2;
58  }
59  else if (alpha_interp >= alpha_min)
60  {
61  amrex::Abort("interpolate_1d: we shouldn't be here!");
62  }
63 
64  amrex::Real y0 = beta[i];
65  amrex::Real y1 = beta[i + 1];
66  amrex::Real x = alpha_interp;
67  amrex::Real x0 = alpha[i];
68  amrex::Real x1 = alpha[i + 1];
69  beta_interp = y0 + ((x - x0) / (x1 - x0)) * (y1 - y0);
70  return beta_interp;
71  }
72 
73  return beta_interp;
74 }
75 
76 /*
77  * Interpolate between values from a vector of reals (e.g., zlevels_stag) to a
78  * new, expanded vector with refine_fac-1 new uniformly spaced points between
79  * the original values.
80  *
81  * Example:
82  * Vector<Real> tmp_orig = {0,1,2};
83  * Vector<Real> tmp(4);
84  * expand_and_interpolate_1d(tmp, tmp_orig, 2, false); // tmp == {0, myhalf, 1, amrex::Real(1.5), 2}
85  * expand_and_interpolate_1d(tmp, tmp_orig, 2, true); // tmp == {fourth, amrex::Real(0.75), amrex::Real(1.25), amrex::Real(1.75)}
86  */
87 AMREX_FORCE_INLINE
88 void
89 expand_and_interpolate_1d (amrex::Vector<amrex::Real>& znew,
90  const amrex::Vector<amrex::Real>& zorig,
91  int refine_fac,
92  bool destag=false)
93 {
94  const int Nz = zorig.size();
95  const int Nz_refined = refine_fac*(Nz-1) + 1;
96  if (destag) {
97  AMREX_ALWAYS_ASSERT(znew.size() == Nz_refined-1);
98  } else {
99  AMREX_ALWAYS_ASSERT(znew.size() == Nz_refined);
100  }
101  amrex::Vector<amrex::Real> znew_stag(Nz_refined);
102  for (int k=0; k < Nz; ++k) {
103  znew_stag[refine_fac*k] = zorig[k];
104  }
105  if (refine_fac > 1) {
106  for (int k=0; k < Nz-1; ++k) {
107  amrex::Real z1 = zorig[k];
108  amrex::Real dz = zorig[k+1] - z1;
109  for (int koff=1; koff < refine_fac; ++koff) {
110  znew_stag[refine_fac*k + koff] = amrex::Real(koff)/refine_fac * dz + z1;
111  }
112  }
113  }
114  if (destag) {
115  for (int k=0; k < Nz_refined-1; ++k) {
116  znew[k] = myhalf*(znew_stag[k] + znew_stag[k+1]);
117  }
118  } else {
119  znew = znew_stag;
120  }
121 }
122 #endif
constexpr amrex::Real bogus_large_value
Definition: ERF_Constants.H:26
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
amrex::Real beta
Definition: ERF_InitCustomPert_DataAssimilation_ISV.H:10
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real interpolate_1d(const amrex::Real *alpha, const amrex::Real *beta, const amrex::Real alpha_interp, const int alpha_size)
Definition: ERF_Interpolation_1D.H:14
AMREX_FORCE_INLINE void expand_and_interpolate_1d(amrex::Vector< amrex::Real > &znew, const amrex::Vector< amrex::Real > &zorig, int refine_fac, bool destag=false)
Definition: ERF_Interpolation_1D.H:89
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ dz
Definition: ERF_AdvanceWSM6.cpp:104
real(kind=kind_phys), parameter, public alpha
Definition: ERF_module_mp_wsm6.F90:44