ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_InitFromInputSounding.cpp File Reference
#include <ERF.H>
#include <ERF_EOS.H>
#include <ERF_Constants.H>
#include <ERF_Utils.H>
#include <ERF_ProbCommon.H>
Include dependency graph for ERF_InitFromInputSounding.cpp:

Functions

void init_state_from_input_sounding (const Box &bx, Array4< Real > const &state, GeometryData const &geomdata, Array4< const Real > const &z_cc_arr, const bool &l_moist, InputSoundingData const &inputSoundingData)
 
void init_state_from_input_sounding_hse (const Box &bx, Array4< Real > const &state, Array4< Real > const &r_hse_arr, Array4< Real > const &p_hse_arr, Array4< Real > const &pi_hse_arr, Array4< Real > const &th_hse_arr, Array4< Real > const &qv_hse_arr, GeometryData const &geomdata, Array4< const Real > const &z_cc_arr, const Real &l_gravity, const Real &l_rdOcp, const bool &l_moist, InputSoundingData const &inputSoundingData, const bool &l_isentropic, const int &ngz)
 
void init_velocities_from_input_sounding (const Box &bx, Array4< Real > const &x_vel, Array4< Real > const &y_vel, Array4< Real > const &z_vel, GeometryData const &geomdata, Array4< const Real > const &z_nd_arr, InputSoundingData const &inputSoundingData)
 

Function Documentation

◆ init_state_from_input_sounding()

void init_state_from_input_sounding ( const Box &  bx,
Array4< Real > const &  state,
GeometryData const &  geomdata,
Array4< const Real > const &  z_cc_arr,
const bool &  l_moist,
InputSoundingData const &  inputSoundingData 
)

Box level wrapper for initializing scalar data from input sounding data.

Parameters
bxBox specifying the indices we are initializing
stateArray4 specifying the state data we are to initialize
geomdataGeometryData object specifying the domain geometry
inputSoundingDataInputSoundingData object we are to initialize from
225 {
226  const Real* z_inp_sound = inputSoundingData.z_inp_sound_d[0].dataPtr();
227  const Real* theta_inp_sound = inputSoundingData.theta_inp_sound_d[0].dataPtr();
228  const Real* qv_inp_sound = inputSoundingData.qv_inp_sound_d[0].dataPtr();
229  const int inp_sound_size = inputSoundingData.size(0);
230 
231  // Geometry
232  const Real* prob_lo = geomdata.ProbLo();
233  const Real* dx = geomdata.CellSize();
234  const Real z_lo = prob_lo[2];
235  const Real dz = dx[2];
236 
237  // We want to set the lateral BC values, too
238  Box gbx = bx; // Copy constructor
239  gbx.grow(0,1); gbx.grow(1,1); // Grow by one in the lateral directions
240 
241  ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
242  const Real z = (z_cc_arr) ? z_cc_arr(i,j,k) : z_lo + (k + myhalf) * dz;
243 
244  Real rho_0 = one;
245 
246  // Set the density
247  state(i, j, k, Rho_comp) = rho_0;
248 
249  // Initial Rho0*Theta0
250  state(i, j, k, RhoTheta_comp) = rho_0 * interpolate_1d(z_inp_sound, theta_inp_sound, z, inp_sound_size);
251 
252  // total nonprecipitating water (Q1) == water vapor (Qv), i.e., there is no cloud water or cloud ice
253  if (l_moist) {
254  state(i, j, k, RhoQ1_comp) = rho_0 * interpolate_1d(z_inp_sound, qv_inp_sound, z, inp_sound_size);
255  }
256  });
257 }
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
Real rho_0
Definition: ERF_InitCustomPert_ABL.H:4
const Real dx
Definition: ERF_InitCustomPert_ABL.H:23
const amrex::Real * prob_lo
Definition: ERF_InitCustomPert_DataAssimilation_ISV.H:16
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
ParallelFor(grown_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);})
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ dz
Definition: ERF_AdvanceWSM6.cpp:104

Referenced by ERF::init_from_input_sounding().

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

◆ init_state_from_input_sounding_hse()

void init_state_from_input_sounding_hse ( const Box &  bx,
Array4< Real > const &  state,
Array4< Real > const &  r_hse_arr,
Array4< Real > const &  p_hse_arr,
Array4< Real > const &  pi_hse_arr,
Array4< Real > const &  th_hse_arr,
Array4< Real > const &  qv_hse_arr,
GeometryData const &  geomdata,
Array4< const Real > const &  z_cc_arr,
const Real ,
const Real l_rdOcp,
const bool &  l_moist,
InputSoundingData const &  inputSoundingData,
const bool &  l_isentropic,
const int &  ngz 
)

Box level wrapper for initializing scalar and hydrostatic base state data from input sounding data.

Parameters
bxBox specifying the indices we are initializing
stateArray4 specifying the state data we are to initialize
r_hse_arrArray4 specifying the density HSE base state data we are to initialize
p_hse_arrArray4 specifying the pressure HSE base state data we are to initialize
pi_hse_arrArray4 specifying the Exner pressure HSE base state data we are to initialize
th_hse_arrArray4 specifying the base state potential temperature we are to initialize
geomdataGeometryData object specifying the domain geometry
l_gravityReal number specifying the gravitational acceleration constant
l_rdOcpReal number specifying the Rhydberg constant ($R_d$) divided by specific heat at constant pressure ($c_p$)
inputSoundingDataInputSoundingData object we are to initialize from
290 {
291  const Real* z_inp_sound = inputSoundingData.z_inp_sound_d[0].dataPtr();
292  const Real* rho_inp_sound = inputSoundingData.rho_inp_sound_d.dataPtr();
293  const Real* theta_inp_sound = inputSoundingData.theta_inp_sound_d[0].dataPtr();
294  const Real* qv_inp_sound = inputSoundingData.qv_inp_sound_d[0].dataPtr();
295  const int inp_sound_size = inputSoundingData.size(0);
296  const bool anel_assume_dry = inputSoundingData.assume_dry;
297 
298  // Geometry
299  const Real* prob_lo = geomdata.ProbLo();
300  const Real* dx = geomdata.CellSize();
301  const Real z_lo = prob_lo[2];
302  const Real dz = dx[2];
303 
304  int kbot = geomdata.Domain().smallEnd(2);
305  int ktop = geomdata.Domain().bigEnd(2);
306 
307  // We want to set the lateral BC values, too
308  Box gbx = bx; // Copy constructor
309  gbx.grow(0,1); gbx.grow(1,1); // Grow by one in the lateral directions
310 
311  ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
312  const Real z = (z_cc_arr) ? z_cc_arr(i,j,k)
313  : z_lo + (k + myhalf) * dz;
314 
315  Real rho_k = interpolate_1d(z_inp_sound, rho_inp_sound, z, inp_sound_size);
316  Real rhoTh_k = rho_k * interpolate_1d(z_inp_sound, theta_inp_sound, z, inp_sound_size);
317 
318  Real rho_k_base = rho_k;
319  if (l_isentropic) {
320  // `rho_inp_sound` previously calculated in calc_rho_p_isentropic()
321  // is in HSE and, when multiplied by the specified
322  // `theta_input_sound`, give p, T, and theta that are consistent
323  // with each other.
324  //
325  // Here, we do not require thermodynamic consistency between the
326  // initial base state rho and the prognostic variables. Instead,
327  // we calculate a `rho_hse` that is consistent with the isentropic
328  // (constant theta) assumption.
329  rho_k_base = rhoTh_k / theta_inp_sound[0];
330  }
331 
332  // Set the density
333  state(i, j, k, Rho_comp) = rho_k;
334 
335  // Initial Rho0*Theta0
336  state(i, j, k, RhoTheta_comp) = rhoTh_k;
337 
338  // Total nonprecipitating water (Q1) == water vapor (Qv), i.e., there
339  // is no cloud water or cloud ice
340  Real qv_k = zero;
341  if (l_moist) {
342  qv_k = interpolate_1d(z_inp_sound, qv_inp_sound, z, inp_sound_size);
343  state(i, j, k, RhoQ1_comp) = rho_k * qv_k;
344  }
345 
346  // Update hse quantities with values calculated from InputSoundingData.calc_rho_p()
347  if (anel_assume_dry) qv_k = 0;
348  r_hse_arr (i,j,k) = rho_k_base;
349  p_hse_arr (i,j,k) = getPgivenRTh(rhoTh_k, qv_k);
350  pi_hse_arr(i,j,k) = getExnergivenRTh(rhoTh_k, l_rdOcp, qv_k);
351  th_hse_arr(i,j,k) = getRhoThetagivenP(p_hse_arr(i,j,k), qv_k) / rho_k_base;
352  qv_hse_arr(i,j,k) = qv_k;
353 
354  if (l_isentropic) {
355 #if 0
356  if (i==0 && j==0) {
357  Print() << "HSE rho,p,T=pi*th,th at " << IntVect(i,j,k) << " : "
358  << r_hse_arr(i,j,k) << " "
359  << p_hse_arr(i,j,k) << " "
360  << pi_hse_arr(i,j,k)*th_hse_arr(i,j,k) << " "
361  << th_hse_arr(i,j,k)
362  << " with rho,rhotheta=" << rho_k << " " << rhoTh_k
363  << std::endl;
364  }
365 #endif
366  // If everything above is thermodynamically consistent, this should be constant
367  AMREX_ALWAYS_ASSERT(std::abs(th_hse_arr(i,j,k) - theta_inp_sound[0]) < 1e-12);
368  }
369 
370  // FOEXTRAP hse arrays
371  if (k==kbot)
372  {
373  for (int kk = 1; kk <= ngz; kk++) {
374  r_hse_arr(i, j, k-kk) = r_hse_arr(i,j,k);
375  p_hse_arr(i, j, k-kk) = p_hse_arr(i,j,k);
376  pi_hse_arr(i, j, k-kk) = pi_hse_arr(i,j,k);
377  th_hse_arr(i, j, k-kk) = th_hse_arr(i,j,k);
378  qv_hse_arr(i, j, k-kk) = qv_hse_arr(i,j,k);
379  }
380  }
381  else if (k==ktop)
382  {
383  for (int kk = 1; kk <= ngz; kk++) {
384  r_hse_arr(i, j, k+kk) = r_hse_arr(i,j,k);
385  p_hse_arr(i, j, k+kk) = p_hse_arr(i,j,k);
386  pi_hse_arr(i, j, k+kk) = pi_hse_arr(i,j,k);
387  th_hse_arr(i, j, k+kk) = th_hse_arr(i,j,k);
388  qv_hse_arr(i, j, k+kk) = qv_hse_arr(i,j,k);
389  }
390  }
391  });
392 }
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhoThetagivenP(const amrex::Real p, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:172
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenRTh(const amrex::Real rhotheta, const amrex::Real rdOcp, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:156
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:81
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)

Referenced by ERF::init_from_input_sounding().

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

◆ init_velocities_from_input_sounding()

void init_velocities_from_input_sounding ( const Box &  bx,
Array4< Real > const &  x_vel,
Array4< Real > const &  y_vel,
Array4< Real > const &  z_vel,
GeometryData const &  geomdata,
Array4< const Real > const &  z_nd_arr,
InputSoundingData const &  inputSoundingData 
)

Box level wrapper for initializing velocities from input sounding data.

Parameters
bxBox specifying the indices we are initializing
x_velArray4 specifying the x-velocity data we are to initialize
y_velArray4 specifying the y-velocity data we are to initialize
z_velArray4 specifying the z-velocity data we are to initialize
geomdataGeometryData object specifying the domain geometry
inputSoundingDataInputSoundingData object we are to initialize from
412 {
413  const Real* z_inp_sound = inputSoundingData.z_inp_sound_d[0].dataPtr();
414  const Real* U_inp_sound = inputSoundingData.U_inp_sound_d[0].dataPtr();
415  const Real* V_inp_sound = inputSoundingData.V_inp_sound_d[0].dataPtr();
416  const int inp_sound_size = inputSoundingData.size(0);
417 
418  // Geometry
419  const Real* prob_lo = geomdata.ProbLo();
420  const Real* dx = geomdata.CellSize();
421  const Real z_lo = prob_lo[2];
422  const Real dz = dx[2];
423 
424  // We want to set the lateral BC values, too
425  Box gbx = bx; // Copy constructor
426  gbx.grow(0,1); gbx.grow(1,1); // Grow by one in the lateral directions
427 
428  // Construct a box that is on x-faces
429  const Box& xbx = surroundingNodes(gbx,0);
430  // Construct a box that is on y-faces
431  const Box& ybx = surroundingNodes(gbx,1);
432  // Construct a box that is on z-faces
433  const Box& zbx = surroundingNodes(gbx,2);
434 
435  // Set the x,y,z-velocities
437  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
438  // Note that this is called on a box of x-faces
439  const Real z = (z_nd_arr) ? fourth*( z_nd_arr(i,j ,k )
440  + z_nd_arr(i,j+1,k )
441  + z_nd_arr(i,j ,k+1)
442  + z_nd_arr(i,j+1,k+1))
443  : z_lo + (k + myhalf) * dz;
444 
445  // Set the x-velocity
446  x_vel(i, j, k) = interpolate_1d(z_inp_sound, U_inp_sound, z, inp_sound_size);
447  },
448  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
449  // Note that this is called on a box of y-faces
450  const Real z = (z_nd_arr) ? fourth*( z_nd_arr(i ,j,k )
451  + z_nd_arr(i+1,j,k )
452  + z_nd_arr(i ,j,k+1)
453  + z_nd_arr(i+1,j,k+1))
454  : z_lo + (k + myhalf) * dz;
455 
456  // Set the y-velocity
457  y_vel(i, j, k) = interpolate_1d(z_inp_sound, V_inp_sound, z, inp_sound_size);
458  },
459  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
460  // Note that this is called on a box of z-faces
461  // Set the z-velocity
462  z_vel(i, j, k) = zero;
463  });
464 }
constexpr amrex::Real fourth
Definition: ERF_Constants.H:14
const Box zbx
Definition: ERF_SetupDiff.H:9
const Box xbx
Definition: ERF_SetupDiff.H:7
const Box ybx
Definition: ERF_SetupDiff.H:8

Referenced by ERF::init_from_input_sounding().

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