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

#include <InputSoundingData.H>

Collaboration diagram for InputSoundingData:

Public Member Functions

 InputSoundingData ()
 
void read_from_file (const std::string input_sounding_file, const amrex::Geometry &geom, const amrex::Vector< amrex::Real > &zlevels_stag)
 
void calc_rho_p ()
 
void host_to_device ()
 
int size () const
 

Public Attributes

amrex::Real press_ref_inp_sound
 
amrex::Real theta_ref_inp_sound
 
amrex::Real qv_ref_inp_sound
 
amrex::Vector< amrex::Real > z_inp_sound
 
amrex::Vector< amrex::Real > theta_inp_sound
 
amrex::Vector< amrex::Real > qv_inp_sound
 
amrex::Vector< amrex::Real > U_inp_sound
 
amrex::Vector< amrex::Real > V_inp_sound
 
amrex::Gpu::DeviceVector< amrex::Real > z_inp_sound_d
 
amrex::Gpu::DeviceVector< amrex::Real > theta_inp_sound_d
 
amrex::Gpu::DeviceVector< amrex::Real > qv_inp_sound_d
 
amrex::Gpu::DeviceVector< amrex::Real > U_inp_sound_d
 
amrex::Gpu::DeviceVector< amrex::Real > V_inp_sound_d
 
amrex::Vector< amrex::Real > pm_integ
 
amrex::Vector< amrex::Real > rhod_integ
 
amrex::Gpu::DeviceVector< amrex::Real > p_inp_sound_d
 
amrex::Gpu::DeviceVector< amrex::Real > rho_inp_sound_d
 

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
22 {}

Member Function Documentation

◆ calc_rho_p()

void InputSoundingData::calc_rho_p ( )
inline
124  {
125  /* Calculate density and pressure, roughly following the procedure in
126  * WRF dyn_em/module_initialize_ideal.F. We integrate hydrostatically
127  * from the surface up through the air column to get the dry density
128  * and moist pressure.
129  */
130  const int maxiter = 10;
131  const int Ninp = size();
132  pm_integ.resize(Ninp);
133  rhod_integ.resize(Ninp);
134 
135  // evaluate surface quantities (k=0): total pressure and dry air
139  R_d/Cp_d,
141 
142  amrex::Print() << "ideal sounding init: surface density of moist air = "
143  << rhod_integ[0] << " kg/m^3" << std::endl;
144 
145  // Note:
146  // p_dry = rho_d R_d T
147  // p_tot = rho_m R_d T_v
148  // = rho_d(1 + q_v) R_d T_v
149 
150  // integrate from surface to domain top
151  amrex::Real qv, dz;
152 #if 1 // Printing
153  // In this absence of moisture, this moist profile will match the
154  // following dry profile
155  amrex::Print() << "z p_m rho_d theta qv U V" << std::endl;
156  amrex::Print() << z_inp_sound[0]
157  << " " << pm_integ[0]
158  << " " << rhod_integ[0]
159  << " " << theta_inp_sound[0]
160  << " " << qv_inp_sound[0]
161  << " " << U_inp_sound[0]
162  << " " << V_inp_sound[0]
163  << std::endl;
164 #endif
165  for (int k=1; k < size(); ++k)
166  {
167  qv = qv_inp_sound[k];
168  dz = z_inp_sound[k] - z_inp_sound[k-1];
169  rhod_integ[k] = rhod_integ[k-1]; // guess
170  for (int it=0; it < maxiter; ++it)
171  {
172  pm_integ[k] = pm_integ[k-1] - 0.5*dz*(rhod_integ[k] + rhod_integ[k-1])*(1.0+qv)*CONST_GRAV;
173  AMREX_ALWAYS_ASSERT(pm_integ[k] > 0);
175  pm_integ[k],
176  R_d/Cp_d,
177  qv);
178  }
179 #if 1 // Printing
180  amrex::Print() << z_inp_sound[k]
181  << " " << pm_integ[k]
182  << " " << rhod_integ[k]
183  << " " << theta_inp_sound[k]
184  << " " << qv_inp_sound[k]
185  << " " << U_inp_sound[k]
186  << " " << V_inp_sound[k]
187  << std::endl;
188 #endif
189  }
190  // Note: at this point, the surface pressure, density of the dry air
191  // column is stored in pm_integ[0], rhod_integ[0]
192 
193  // update
194  host_to_device();
195  }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhogivenThetaPress(const amrex::Real theta, const amrex::Real p, const amrex::Real rdOcp, const amrex::Real qv=0.0)
Definition: EOS.H:75
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:12
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:21
constexpr amrex::Real R_d
Definition: ERF_Constants.H:10
@ qv
Definition: Kessler.H:36
amrex::Real press_ref_inp_sound
Definition: InputSoundingData.H:247
amrex::Vector< amrex::Real > z_inp_sound
Definition: InputSoundingData.H:248
amrex::Real theta_ref_inp_sound
Definition: InputSoundingData.H:247
amrex::Vector< amrex::Real > pm_integ
Definition: InputSoundingData.H:251
amrex::Vector< amrex::Real > rhod_integ
Definition: InputSoundingData.H:253
amrex::Vector< amrex::Real > qv_inp_sound
Definition: InputSoundingData.H:248
amrex::Vector< amrex::Real > U_inp_sound
Definition: InputSoundingData.H:248
amrex::Vector< amrex::Real > V_inp_sound
Definition: InputSoundingData.H:248
amrex::Real qv_ref_inp_sound
Definition: InputSoundingData.H:247
void host_to_device()
Definition: InputSoundingData.H:197
amrex::Vector< amrex::Real > theta_inp_sound
Definition: InputSoundingData.H:248
int size() const
Definition: InputSoundingData.H:236
Here is the call graph for this function:

◆ host_to_device()

void InputSoundingData::host_to_device ( )
inline
198  {
199  const int Ninp = size();
200  z_inp_sound_d.resize(Ninp);
201  theta_inp_sound_d.resize(Ninp);
202  qv_inp_sound_d.resize(Ninp);
203  U_inp_sound_d.resize(Ninp);
204  V_inp_sound_d.resize(Ninp);
205 
206  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
207  z_inp_sound.begin(), z_inp_sound.end(),
208  z_inp_sound_d.begin());
209  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
210  theta_inp_sound.begin(), theta_inp_sound.end(),
211  theta_inp_sound_d.begin());
212  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
213  qv_inp_sound.begin(), qv_inp_sound.end(),
214  qv_inp_sound_d.begin());
215  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
216  U_inp_sound.begin(), U_inp_sound.end(),
217  U_inp_sound_d.begin());
218  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
219  V_inp_sound.begin(), V_inp_sound.end(),
220  V_inp_sound_d.begin());
221 
222  if (rhod_integ.size() > 0)
223  {
224  //amrex::Print() << "Copying rho_d, p_d to device" << std::endl;
225  rho_inp_sound_d.resize(size()+2);
226  p_inp_sound_d.resize(size()+2);
227  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
228  rhod_integ.begin(), rhod_integ.end(),
229  rho_inp_sound_d.begin());
230  amrex::Gpu::copy(amrex::Gpu::hostToDevice,
231  pm_integ.begin(), pm_integ.end(),
232  p_inp_sound_d.begin());
233  }
234  }
amrex::Gpu::DeviceVector< amrex::Real > p_inp_sound_d
Definition: InputSoundingData.H:255
amrex::Gpu::DeviceVector< amrex::Real > V_inp_sound_d
Definition: InputSoundingData.H:249
amrex::Gpu::DeviceVector< amrex::Real > rho_inp_sound_d
Definition: InputSoundingData.H:255
amrex::Gpu::DeviceVector< amrex::Real > U_inp_sound_d
Definition: InputSoundingData.H:249
amrex::Gpu::DeviceVector< amrex::Real > z_inp_sound_d
Definition: InputSoundingData.H:249
amrex::Gpu::DeviceVector< amrex::Real > qv_inp_sound_d
Definition: InputSoundingData.H:249
amrex::Gpu::DeviceVector< amrex::Real > theta_inp_sound_d
Definition: InputSoundingData.H:249

Referenced by calc_rho_p(), 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 std::string  input_sounding_file,
const amrex::Geometry &  geom,
const amrex::Vector< amrex::Real > &  zlevels_stag 
)
inline
27  {
28  const int klo = 0;
29  const int khi = geom.Domain().bigEnd()[AMREX_SPACEDIM-1];
30  const int Nz = geom.Domain().size()[AMREX_SPACEDIM-1];
31  const amrex::Real dz = geom.CellSize()[AMREX_SPACEDIM-1];
32 
33  const bool use_terrain = (zlevels_stag.size() > 0);
34  const amrex::Real zbot = (use_terrain) ? zlevels_stag[klo] : geom.ProbLo(AMREX_SPACEDIM-1);
35  const amrex::Real ztop = (use_terrain) ? zlevels_stag[khi+1] : geom.ProbHi(AMREX_SPACEDIM-1);
36 
37  z_inp_sound.resize(Nz+2);
38  theta_inp_sound.resize(Nz+2);
39  qv_inp_sound.resize(Nz+2);
40  U_inp_sound.resize(Nz+2);
41  V_inp_sound.resize(Nz+2);
42 
43  // Read the input_sounding file
44  amrex::Print() << "input_sounding file location : " << input_sounding_file << std::endl;
45  std::ifstream input_sounding_reader(input_sounding_file);
46  if(!input_sounding_reader.is_open()) {
47  amrex::Error("Error opening the input_sounding file\n");
48  }
49  else {
50  // Read the contents of the input_sounding file
51  amrex::Print() << "Successfully opened the input_sounding file. Now reading... " << std::endl;
52  std::string line;
53 
54  // First, read the input data into temp vectors; then, interpolate vectors to the
55  // domain lo/hi and cell centers (from level 0)
56  amrex::Vector<amrex::Real> z_inp_sound_tmp, theta_inp_sound_tmp, qv_inp_sound_tmp,
57  U_inp_sound_tmp, V_inp_sound_tmp;
58 
59  // Read surface quantities from the first line
60  std::getline(input_sounding_reader, line);
61  std::istringstream iss(line);
63  press_ref_inp_sound *= 100; // convert from hPa to Pa
64  qv_ref_inp_sound *= 0.001; // convert from g/kg to kg/kg
65 
66  // Add surface
67  z_inp_sound_tmp.push_back(zbot); // height above sea level [m]
68  theta_inp_sound_tmp.push_back(theta_ref_inp_sound);
69  qv_inp_sound_tmp.push_back(qv_ref_inp_sound);
70  U_inp_sound_tmp.push_back(0);
71  V_inp_sound_tmp.push_back(0);
72 
73  // Read the vertical profile at each given height
74  amrex::Real z, theta, qv, U, V;
75  while(std::getline(input_sounding_reader, line)) {
76  std::istringstream iss_z(line);
77  iss_z >> z >> theta >> qv >> U >> V;
78  if (z == zbot) {
79  AMREX_ALWAYS_ASSERT(theta == theta_inp_sound_tmp[0]);
80  AMREX_ALWAYS_ASSERT(qv*0.001 == qv_inp_sound_tmp[0]); // convert from g/kg to kg/kg
81  U_inp_sound_tmp[0] = U;
82  V_inp_sound_tmp[0] = V;
83  } else {
84  AMREX_ALWAYS_ASSERT(z > z_inp_sound_tmp[z_inp_sound_tmp.size()-1]); // sounding is increasing in height
85  z_inp_sound_tmp.push_back(z);
86  theta_inp_sound_tmp.push_back(theta);
87  qv_inp_sound_tmp.push_back(qv*0.001); // convert from g/kg to kg/kg
88  U_inp_sound_tmp.push_back(U);
89  V_inp_sound_tmp.push_back(V);
90  if (z >= ztop) break;
91  }
92  }
93 
94  // At this point, we have an input_sounding from zbot up to
95  // z_inp_sound_tmp[N-1] >= ztop. Now, interpolate to grid level 0 heights
96  const int Ninp = z_inp_sound_tmp.size();
97  z_inp_sound[0] = zbot;
98  theta_inp_sound[0] = theta_inp_sound_tmp[0];
99  qv_inp_sound[0] = qv_inp_sound_tmp[0];
100  U_inp_sound[0] = U_inp_sound_tmp[0];
101  V_inp_sound[0] = V_inp_sound_tmp[0];
102  for (int k=0; k < Nz; ++k) {
103  z_inp_sound[k+1] = (use_terrain) ? 0.5 * (zlevels_stag[k] + zlevels_stag[k+1])
104  : zbot + (k + 0.5) * dz;
105  theta_inp_sound[k+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), theta_inp_sound_tmp.dataPtr(), z_inp_sound[k+1], Ninp);
106  qv_inp_sound[k+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), qv_inp_sound_tmp.dataPtr(), z_inp_sound[k+1], Ninp);
107  U_inp_sound[k+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), U_inp_sound_tmp.dataPtr(), z_inp_sound[k+1], Ninp);
108  V_inp_sound[k+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), V_inp_sound_tmp.dataPtr(), z_inp_sound[k+1], Ninp);
109  }
110  z_inp_sound[Nz+1] = ztop;
111  theta_inp_sound[Nz+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), theta_inp_sound_tmp.dataPtr(), ztop, Ninp);
112  qv_inp_sound[Nz+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), qv_inp_sound_tmp.dataPtr(), ztop, Ninp);
113  U_inp_sound[Nz+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), U_inp_sound_tmp.dataPtr(), ztop, Ninp);
114  V_inp_sound[Nz+1] = interpolate_1d(z_inp_sound_tmp.dataPtr(), V_inp_sound_tmp.dataPtr(), ztop, Ninp);
115  }
116 
117  amrex::Print() << "Successfully read the input_sounding file..." << std::endl;
118  input_sounding_reader.close();
119 
120  host_to_device();
121  }
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: Interpolation_1D.H:12
@ theta
Definition: MM5.H:20
@ U
Definition: IndexDefines.H:64
@ V
Definition: IndexDefines.H:65
Here is the call graph for this function:

◆ size()

int InputSoundingData::size ( ) const
inline
237  {
238  AMREX_ALWAYS_ASSERT(z_inp_sound.size() == theta_inp_sound.size());
239  AMREX_ALWAYS_ASSERT(z_inp_sound.size() == qv_inp_sound.size());
240  AMREX_ALWAYS_ASSERT(z_inp_sound.size() == U_inp_sound.size());
241  AMREX_ALWAYS_ASSERT(z_inp_sound.size() == V_inp_sound.size());
242  return z_inp_sound.size();
243  }

Referenced by calc_rho_p(), host_to_device(), init_bx_scalars_from_input_sounding(), init_bx_scalars_from_input_sounding_hse(), and init_bx_velocities_from_input_sounding().

Here is the caller graph for this function:

Member Data Documentation

◆ p_inp_sound_d

amrex::Gpu::DeviceVector<amrex::Real> InputSoundingData::p_inp_sound_d

Referenced by host_to_device().

◆ pm_integ

amrex::Vector<amrex::Real> InputSoundingData::pm_integ

Referenced by calc_rho_p(), and host_to_device().

◆ press_ref_inp_sound

amrex::Real InputSoundingData::press_ref_inp_sound

Referenced by calc_rho_p(), and read_from_file().

◆ qv_inp_sound

amrex::Vector<amrex::Real> InputSoundingData::qv_inp_sound

◆ qv_inp_sound_d

amrex::Gpu::DeviceVector<amrex::Real> InputSoundingData::qv_inp_sound_d

◆ qv_ref_inp_sound

amrex::Real InputSoundingData::qv_ref_inp_sound

Referenced by calc_rho_p(), and read_from_file().

◆ rho_inp_sound_d

amrex::Gpu::DeviceVector<amrex::Real> InputSoundingData::rho_inp_sound_d

◆ rhod_integ

amrex::Vector<amrex::Real> InputSoundingData::rhod_integ

Referenced by calc_rho_p(), and host_to_device().

◆ theta_inp_sound

amrex::Vector<amrex::Real> InputSoundingData::theta_inp_sound

◆ theta_inp_sound_d

amrex::Gpu::DeviceVector<amrex::Real> InputSoundingData::theta_inp_sound_d

◆ theta_ref_inp_sound

amrex::Real InputSoundingData::theta_ref_inp_sound

Referenced by calc_rho_p(), and read_from_file().

◆ U_inp_sound

amrex::Vector<amrex::Real> InputSoundingData::U_inp_sound

◆ U_inp_sound_d

amrex::Gpu::DeviceVector<amrex::Real> InputSoundingData::U_inp_sound_d

◆ V_inp_sound

amrex::Vector<amrex::Real> InputSoundingData::V_inp_sound

◆ V_inp_sound_d

amrex::Gpu::DeviceVector<amrex::Real> InputSoundingData::V_inp_sound_d

◆ z_inp_sound

amrex::Vector<amrex::Real> InputSoundingData::z_inp_sound

◆ z_inp_sound_d

amrex::Gpu::DeviceVector<amrex::Real> InputSoundingData::z_inp_sound_d

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