1 #ifndef ERF_PROBCOMMON_H_
2 #define ERF_PROBCOMMON_H_
4 #include <AMReX_ParmParse.H>
5 #include <AMReX_Geometry.H>
6 #include <AMReX_FArrayBox.H>
7 #include <AMReX_MultiFab.H>
24 if (std::getline(is, line)) {
25 std::stringstream ss(line);
28 amrex::Abort(
"Failed to read");
31 amrex::Print() <<
"Trying to read line " << n <<
" in this file " << std::endl;
32 amrex::Abort(
"Wrong format: more than one number in this line");
35 amrex::Abort(
"Unable to read this line");
42 amrex::FArrayBox& terrain_fab,
67 std::unique_ptr<amrex::MultiFab>& ,
68 std::unique_ptr<amrex::MultiFab>& ,
69 amrex::Geometry
const& )
71 amrex::Print() <<
"Hydrostatically balanced density was NOT set"
72 <<
" -- an appropriate init_type should probably have been specified"
73 <<
" (e.g., input_sounding, WRFInput, or Metgrid)"
75 amrex::Error(
"Should never call this version of erf_init_dens_hse for "+
name()+
" problem");
81 amrex::Error(
"Should never call this version of erf_init_const_dens_hse for "+
name()+
" problem");
86 amrex::MultiFab& , amrex::MultiFab& ,
89 amrex::Error(
"Should never call this version of erf_init_const_dens_and_th_hse for "+
name()+
" problem");
94 amrex::MultiFab& , amrex::MultiFab& ,
96 std::unique_ptr<amrex::MultiFab>& )
98 amrex::Error(
"Should never call this version of erf_init_const_dens_and_linear_th_hse for "+
name()+
" problem");
103 std::unique_ptr<amrex::MultiFab>& ,
104 amrex::Geometry
const& )
126 amrex::Array4<amrex::Real const>
const& ,
127 amrex::Array4<amrex::Real >
const& ,
128 amrex::Array4<amrex::Real >
const& ,
129 amrex::Array4<amrex::Real >
const& ,
130 amrex::Array4<amrex::Real const>
const& ,
131 amrex::Array4<amrex::Real const>
const& ,
132 amrex::GeometryData
const& ,
133 amrex::Array4<amrex::Real const>
const& ,
136 amrex::Print() <<
"No perturbation to background fields supplied for "
137 <<
name() <<
" problem" << std::endl;
160 amrex::Array4<amrex::Real >
const& ,
161 amrex::Array4<amrex::Real >
const& ,
162 amrex::Array4<amrex::Real >
const& ,
163 amrex::Array4<amrex::Real const>
const& ,
164 amrex::GeometryData
const& ,
165 amrex::Array4<amrex::Real const>
const& ,
166 amrex::Array4<amrex::Real const>
const& ,
169 amrex::Print() <<
"No perturbation velocities supplied for " <<
name() <<
" problem" << std::endl;
183 amrex::MultiFab* src,
184 const amrex::Geometry& ,
185 std::unique_ptr<amrex::MultiFab>& )
187 if (src->empty())
return;
189 amrex::Warning(
"Temperature forcing not defined for "+
name()+
" problem");
190 for ( amrex::MFIter mfi(*src, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi )
192 const auto &box = mfi.tilebox();
193 const amrex::Array4<amrex::Real>& src_arr = src->array(mfi);
196 ParallelFor(box, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept {
199 src_arr(i, j, k) = 0.0;
215 amrex::MultiFab* qsrc,
216 const amrex::Geometry& ,
217 std::unique_ptr<amrex::MultiFab>& )
219 if (qsrc->empty())
return;
221 amrex::Warning(
"Moisture forcing not defined for "+
name()+
" problem");
222 for ( amrex::MFIter mfi(*qsrc, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi )
224 const auto &box = mfi.tilebox();
225 const amrex::Array4<amrex::Real>& qsrc_arr = qsrc->array(mfi);
228 ParallelFor(box, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept {
231 qsrc_arr(i, j, k) = 0.0;
250 amrex::Vector<amrex::Real>&
wbar,
251 amrex::Gpu::DeviceVector<amrex::Real>& d_wbar,
252 const amrex::MultiFab& ,
253 const amrex::Geometry& geom,
254 std::unique_ptr<amrex::MultiFab>& )
256 if (
wbar.empty())
return;
258 amrex::Warning(
"Moisture forcing not defined for "+
name()+
" problem");
260 const int khi = geom.Domain().bigEnd()[2];
263 for (
int k = 0; k <=
khi; k++)
271 amrex::Gpu::copy(amrex::Gpu::hostToDevice,
wbar.begin(),
wbar.end(), d_wbar.begin());
285 amrex::Vector<amrex::Real>& u_geos,
286 amrex::Gpu::DeviceVector<amrex::Real>& d_u_geos,
287 amrex::Vector<amrex::Real>& v_geos,
288 amrex::Gpu::DeviceVector<amrex::Real>& d_v_geos,
289 const amrex::Geometry& geom,
290 std::unique_ptr<amrex::MultiFab>& )
292 if (u_geos.empty())
return;
294 amrex::Warning(
"Geostrophic wind profile not defined for "+
name()+
" problem");
296 const int khi = geom.Domain().bigEnd()[2];
299 for (
int k = 0; k <=
khi; k++)
308 amrex::Gpu::copy(amrex::Gpu::hostToDevice, u_geos.begin(), u_geos.end(), d_u_geos.begin());
309 amrex::Gpu::copy(amrex::Gpu::hostToDevice, v_geos.begin(), v_geos.end(), d_v_geos.begin());
321 amrex::FArrayBox& buildings_fab,
326 amrex::ParmParse
pp(
"erf");
327 auto valid_fname =
pp.query(
"buildings_file_name",fname);
346 amrex::FArrayBox& terrain_fab,
350 std::string fname, fname_usgs;
351 amrex::ParmParse
pp(
"erf");
352 auto valid_fname =
pp.query(
"terrain_file_name",fname);
353 auto valid_fname_USGS =
pp.query(
"terrain_file_name_USGS",fname_usgs);
361 }
else if (valid_fname_USGS) {
373 const amrex::Geometry& geom,
374 amrex::FArrayBox& terrain_fab,
377 amrex::Vector<amrex::Real> m_xterrain,m_yterrain,m_zterrain;
379 int nx = 0;
int ny = 0;
381 if (amrex::ParallelDescriptor::IOProcessor()) {
383 amrex::Print()<<
"Reading terrain file: "<< fname<< std::endl;
384 std::ifstream file(fname);
386 if (!file.is_open()) {
387 amrex::Abort(
"Error: Could not open the file " + fname+
"\n");
391 if (file.peek() == std::ifstream::traits_type::eof()) {
392 amrex::Abort(
"Error: The file " + fname+
" is empty.\n");
400 file >> lon_min >> lat_min;
401 if(std::fabs(lon_min) > 180.0) {
402 amrex::Error(
"The value of longitude for entry in the first line in " + fname
403 +
" should not exceed 180. It is " + std::to_string(lon_min));
405 if(std::fabs(lat_min) > 90.0) {
406 amrex::Error(
"The value of latitude for entry in the first line in " + fname
407 +
" should not exceed 90. It is " + std::to_string(lat_min));
413 while (file >> value1 >> value2 >> value3) {
414 m_xterrain.push_back(value1);
416 m_yterrain.push_back(value2);
418 m_zterrain.push_back(value3);
421 AMREX_ASSERT(m_xterrain.size() ==
static_cast<long int>(nx*ny));
422 AMREX_ASSERT(m_yterrain.size() ==
static_cast<long int>(ny));
423 AMREX_ASSERT(m_zterrain.size() ==
static_cast<long int>(nx*ny));
427 nx = erf_get_single_value<int>(file,cnt); cnt++;
428 ny = erf_get_single_value<int>(file,cnt); cnt++;
429 amrex::Print()<<
"Expecting " << nx <<
" values of x, " <<
430 ny <<
" values of y, and " <<
431 nx*ny <<
" values of z" << std::endl;
434 m_xterrain.resize(nx);
435 m_yterrain.resize(ny);
436 m_zterrain.resize(nx * ny);
437 for (
int n = 0; n < nx; n++) {
438 m_xterrain[n] = erf_get_single_value<amrex::Real>(file,cnt);
441 for (
int n = 0; n < ny; n++) {
442 m_yterrain[n] = erf_get_single_value<amrex::Real>(file,cnt);
445 for (
int n = 0; n < nx * ny; n++) {
446 m_zterrain[n] = erf_get_single_value<amrex::Real>(file,cnt);
455 amrex::ParallelDescriptor::Bcast(&nx,1,amrex::ParallelDescriptor::IOProcessorNumber());
456 amrex::ParallelDescriptor::Bcast(&ny,1,amrex::ParallelDescriptor::IOProcessorNumber());
460 m_xterrain.resize(nx);
461 m_yterrain.resize(ny);
462 m_zterrain.resize(nz);
464 amrex::ParallelDescriptor::Bcast(m_xterrain.data(),nx,amrex::ParallelDescriptor::IOProcessorNumber());
465 amrex::ParallelDescriptor::Bcast(m_yterrain.data(),ny,amrex::ParallelDescriptor::IOProcessorNumber());
466 amrex::ParallelDescriptor::Bcast(m_zterrain.data(),nz,amrex::ParallelDescriptor::IOProcessorNumber());
469 amrex::Gpu::DeviceVector<amrex::Real> d_xterrain(nx),d_yterrain(ny),d_zterrain(nz);
470 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_xterrain.begin(), m_xterrain.end(), d_xterrain.begin());
471 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_yterrain.begin(), m_yterrain.end(), d_yterrain.begin());
472 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_zterrain.begin(), m_zterrain.end(), d_zterrain.begin());
478 auto dx = geom.CellSizeArray();
479 auto ProbLoArr = geom.ProbLoArray();
481 int ilo = geom.Domain().smallEnd(0);
482 int jlo = geom.Domain().smallEnd(1);
483 int klo = geom.Domain().smallEnd(2);
484 int ihi = geom.Domain().bigEnd(0) + 1;
485 int jhi = geom.Domain().bigEnd(1) + 1;
487 amrex::Box
zbx = terrain_fab.box();
488 amrex::Array4<amrex::Real>
const& z_arr = terrain_fab.array();
493 int ii = amrex::min(amrex::max(i,ilo),ihi);
494 int jj = amrex::min(amrex::max(j,jlo),jhi);
500 int ind11, ind12, ind21, ind22;
503 int iindex_terrain=-1;
504 int jindex_terrain=-1;
510 for (
int it = 0; it < ny && jindex_terrain == -1; it++) {
512 jindex_terrain = it-1;
515 if (jindex_terrain == -1) {
516 jindex_terrain = ny-1;
519 int gstart = (jindex_terrain )*nx;
520 int gend = (jindex_terrain+1)*nx-1;
521 for (
int it = gstart; it <= gend && iindex_terrain == -1; it++) {
523 iindex_terrain = it-gstart;
528 ind11 = jindex_terrain*nx + iindex_terrain;
535 y1 = d_yt[jindex_terrain];
536 y2 = d_yt[jindex_terrain+1];
545 z_arr(i,j,
klo) = w_11*d_zt[ind11] + w_12*d_zt[ind12] + w_21*d_zt[ind21] + w_22*d_zt[ind22];
549 for (
int it = 0; it < ny && jindex_terrain == -1; it++) {
551 jindex_terrain = it-1;
554 if (jindex_terrain == -1) {
555 jindex_terrain = ny-1;
558 for (
int it = 0; it < nx && iindex_terrain == -1; it++) {
560 iindex_terrain = it-1;
563 if (iindex_terrain == -1) {
564 iindex_terrain = nx-1;
568 x1 = d_xt[iindex_terrain];
569 x2 = d_xt[iindex_terrain+1];
570 y1 = d_yt[jindex_terrain];
571 y2 = d_yt[jindex_terrain+1];
577 ind11 = iindex_terrain * ny + jindex_terrain;
578 ind21 = std::min(iindex_terrain+1,nx-1) * ny + jindex_terrain;
580 ind12 = iindex_terrain * ny + std::min(jindex_terrain+1,ny-1);
581 ind22 = std::min(iindex_terrain+1,nx-1) * ny + std::min(jindex_terrain+1,ny-1);
587 ind11 = jindex_terrain * nx + iindex_terrain;
588 ind12 = std::min(jindex_terrain+1,ny-1) * nx + iindex_terrain;
590 ind21 = jindex_terrain * nx + std::min(iindex_terrain+1,nx-1);
591 ind22 = std::min(jindex_terrain+1,ny-1) * nx + std::min(iindex_terrain+1,nx-1);
594 if (iindex_terrain == nx-1 && jindex_terrain == ny-1)
596 z_arr(i,j,
klo) = d_zt[ind11];
598 else if (iindex_terrain != nx-1 && jindex_terrain == ny-1)
603 z_arr(i,j,
klo) = (w_11*d_zt[ind11] + w_21*d_zt[ind21])/denom;
605 else if (iindex_terrain == nx-1 && jindex_terrain != ny-1)
610 z_arr(i,j,
klo) = (w_11*d_zt[ind11] + w_12*d_zt[ind12])/denom;
619 z_arr(i,j,
klo) = (w_11*d_zt[ind11] + w_12*d_zt[ind12] + w_21*d_zt[ind21] + w_22*d_zt[ind22]) / denom;
636 amrex::FArrayBox& terrain_fab,
639 std::string custom_terrain_type =
"None";
640 amrex::ParmParse
pp_prob(
"prob");
pp_prob.query(
"custom_terrain_type",custom_terrain_type);
642 if (custom_terrain_type !=
"None")
644 amrex::Print() <<
"Calling custom terrain initialization" << std::endl;
648 amrex::Print() <<
"Initializing flat terrain" << std::endl;
649 terrain_fab.template setVal<amrex::RunOn::Device>(0.0);
653 amrex::Print() <<
"Resetting mesh type to StretchedDz" << std::endl;
658 #ifdef ERF_USE_TERRAIN_VELOCITY
661 amrex::Error(
"Should never call compute_terrain_velocity for "+
name()+
" problem");
674 amrex::Geometry
const& ,
675 std::unique_ptr<amrex::MultiFab>& ,
694 std::string
name() { std::string prob_name; amrex::ParmParse
pp(
"erf");
pp.query(
"prob_name",prob_name);
return prob_name; }
703 const amrex_real*
probhi) AMREX_ATTRIBUTE_WEAK;
@ wbar
Definition: ERF_DataStruct.H:98
auto probhi
Definition: ERF_InitCustomPertVels_ABL.H:21
auto problo
Definition: ERF_InitCustomPertVels_ABL.H:20
const int klo
Definition: ERF_InitCustomPertVels_ParticleTests.H:4
Real rho_0
Definition: ERF_InitCustomPert_ABL.H:4
Real T_0
Definition: ERF_InitCustomPert_ABL.H:5
const Real dx
Definition: ERF_InitCustomPert_ABL.H:23
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
ParmParse pp_prob("prob")
Real T
Definition: ERF_InitCustomPert_Bubble.H:105
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { const auto prob_lo=geomdata.ProbLo();const auto dx=geomdata.CellSize();const Real x=(prob_lo[0]+(i+0.5) *dx[0])/mf_m(i, j, 0);const Real z=z_cc(i, j, k);Real L=std::sqrt(std::pow((x - x_c)/x_r, 2)+std::pow((z - z_c)/z_r, 2));if(L<=1.0) { Real dT=T_pert *(std::cos(PI *L)+1.0)/2.0;Real Tbar_hse=p_hse(i, j, k)/(R_d *r_hse(i, j, k));Real theta_perturbed=(Tbar_hse+dT) *std::pow(p_0/p_hse(i, j, k), rdOcp);Real theta_0=(Tbar_hse) *std::pow(p_0/p_hse(i, j, k), rdOcp);if(const_rho) { state_pert(i, j, k, RhoTheta_comp)=r_hse(i, j, k) *(theta_perturbed - theta_0);} else { state_pert(i, j, k, Rho_comp)=getRhoThetagivenP(p_hse(i, j, k))/theta_perturbed - r_hse(i, j, k);} } })
T erf_get_single_value(std::istream &is, int n)
Definition: ERF_ProbCommon.H:20
void init_my_custom_terrain(const amrex::Geometry &geom, amrex::FArrayBox &terrain_fab, const amrex::Real &time)
std::unique_ptr< ProblemBase > amrex_probinit(const amrex_real *problo, const amrex_real *probhi) AMREX_ATTRIBUTE_WEAK
const Box zbx
Definition: ERF_SetupDiff.H:9
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_ProbCommon.H:49
virtual void init_custom_terrain(const amrex::Geometry &geom, amrex::FArrayBox &terrain_fab, const amrex::Real &time)
Definition: ERF_ProbCommon.H:635
virtual void update_w_subsidence(const amrex::Real &, amrex::Vector< amrex::Real > &wbar, amrex::Gpu::DeviceVector< amrex::Real > &d_wbar, const amrex::MultiFab &, const amrex::Geometry &geom, std::unique_ptr< amrex::MultiFab > &)
Definition: ERF_ProbCommon.H:249
virtual void update_rhoqt_sources(const amrex::Real &, amrex::MultiFab *qsrc, const amrex::Geometry &, std::unique_ptr< amrex::MultiFab > &)
Definition: ERF_ProbCommon.H:214
virtual void erf_init_const_dens_and_linear_th_hse(amrex::MultiFab &, amrex::MultiFab &, amrex::MultiFab &, amrex::MultiFab &, amrex::MultiFab &, amrex::Real, std::unique_ptr< amrex::MultiFab > &)
Definition: ERF_ProbCommon.H:93
void init_terrain_surface(const amrex::Geometry &geom, amrex::FArrayBox &terrain_fab, const amrex::Real &time)
Definition: ERF_ProbCommon.H:345
virtual void init_custom_pert_vels(const amrex::Box &, const amrex::Box &, const amrex::Box &, amrex::Array4< amrex::Real > const &, amrex::Array4< amrex::Real > const &, amrex::Array4< amrex::Real > const &, amrex::Array4< amrex::Real const > const &, amrex::GeometryData const &, amrex::Array4< amrex::Real const > const &, amrex::Array4< amrex::Real const > const &, const SolverChoice &, const int)
Definition: ERF_ProbCommon.H:157
virtual void erf_init_const_dens_hse(amrex::MultiFab &)
Definition: ERF_ProbCommon.H:79
void read_custom_terrain(const std::string &fname, const bool is_usgs, const amrex::Geometry &geom, amrex::FArrayBox &terrain_fab, const amrex::Real &)
Definition: ERF_ProbCommon.H:371
void init_buildings_surface(const amrex::Geometry &geom, amrex::FArrayBox &buildings_fab, const amrex::Real &time)
Definition: ERF_ProbCommon.H:320
virtual void erf_init_rayleigh(amrex::Vector< amrex::Vector< amrex::Real > > &, amrex::Geometry const &, std::unique_ptr< amrex::MultiFab > &, amrex::Real)
Definition: ERF_ProbCommon.H:673
void init_base_parms(amrex::Real rho_0, amrex::Real T_0)
Definition: ERF_ProbCommon.H:689
virtual void update_rhotheta_sources(const amrex::Real &, amrex::MultiFab *src, const amrex::Geometry &, std::unique_ptr< amrex::MultiFab > &)
Definition: ERF_ProbCommon.H:182
virtual ~ProblemBase()=default
virtual void erf_init_dens_hse_moist(amrex::MultiFab &, std::unique_ptr< amrex::MultiFab > &, amrex::Geometry const &)
Definition: ERF_ProbCommon.H:102
virtual void init_custom_pert(const amrex::Box &, amrex::Array4< amrex::Real const > const &, amrex::Array4< amrex::Real > const &, amrex::Array4< amrex::Real > const &, amrex::Array4< amrex::Real > const &, amrex::Array4< amrex::Real const > const &, amrex::Array4< amrex::Real const > const &, amrex::GeometryData const &, amrex::Array4< amrex::Real const > const &, const SolverChoice &, const int)
Definition: ERF_ProbCommon.H:125
std::string name()
Definition: ERF_ProbCommon.H:694
virtual void erf_init_const_dens_and_th_hse(amrex::MultiFab &, amrex::MultiFab &, amrex::MultiFab &, amrex::MultiFab &, amrex::MultiFab &, amrex::Real)
Definition: ERF_ProbCommon.H:85
ProbParmDefaults base_parms
Definition: ERF_ProbCommon.H:683
virtual void erf_init_dens_hse(amrex::MultiFab &, std::unique_ptr< amrex::MultiFab > &, std::unique_ptr< amrex::MultiFab > &, amrex::Geometry const &)
Definition: ERF_ProbCommon.H:66
virtual void update_geostrophic_profile(const amrex::Real &, amrex::Vector< amrex::Real > &u_geos, amrex::Gpu::DeviceVector< amrex::Real > &d_u_geos, amrex::Vector< amrex::Real > &v_geos, amrex::Gpu::DeviceVector< amrex::Real > &d_v_geos, const amrex::Geometry &geom, std::unique_ptr< amrex::MultiFab > &)
Definition: ERF_ProbCommon.H:284
Definition: ERF_ProbCommon.H:14
amrex::Real T_0
Definition: ERF_ProbCommon.H:16
amrex::Real rho_0
Definition: ERF_ProbCommon.H:15
Definition: ERF_DataStruct.H:130
static MeshType mesh_type
Definition: ERF_DataStruct.H:1068
static void set_mesh_type(MeshType new_mesh_type)
Definition: ERF_DataStruct.H:1071