ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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_bx_scalars_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_bx_scalars_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)
 
void init_bx_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_bx_scalars_from_input_sounding()

void init_bx_scalars_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
169 {
170  const Real* z_inp_sound = inputSoundingData.z_inp_sound_d[0].dataPtr();
171  const Real* theta_inp_sound = inputSoundingData.theta_inp_sound_d[0].dataPtr();
172  const Real* qv_inp_sound = inputSoundingData.qv_inp_sound_d[0].dataPtr();
173  const int inp_sound_size = inputSoundingData.size(0);
174 
175  // Geometry
176  const Real* prob_lo = geomdata.ProbLo();
177  const Real* dx = geomdata.CellSize();
178  const Real z_lo = prob_lo[2];
179  const Real dz = dx[2];
180 
181  // We want to set the lateral BC values, too
182  Box gbx = bx; // Copy constructor
183  gbx.grow(0,1); gbx.grow(1,1); // Grow by one in the lateral directions
184 
185  ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
186  const Real z = (z_cc_arr) ? z_cc_arr(i,j,k)
187  : z_lo + (k + 0.5) * dz;
188 
189  Real rho_0 = 1.0;
190 
191  // Set the density
192  state(i, j, k, Rho_comp) = rho_0;
193 
194  // Initial Rho0*Theta0
195  state(i, j, k, RhoTheta_comp) = rho_0 * interpolate_1d(z_inp_sound, theta_inp_sound, z, inp_sound_size);
196 
197  // Initialize all scalars to 0.
198  for (int n = 0; n < NSCALARS; n++) {
199  state(i, j, k, RhoScalar_comp+n) = 0;
200  }
201 
202  // total nonprecipitating water (Q1) == water vapor (Qv), i.e., there is no cloud water or cloud ice
203  if (l_moist) {
204  state(i, j, k, RhoQ1_comp) = rho_0 * interpolate_1d(z_inp_sound, qv_inp_sound, z, inp_sound_size);
205  }
206  });
207 }
#define RhoScalar_comp
Definition: ERF_IndexDefines.H:40
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define NSCALARS
Definition: ERF_IndexDefines.H:16
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
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:12

Referenced by ERF::init_from_input_sounding().

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

◆ init_bx_scalars_from_input_sounding_hse()

void init_bx_scalars_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 
)

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
238 {
239  const Real* z_inp_sound = inputSoundingData.z_inp_sound_d[0].dataPtr();
240  const Real* rho_inp_sound = inputSoundingData.rho_inp_sound_d.dataPtr();
241  const Real* theta_inp_sound = inputSoundingData.theta_inp_sound_d[0].dataPtr();
242  const Real* qv_inp_sound = inputSoundingData.qv_inp_sound_d[0].dataPtr();
243  const int inp_sound_size = inputSoundingData.size(0);
244 
245  // Geometry
246  const Real* prob_lo = geomdata.ProbLo();
247  const Real* dx = geomdata.CellSize();
248  const Real z_lo = prob_lo[2];
249  const Real dz = dx[2];
250 
251  int kbot = geomdata.Domain().smallEnd(2);
252  int ktop = geomdata.Domain().bigEnd(2);
253 
254  // We want to set the lateral BC values, too
255  Box gbx = bx; // Copy constructor
256  gbx.grow(0,1); gbx.grow(1,1); // Grow by one in the lateral directions
257 
258  ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
259  const Real z = (z_cc_arr) ? z_cc_arr(i,j,k)
260  : z_lo + (k + 0.5) * dz;
261 
262  Real rho_k, qv_k, rhoTh_k;
263 
264  // Set the density
265  rho_k = interpolate_1d(z_inp_sound, rho_inp_sound, z, inp_sound_size);
266  state(i, j, k, Rho_comp) = rho_k;
267 
268  // Initial Rho0*Theta0
269  rhoTh_k = rho_k * interpolate_1d(z_inp_sound, theta_inp_sound, z, inp_sound_size);
270  state(i, j, k, RhoTheta_comp) = rhoTh_k;
271 
272  // Initialize all scalars to 0.
273  for (int n = 0; n < NSCALARS; n++) {
274  state(i, j, k, RhoScalar_comp+n) = 0;
275  }
276 
277  // Update hse quantities with values calculated from InputSoundingData.calc_rho_p()
278  qv_k = (l_moist) ? interpolate_1d(z_inp_sound, qv_inp_sound, z, inp_sound_size) : 0.0;
279 
280  qv_hse_arr(i,j,k) = qv_k;
281  r_hse_arr (i,j,k) = rho_k * (1.0 + qv_k);
282  p_hse_arr (i,j,k) = getPgivenRTh(rhoTh_k, qv_k);
283  pi_hse_arr(i,j,k) = getExnergivenRTh(rhoTh_k, l_rdOcp);
284  th_hse_arr(i,j,k) = getRhoThetagivenP(p_hse_arr(i,j,k), qv_k) / rho_k;
285 
286  // TODO: we should be setting this to the number of ghost cells of base_state[lev]
287  // instead of hard-wiring it here!
288  int ng = 3;
289 
290  // FOEXTRAP hse arrays
291  if (k==kbot)
292  {
293  for (int kk = 1; kk <= ng; kk++) {
294  r_hse_arr(i, j, k-kk) = r_hse_arr(i,j,k);
295  p_hse_arr(i, j, k-kk) = p_hse_arr(i,j,k);
296  pi_hse_arr(i, j, k-kk) = pi_hse_arr(i,j,k);
297  th_hse_arr(i, j, k-kk) = th_hse_arr(i,j,k);
298  qv_hse_arr(i, j, k-kk) = qv_hse_arr(i,j,k);
299  }
300  }
301  else if (k==ktop)
302  {
303  for (int kk = 1; kk <= ng; kk++) {
304  r_hse_arr(i, j, k+kk) = r_hse_arr(i,j,k);
305  p_hse_arr(i, j, k+kk) = p_hse_arr(i,j,k);
306  pi_hse_arr(i, j, k+kk) = pi_hse_arr(i,j,k);
307  qv_hse_arr(i, j, k+kk) = qv_hse_arr(i,j,k);
308  }
309  }
310 
311  // total nonprecipitating water (Q1) == water vapor (Qv), i.e., there
312  // is no cloud water or cloud ice
313  if (l_moist) {
314  state(i, j, k, RhoQ1_comp) = rho_k * qv_k;
315  }
316  });
317 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=0.)
Definition: ERF_EOS.H:84
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenRTh(const amrex::Real rhotheta, const amrex::Real rdOcp, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:159
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhoThetagivenP(const amrex::Real p, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:175

Referenced by ERF::init_from_input_sounding().

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

◆ init_bx_velocities_from_input_sounding()

void init_bx_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
337 {
338  const Real* z_inp_sound = inputSoundingData.z_inp_sound_d[0].dataPtr();
339  const Real* U_inp_sound = inputSoundingData.U_inp_sound_d[0].dataPtr();
340  const Real* V_inp_sound = inputSoundingData.V_inp_sound_d[0].dataPtr();
341  const int inp_sound_size = inputSoundingData.size(0);
342 
343  // Geometry
344  const Real* prob_lo = geomdata.ProbLo();
345  const Real* dx = geomdata.CellSize();
346  const Real z_lo = prob_lo[2];
347  const Real dz = dx[2];
348 
349  // We want to set the lateral BC values, too
350  Box gbx = bx; // Copy constructor
351  gbx.grow(0,1); gbx.grow(1,1); // Grow by one in the lateral directions
352 
353  // Construct a box that is on x-faces
354  const Box& xbx = surroundingNodes(gbx,0);
355  // Construct a box that is on y-faces
356  const Box& ybx = surroundingNodes(gbx,1);
357  // Construct a box that is on z-faces
358  const Box& zbx = surroundingNodes(gbx,2);
359 
360  // Set the x,y,z-velocities
361  ParallelFor(xbx, ybx, zbx,
362  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
363  // Note that this is called on a box of x-faces
364  const Real z = (z_nd_arr) ? 0.25*( z_nd_arr(i,j ,k )
365  + z_nd_arr(i,j+1,k )
366  + z_nd_arr(i,j ,k+1)
367  + z_nd_arr(i,j+1,k+1))
368  : z_lo + (k + 0.5) * dz;
369 
370  // Set the x-velocity
371  x_vel(i, j, k) = interpolate_1d(z_inp_sound, U_inp_sound, z, inp_sound_size);
372  },
373  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
374  // Note that this is called on a box of y-faces
375  const Real z = (z_nd_arr) ? 0.25*( z_nd_arr(i ,j,k )
376  + z_nd_arr(i+1,j,k )
377  + z_nd_arr(i ,j,k+1)
378  + z_nd_arr(i+1,j,k+1))
379  : z_lo + (k + 0.5) * dz;
380 
381  // Set the y-velocity
382  y_vel(i, j, k) = interpolate_1d(z_inp_sound, V_inp_sound, z, inp_sound_size);
383  },
384  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
385  // Note that this is called on a box of z-faces
386  // Set the z-velocity
387  z_vel(i, j, k) = 0.0;
388  });
389 }

Referenced by ERF::init_from_input_sounding().

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