ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
InputSoundingData Struct Reference

#include <ERF_InputSoundingData.H>

Collaboration diagram for InputSoundingData:

Public Member Functions

 InputSoundingData ()
 Construct input sounding metadata from the ERF input namespace. More...
 
void resize_arrays ()
 Resize host and device sounding arrays for the configured sounding times. More...
 
void read_from_file (const amrex::Geometry &geom, const amrex::Vector< amrex::Real > &zlevels_stag, int itime, bool is_moist)
 Read and interpolate one input sounding profile onto level-0 heights. More...
 
void calc_rho_p (int itime)
 Hydrostatically integrate density and pressure for one sounding. More...
 
void calc_rho_p_isentropic (int itime)
 Compute density and pressure for an isentropic sounding profile. More...
 
void host_to_device (int itime)
 Copy host sounding arrays for one time index to device storage. More...
 
int size (int itime) const
 Return the number of interpolated samples for one sounding time. More...
 

Public Attributes

int ntimes
 Number of sounding times represented in the arrays. More...
 
amrex::Real tau_nudging = amrex::Real(5.0)
 Nudging time scale for relaxing toward input sounding data. More...
 
amrex::Vector< std::string > input_sounding_file = {}
 Sounding file path for each configured sounding time. More...
 
amrex::Vector< amrex::Realinput_sounding_time = {}
 Physical time associated with each input sounding file. More...
 
int n_sounding_files = 0
 Number of input sounding files. More...
 
int n_sounding_times = 0
 Number of input sounding times. More...
 
bool assume_dry {false}
 Whether to ignore moisture in isentropic pressure integration. More...
 
amrex::Real press_ref_inp_sound
 Surface reference pressure read from the input sounding [Pa]. More...
 
amrex::Real theta_ref_inp_sound
 Surface reference potential temperature read from the input sounding [K]. More...
 
amrex::Real qv_ref_inp_sound
 Surface reference water vapor mixing ratio read from the input sounding [kg/kg]. More...
 
amrex::Vector< amrex::Vector< amrex::Real > > z_inp_sound
 Interpolated host sounding heights for each sounding time [m]. More...
 
amrex::Vector< amrex::Vector< amrex::Real > > theta_inp_sound
 Interpolated host potential temperature profiles [K]. More...
 
amrex::Vector< amrex::Vector< amrex::Real > > qv_inp_sound
 Interpolated host water vapor mixing ratio profiles [kg/kg]. More...
 
amrex::Vector< amrex::Vector< amrex::Real > > U_inp_sound
 Interpolated host x velocity profiles. More...
 
amrex::Vector< amrex::Vector< amrex::Real > > V_inp_sound
 Interpolated host y velocity profiles. More...
 
amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real > > z_inp_sound_d
 Device sounding heights for each sounding time [m]. More...
 
amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real > > theta_inp_sound_d
 Device potential temperature profiles [K]. More...
 
amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real > > qv_inp_sound_d
 Device water vapor mixing ratio profiles [kg/kg]. More...
 
amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real > > U_inp_sound_d
 Device x velocity profiles. More...
 
amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real > > V_inp_sound_d
 Device y velocity profiles. More...
 
amrex::Vector< amrex::Realpm_integ
 Hydrostatically integrated moist pressure profile. More...
 
amrex::Vector< amrex::Realrhod_integ
 Hydrostatically integrated dry density profile. More...
 
amrex::Gpu::DeviceVector< amrex::Realp_inp_sound_d
 Device pressure profile used to initialize solution fields. More...
 
amrex::Gpu::DeviceVector< amrex::Realrho_inp_sound_d
 Device density profile used to initialize solution fields. More...
 

Detailed Description

Data structure storing input sounding data. Also handles reading the input file for sounding data and hydrostatic column integration.

Constructor & Destructor Documentation

◆ InputSoundingData()

InputSoundingData::InputSoundingData ( )
inline

Construct input sounding metadata from the ERF input namespace.

28  {
29  amrex::ParmParse pp("erf");
30  pp.query("tau_nudging", tau_nudging);
31 
32  // Read in input_sounding filename
33  n_sounding_files = pp.countval("input_sounding_file");
34  if (n_sounding_files > 0) {
36  pp.queryarr("input_sounding_file", input_sounding_file, 0, n_sounding_files);
37  } else {
38  n_sounding_files = 1;
40  input_sounding_file[0] = "input_sounding";
41  }
42 
43  // Read in input_sounding times
44  n_sounding_times = pp.countval("input_sounding_time");
45 
46  if (n_sounding_times > 0) {
48  pp.queryarr("input_sounding_time", input_sounding_time, 0, n_sounding_times);
49  } else {
50  n_sounding_times = 1;
53  }
54 
55  // If we have more files than times or times than files we just use the minimum
56  int n = std::min(n_sounding_times, n_sounding_files);
57  n_sounding_files = n;
58  n_sounding_times = n;
59  input_sounding_file.resize(n);
60  input_sounding_time.resize(n);
61  }
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
ParmParse pp("prob")
amrex::Vector< amrex::Real > input_sounding_time
Physical time associated with each input sounding file.
Definition: ERF_InputSoundingData.H:462
int n_sounding_times
Number of input sounding times.
Definition: ERF_InputSoundingData.H:464
amrex::Vector< std::string > input_sounding_file
Sounding file path for each configured sounding time.
Definition: ERF_InputSoundingData.H:461
amrex::Real tau_nudging
Nudging time scale for relaxing toward input sounding data.
Definition: ERF_InputSoundingData.H:459
int n_sounding_files
Number of input sounding files.
Definition: ERF_InputSoundingData.H:463
Here is the call graph for this function:

Member Function Documentation

◆ calc_rho_p()

void InputSoundingData::calc_rho_p ( int  itime)
inline

Hydrostatically integrate density and pressure for one sounding.

Parameters
itimeSounding time/file index to integrate.
223  {
224  /* Calculate density and pressure, roughly following the procedure in
225  * WRF dyn_em/module_initialize_ideal.F. We integrate hydrostatically
226  * from the surface up through the air column to get the dry density
227  * and moist pressure.
228  */
229  const amrex::Real tol = amrex::Real(1.0e-12);
230  const int Ninp = size(itime);
231  pm_integ.resize(Ninp);
232  rhod_integ.resize(Ninp);
233 
234  // evaluate surface quantities (k=0): total pressure and dry air
238  RdoCp,
240 
241  amrex::Print() << "ideal sounding init: surface dry air density = "
242  << std::setprecision(15)
243  << rhod_integ[0] << " kg/m^3" << std::endl;
244 
245  // Note:
246  // p_dry = rho_d R_d T
247  // p_tot = rho_m R_d T_v
248  // = rho_d(1 + q_v) R_d T_v
249 
250 #if 0 // Printing
251  // In this absence of moisture, this moist profile will match the
252  // following dry profile
253  amrex::Print() << "z p_m rho_d theta qv U V" << std::endl;
254  amrex::Print() << z_inp_sound[itime][0]
255  << " " << pm_integ[0]
256  << " " << rhod_integ[0]
257  << " " << theta_inp_sound[itime][0]
258  << " " << qv_inp_sound[itime][0]
259  << " " << U_inp_sound[itime][0]
260  << " " << V_inp_sound[itime][0]
261  << std::endl;
262 #endif
263 
264  // integrate from surface to domain top
265  amrex::Real dz, F, C;
266  amrex::Real T_hi;
267  amrex::Real rho_tot_hi, rho_tot_lo;
268  for (int k=1; k < size(itime); ++k)
269  {
270  // Vertical grid spacing
271  dz = z_inp_sound[itime][k] - z_inp_sound[itime][k-1];
272 
273  // Establish known constant
274  rho_tot_lo = rhod_integ[k-1] * (one + qv_inp_sound[itime][k-1]);
275  C = -pm_integ[k-1] + myhalf*rho_tot_lo*CONST_GRAV*dz;
276 
277  // Initial guess and residual
278  pm_integ[k] = pm_integ[k-1];
279  T_hi = getTgivenPandTh(pm_integ[k], theta_inp_sound[itime][k], RdoCp);
281  pm_integ[k],
282  RdoCp,
283  qv_inp_sound[itime][k]);
284  rho_tot_hi = rhod_integ[k] * (one + qv_inp_sound[itime][k]);
285  F = pm_integ[k] + myhalf*rho_tot_hi*CONST_GRAV*dz + C;
286 
287  // Do iterations
288  if (std::abs(F)>tol) {
289  bool maintain_Th = true;
291  CONST_GRAV, C, theta_inp_sound[itime][k], T_hi,
292  qv_inp_sound[itime][k], qv_inp_sound[itime][k],
293  pm_integ[k], rhod_integ[k], F, maintain_Th);
294  }
295 
296 #if 0 // Printing
297  amrex::Print() << z_inp_sound[itime][k]
298  << " " << pm_integ[k]
299  << " " << rhod_integ[k]
300  << " " << theta_inp_sound[itime][k]
301  << " " << qv_inp_sound[itime][k]
302  << " " << U_inp_sound[itime][k]
303  << " " << V_inp_sound[itime][k]
304  << std::endl;
305 #endif
306  }
307  // Note: at this point, the surface pressure, density of the dry air
308  // column is stored in pm_integ[0], rhod_integ[0]
309 
310  // update
311  host_to_device(itime);
312  }
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:64
constexpr amrex::Real RdoCp
Definition: ERF_Constants.H:54
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhogivenThetaPress(const amrex::Real th, const amrex::Real p, const amrex::Real rdOcp, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:96
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getTgivenPandTh(const amrex::Real P, const amrex::Real th, const amrex::Real rdOcp)
Definition: ERF_EOS.H:32
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void Newton_Raphson_hse(const Real &m_tol, const Real &RdoCp, const Real &dz, const Real &g, const Real &C, const Real &Th, const Real &T, const Real &qt, const Real &qv, Real &P, Real &rd, Real &F, const bool &maintain_Th)
Definition: ERF_HSEUtils.H:44
@ dz
Definition: ERF_AdvanceWSM6.cpp:104
void host_to_device(int itime)
Copy host sounding arrays for one time index to device storage.
Definition: ERF_InputSoundingData.H:403
amrex::Vector< amrex::Vector< amrex::Real > > V_inp_sound
Interpolated host y velocity profiles.
Definition: ERF_InputSoundingData.H:472
amrex::Vector< amrex::Real > pm_integ
Hydrostatically integrated moist pressure profile.
Definition: ERF_InputSoundingData.H:478
amrex::Real qv_ref_inp_sound
Surface reference water vapor mixing ratio read from the input sounding [kg/kg].
Definition: ERF_InputSoundingData.H:469
amrex::Vector< amrex::Vector< amrex::Real > > theta_inp_sound
Interpolated host potential temperature profiles [K].
Definition: ERF_InputSoundingData.H:472
amrex::Vector< amrex::Real > rhod_integ
Hydrostatically integrated dry density profile.
Definition: ERF_InputSoundingData.H:480
amrex::Vector< amrex::Vector< amrex::Real > > U_inp_sound
Interpolated host x velocity profiles.
Definition: ERF_InputSoundingData.H:472
amrex::Real theta_ref_inp_sound
Surface reference potential temperature read from the input sounding [K].
Definition: ERF_InputSoundingData.H:469
amrex::Vector< amrex::Vector< amrex::Real > > z_inp_sound
Interpolated host sounding heights for each sounding time [m].
Definition: ERF_InputSoundingData.H:472
amrex::Vector< amrex::Vector< amrex::Real > > qv_inp_sound
Interpolated host water vapor mixing ratio profiles [kg/kg].
Definition: ERF_InputSoundingData.H:472
amrex::Real press_ref_inp_sound
Surface reference pressure read from the input sounding [Pa].
Definition: ERF_InputSoundingData.H:469
int size(int itime) const
Return the number of interpolated samples for one sounding time.
Definition: ERF_InputSoundingData.H:447
Here is the call graph for this function:

◆ calc_rho_p_isentropic()

void InputSoundingData::calc_rho_p_isentropic ( int  itime)
inline

Compute density and pressure for an isentropic sounding profile.

Parameters
itimeSounding time/file index to integrate.
319  {
320  /* Calculate density and pressure assuming isentropic (constant theta)
321  background conditions. This does not use Newton-Raphson iterations
322  to calculate rho and p.
323  */
324  const int Ninp = size(itime);
325  pm_integ.resize(Ninp);
326  rhod_integ.resize(Ninp);
327 
328  // evaluate surface quantities (k=0): total pressure and dry air
332  RdoCp,
334 
335  const amrex::Real th0 = theta_ref_inp_sound;
336  const amrex::Real p0_pow = std::pow(p_0, (Gamma-1)/Gamma);
337 
338  amrex::Print() << "isentropic sounding init: surface dry air density = "
339  << std::setprecision(15)
340  << rhod_integ[0] << " kg/m^3" << std::endl;
341 
342 #if 0 // Printing
343  // In this absence of moisture, this moist profile will match the
344  // following dry profile
345  amrex::Print() << "z p_m rho_d theta qv U V" << std::endl;
346  amrex::Print() << z_inp_sound[itime][0]
347  << " " << pm_integ[0]
348  << " " << rhod_integ[0]
349  << " " << theta_inp_sound[itime][0]
350  << " " << qv_inp_sound[itime][0]
351  << " " << U_inp_sound[itime][0]
352  << " " << V_inp_sound[itime][0]
353  << std::endl;
354 #endif
355 
356  // integrate from surface to domain top
357  amrex::Real dz;
358  for (int k=1; k < size(itime); ++k)
359  {
360  // Vertical grid spacing
361  dz = z_inp_sound[itime][k] - z_inp_sound[itime][k-1];
362 
363  // Isentropic pressure at next level
364  amrex::Real qvmean = (assume_dry) ? zero : myhalf*(qv_inp_sound[itime][k-1] + qv_inp_sound[itime][k]);
365  amrex::Real thm0 = th0 * (one + RvoRd * qvmean);
366  amrex::Real plo_pow = std::pow(pm_integ[k-1], (Gamma-1)/Gamma);
367  pm_integ[k] = (Gamma-1)/Gamma *
368  (-CONST_GRAV * p0_pow / (R_d * thm0) * (1 + qvmean) * dz
369  + Gamma/(Gamma-1) * plo_pow);
370  pm_integ[k] = std::pow(pm_integ[k], Gamma / (Gamma-1));
371 
372  // Note: The pressure calculated here is copied to `p_inp_sound_d`
373  // and currently not used.
374 
375  // Get corresponding dry air density
377  pm_integ[k],
378  RdoCp,
379  qv_inp_sound[itime][k]);
380 
381 #if 0 // Printing
382  amrex::Print() << z_inp_sound[itime][k]
383  << " " << pm_integ[k]
384  << " " << rhod_integ[k]
385  << " " << theta_inp_sound[itime][k]
386  << " " << qv_inp_sound[itime][k]
387  << " " << U_inp_sound[itime][k]
388  << " " << V_inp_sound[itime][k]
389  << std::endl;
390 #endif
391  }
392  // Note: at this point, the surface pressure, density of the dry air
393  // column is stored in pm_integ[0], rhod_integ[0]
394 
395  // update
396  host_to_device(itime);
397  }
constexpr amrex::Real p_0
Definition: ERF_Constants.H:61
constexpr amrex::Real RvoRd
Definition: ERF_Constants.H:56
constexpr amrex::Real R_d
Definition: ERF_Constants.H:47
constexpr amrex::Real Gamma
Definition: ERF_Constants.H:62
bool assume_dry
Whether to ignore moisture in isentropic pressure integration.
Definition: ERF_InputSoundingData.H:466
Here is the call graph for this function:

◆ host_to_device()

void InputSoundingData::host_to_device ( int  itime)
inline

Copy host sounding arrays for one time index to device storage.

Parameters
itimeSounding time/file index to copy.
404  {
405  const int Ninp = size(itime);
406  z_inp_sound_d[itime].resize(Ninp);
407  theta_inp_sound_d[itime].resize(Ninp);
408  qv_inp_sound_d[itime].resize(Ninp);
409  U_inp_sound_d[itime].resize(Ninp);
410  V_inp_sound_d[itime].resize(Ninp);
411 
412  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
413  z_inp_sound[itime].begin(), z_inp_sound[itime].end(),
414  z_inp_sound_d[itime].begin());
415  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
416  theta_inp_sound[itime].begin(), theta_inp_sound[itime].end(),
417  theta_inp_sound_d[itime].begin());
418  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
419  qv_inp_sound[itime].begin(), qv_inp_sound[itime].end(),
420  qv_inp_sound_d[itime].begin());
421  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
422  U_inp_sound[itime].begin(), U_inp_sound[itime].end(),
423  U_inp_sound_d[itime].begin());
424  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
425  V_inp_sound[itime].begin(), V_inp_sound[itime].end(),
426  V_inp_sound_d[itime].begin());
427 
428  if (rhod_integ.size() > 0)
429  {
430  //amrex::Print() << "Copying rho_d, p_d to device" << std::endl;
431  rho_inp_sound_d.resize(size(itime)+2);
432  p_inp_sound_d.resize(size(itime)+2);
433  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
434  rhod_integ.begin(), rhod_integ.end(),
435  rho_inp_sound_d.begin());
436  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
437  pm_integ.begin(), pm_integ.end(),
438  p_inp_sound_d.begin());
439  }
440  }
amrex::Gpu::DeviceVector< amrex::Real > rho_inp_sound_d
Device density profile used to initialize solution fields.
Definition: ERF_InputSoundingData.H:482
amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real > > qv_inp_sound_d
Device water vapor mixing ratio profiles [kg/kg].
Definition: ERF_InputSoundingData.H:475
amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real > > V_inp_sound_d
Device y velocity profiles.
Definition: ERF_InputSoundingData.H:475
amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real > > z_inp_sound_d
Device sounding heights for each sounding time [m].
Definition: ERF_InputSoundingData.H:475
amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real > > theta_inp_sound_d
Device potential temperature profiles [K].
Definition: ERF_InputSoundingData.H:475
amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real > > U_inp_sound_d
Device x velocity profiles.
Definition: ERF_InputSoundingData.H:475
amrex::Gpu::DeviceVector< amrex::Real > p_inp_sound_d
Device pressure profile used to initialize solution fields.
Definition: ERF_InputSoundingData.H:482

Referenced by calc_rho_p(), calc_rho_p_isentropic(), and read_from_file().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_from_file()

void InputSoundingData::read_from_file ( const amrex::Geometry &  geom,
const amrex::Vector< amrex::Real > &  zlevels_stag,
int  itime,
bool  is_moist 
)
inline

Read and interpolate one input sounding profile onto level-0 heights.

Parameters
geomGeometry defining the level-0 vertical domain.
zlevels_stagStaggered vertical coordinates used for interpolation.
itimeSounding time/file index to read.
is_moistWhether the selected physics permits nonzero water vapor.
93  {
94  const int klo = 0;
95  const int khi = geom.Domain().bigEnd()[AMREX_SPACEDIM-1];
96  const int Nz = geom.Domain().size()[AMREX_SPACEDIM-1];
97 
98  const amrex::Real zbot = zlevels_stag[klo];
99  const amrex::Real ztop = zlevels_stag[khi+1];
100 
101  z_inp_sound[itime].resize(Nz+2);
102  theta_inp_sound[itime].resize(Nz+2);
103  qv_inp_sound[itime].resize(Nz+2);
104  U_inp_sound[itime].resize(Nz+2);
105  V_inp_sound[itime].resize(Nz+2);
106 
107  // Read the input_sounding file
108  amrex::Print() << "input_sounding file location : " << input_sounding_file[itime] << std::endl;
109  std::ifstream input_sounding_reader(input_sounding_file[itime]);
110  if(!input_sounding_reader.is_open()) {
111  amrex::Error("Error opening the input_sounding file\n");
112  }
113  else {
114  // Read the contents of the input_sounding file
115  amrex::Print() << "Successfully opened the input_sounding file. Now reading... " << std::endl;
116  std::string line;
117 
118  // First, read the input data into temp vectors; then, interpolate vectors to the
119  // domain lo/hi and cell centers (from level 0)
120  amrex::Vector<amrex::Real> z_inp_sound_tmp, theta_inp_sound_tmp, qv_inp_sound_tmp,
121  U_inp_sound_tmp, V_inp_sound_tmp;
122 
123  // Read surface quantities from the first line
124  std::getline(input_sounding_reader, line);
125  std::istringstream iss(line);
127  press_ref_inp_sound *= 100; // convert from hPa to Pa
128  qv_ref_inp_sound *= amrex::Real(0.001); // convert from g/kg to kg/kg
129 
130  // Add surface
131  z_inp_sound_tmp.push_back(zbot); // height above sea level [m]
132  theta_inp_sound_tmp.push_back(theta_ref_inp_sound);
133  qv_inp_sound_tmp.push_back(qv_ref_inp_sound);
134  U_inp_sound_tmp.push_back(0);
135  V_inp_sound_tmp.push_back(0);
136 
137  // *************************************************************************************************
138  // Make sure that if we specify surface values for temp in the inputs file and in the input sounding file,
139  // those values must match
140  // *************************************************************************************************
141  amrex::ParmParse pp_erf("erf");
142 
143  amrex::Real surf_temp;
144  bool surf_temp_specified = pp_erf.query("most.surf_temp", surf_temp);
145  if ( surf_temp_specified && (surf_temp != theta_inp_sound_tmp[0]) ) {
146  amrex::Print() << "Input sounding temp does not match most.surf_temp" << std::endl;
147  amrex::Print() << "Modify one or both to match." << std::endl;
148  amrex::Abort();
149  }
150 
151  // *************************************************************************************************
152  // Make sure that if we specify surface values for qv in the inputs file and in the input sounding file,
153  // those values must match
154  // *************************************************************************************************
155  amrex::Real surf_moist;
156  bool surf_moist_specified = pp_erf.query("most.surf_moist", surf_moist);
157  if ( surf_moist_specified && (surf_moist != qv_inp_sound_tmp[0]) ) {
158  amrex::Print() << "Input sounding qv does not match most.surf_moist" << std::endl;
159  amrex::Print() << "Modify one or both to match." << std::endl;
160  amrex::Abort();
161  }
162 
163  // Read the vertical profile at each given height
164  amrex::Real z, theta, qv, U, V;
165 
166  while(std::getline(input_sounding_reader, line)) {
167  std::istringstream iss_z(line);
168  iss_z >> z >> theta >> qv >> U >> V;
169 
170  // Dont read in non-zero qv if not using a moisture model
171  AMREX_ALWAYS_ASSERT(qv == zero || is_moist);
172 
173  if (z == zbot) {
174  AMREX_ALWAYS_ASSERT(theta == theta_inp_sound_tmp[0]);
175  AMREX_ALWAYS_ASSERT(qv*amrex::Real(0.001) == qv_inp_sound_tmp[0]); // convert from g/kg to kg/kg
176  U_inp_sound_tmp[0] = U;
177  V_inp_sound_tmp[0] = V;
178  } else {
179  AMREX_ALWAYS_ASSERT(z > z_inp_sound_tmp[z_inp_sound_tmp.size()-1]); // sounding is increasing in height
180  z_inp_sound_tmp.push_back(z);
181 
182  theta_inp_sound_tmp.push_back(theta);
183  qv_inp_sound_tmp.push_back(qv*amrex::Real(0.001)); // convert from g/kg to kg/kg
184  U_inp_sound_tmp.push_back(U);
185  V_inp_sound_tmp.push_back(V);
186  if (z >= ztop) break;
187  }
188  }
189 
190  // At this point, we have an input_sounding from zbot up to
191  // z_inp_sound_tmp[N-1] >= ztop. Now, interpolate to grid level 0 heights
192  const int Ninp = z_inp_sound_tmp.size();
193  z_inp_sound[itime][0] = zbot;
194  theta_inp_sound[itime][0] = theta_inp_sound_tmp[0];
195  qv_inp_sound[itime][0] = qv_inp_sound_tmp[0];
196  U_inp_sound[itime][0] = U_inp_sound_tmp[0];
197  V_inp_sound[itime][0] = V_inp_sound_tmp[0];
198  for (int k=0; k < Nz; ++k) {
199  z_inp_sound[itime][k+1] = myhalf * (zlevels_stag[k] + zlevels_stag[k+1]);
200  theta_inp_sound[itime][k+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), theta_inp_sound_tmp.dataPtr(), z_inp_sound[itime][k+1], Ninp);
201  qv_inp_sound[itime][k+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), qv_inp_sound_tmp.dataPtr(), z_inp_sound[itime][k+1], Ninp);
202  U_inp_sound[itime][k+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), U_inp_sound_tmp.dataPtr(), z_inp_sound[itime][k+1], Ninp);
203  V_inp_sound[itime][k+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), V_inp_sound_tmp.dataPtr(), z_inp_sound[itime][k+1], Ninp);
204  }
205  z_inp_sound[itime][Nz+1] = ztop;
206  theta_inp_sound[itime][Nz+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), theta_inp_sound_tmp.dataPtr(), ztop, Ninp);
207  qv_inp_sound[itime][Nz+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), qv_inp_sound_tmp.dataPtr(), ztop, Ninp);
208  U_inp_sound[itime][Nz+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), U_inp_sound_tmp.dataPtr(), ztop, Ninp);
209  V_inp_sound[itime][Nz+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), V_inp_sound_tmp.dataPtr(), ztop, Ninp);
210  }
211 
212  amrex::Print() << "Successfully read the " << itime << "th input_sounding file..." << std::endl;
213  input_sounding_reader.close();
214 
215  host_to_device(itime);
216  }
const Real ztop
Definition: ERF_InitCustomPertVels_ParticleTests.H:4
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
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
@ theta
Definition: ERF_SLM.H:20
@ qv
Definition: ERF_Kessler.H:30
@ U
Definition: ERF_IndexDefines.H:123
@ V
Definition: ERF_IndexDefines.H:124
Here is the call graph for this function:

◆ resize_arrays()

void InputSoundingData::resize_arrays ( )
inline

Resize host and device sounding arrays for the configured sounding times.

67  {
69 
70  z_inp_sound.resize(ntimes);
71  theta_inp_sound.resize(ntimes);
72  qv_inp_sound.resize(ntimes);
73  U_inp_sound.resize(ntimes);
74  V_inp_sound.resize(ntimes);
75 
76  z_inp_sound_d.resize(ntimes);
77  theta_inp_sound_d.resize(ntimes);
78  qv_inp_sound_d.resize(ntimes);
79  U_inp_sound_d.resize(ntimes);
80  V_inp_sound_d.resize(ntimes);
81  }
int ntimes
Number of sounding times represented in the arrays.
Definition: ERF_InputSoundingData.H:457

◆ size()

int InputSoundingData::size ( int  itime) const
inline

Return the number of interpolated samples for one sounding time.

Parameters
itimeSounding time/file index to query.
Returns
Number of stored sounding profile levels.
448  {
450  AMREX_ALWAYS_ASSERT(z_inp_sound[itime].size() == qv_inp_sound[itime].size());
451  AMREX_ALWAYS_ASSERT(z_inp_sound[itime].size() == U_inp_sound[itime].size());
452  AMREX_ALWAYS_ASSERT(z_inp_sound[itime].size() == V_inp_sound[itime].size());
453  return z_inp_sound[itime].size();
454  }

Referenced by calc_rho_p(), calc_rho_p_isentropic(), host_to_device(), init_state_from_input_sounding(), init_state_from_input_sounding_hse(), and init_velocities_from_input_sounding().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ assume_dry

InputSoundingData::assume_dry {false}

Whether to ignore moisture in isentropic pressure integration.

Referenced by calc_rho_p_isentropic(), and init_state_from_input_sounding_hse().

◆ input_sounding_file

InputSoundingData::input_sounding_file = {}

Sounding file path for each configured sounding time.

Referenced by InputSoundingData(), and read_from_file().

◆ input_sounding_time

InputSoundingData::input_sounding_time = {}

Physical time associated with each input sounding file.

Referenced by InputSoundingData(), make_mom_sources(), and make_sources().

◆ n_sounding_files

InputSoundingData::n_sounding_files = 0

Number of input sounding files.

Referenced by InputSoundingData(), and resize_arrays().

◆ n_sounding_times

InputSoundingData::n_sounding_times = 0

Number of input sounding times.

Referenced by InputSoundingData().

◆ ntimes

InputSoundingData::ntimes

Number of sounding times represented in the arrays.

Referenced by resize_arrays().

◆ p_inp_sound_d

InputSoundingData::p_inp_sound_d

Device pressure profile used to initialize solution fields.

Referenced by host_to_device().

◆ pm_integ

InputSoundingData::pm_integ

Hydrostatically integrated moist pressure profile.

Referenced by calc_rho_p(), calc_rho_p_isentropic(), and host_to_device().

◆ press_ref_inp_sound

InputSoundingData::press_ref_inp_sound

Surface reference pressure read from the input sounding [Pa].

Referenced by calc_rho_p(), calc_rho_p_isentropic(), and read_from_file().

◆ qv_inp_sound

InputSoundingData::qv_inp_sound

Interpolated host water vapor mixing ratio profiles [kg/kg].

Referenced by calc_rho_p(), calc_rho_p_isentropic(), host_to_device(), read_from_file(), resize_arrays(), and size().

◆ qv_inp_sound_d

InputSoundingData::qv_inp_sound_d

Device water vapor mixing ratio profiles [kg/kg].

Referenced by host_to_device(), init_state_from_input_sounding(), init_state_from_input_sounding_hse(), and resize_arrays().

◆ qv_ref_inp_sound

InputSoundingData::qv_ref_inp_sound

Surface reference water vapor mixing ratio read from the input sounding [kg/kg].

Referenced by calc_rho_p(), calc_rho_p_isentropic(), and read_from_file().

◆ rho_inp_sound_d

InputSoundingData::rho_inp_sound_d

Device density profile used to initialize solution fields.

Referenced by host_to_device(), and init_state_from_input_sounding_hse().

◆ rhod_integ

InputSoundingData::rhod_integ

Hydrostatically integrated dry density profile.

Referenced by calc_rho_p(), calc_rho_p_isentropic(), and host_to_device().

◆ tau_nudging

InputSoundingData::tau_nudging = amrex::Real(5.0)

Nudging time scale for relaxing toward input sounding data.

Referenced by InputSoundingData(), make_mom_sources(), and make_sources().

◆ theta_inp_sound

InputSoundingData::theta_inp_sound

Interpolated host potential temperature profiles [K].

Referenced by calc_rho_p(), calc_rho_p_isentropic(), host_to_device(), read_from_file(), resize_arrays(), and size().

◆ theta_inp_sound_d

InputSoundingData::theta_inp_sound_d

◆ theta_ref_inp_sound

InputSoundingData::theta_ref_inp_sound

Surface reference potential temperature read from the input sounding [K].

Referenced by calc_rho_p(), calc_rho_p_isentropic(), and read_from_file().

◆ U_inp_sound

InputSoundingData::U_inp_sound

Interpolated host x velocity profiles.

Referenced by calc_rho_p(), calc_rho_p_isentropic(), host_to_device(), read_from_file(), resize_arrays(), and size().

◆ U_inp_sound_d

InputSoundingData::U_inp_sound_d

◆ V_inp_sound

InputSoundingData::V_inp_sound

Interpolated host y velocity profiles.

Referenced by calc_rho_p(), calc_rho_p_isentropic(), host_to_device(), read_from_file(), resize_arrays(), and size().

◆ V_inp_sound_d

InputSoundingData::V_inp_sound_d

◆ z_inp_sound

InputSoundingData::z_inp_sound

Interpolated host sounding heights for each sounding time [m].

Referenced by calc_rho_p(), calc_rho_p_isentropic(), host_to_device(), read_from_file(), resize_arrays(), and size().

◆ z_inp_sound_d

InputSoundingData::z_inp_sound_d

The documentation for this struct was generated from the following file: