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");
62 std::unique_ptr<amrex::MultiFab>& ,
63 std::unique_ptr<amrex::MultiFab>& ,
64 amrex::Geometry
const& )
66 amrex::Print() <<
"Hydrostatically balanced density was NOT set"
67 <<
" -- an appropriate init_type should probably have been specified"
68 <<
" (e.g., input_sounding, WRFInput, or Metgrid)"
70 amrex::Error(
"Should never call erf_init_dens_hse for "+
name()+
" problem");
75 std::unique_ptr<amrex::MultiFab>& ,
76 amrex::Geometry
const& )
109 amrex::Array4<amrex::Real const>
const& ,
110 amrex::Array4<amrex::Real >
const& ,
111 amrex::Array4<amrex::Real >
const& ,
112 amrex::Array4<amrex::Real >
const& ,
113 amrex::Array4<amrex::Real >
const& ,
114 amrex::Array4<amrex::Real >
const& ,
115 amrex::Array4<amrex::Real >
const& ,
116 amrex::Array4<amrex::Real const>
const& ,
117 amrex::Array4<amrex::Real const>
const& ,
118 amrex::GeometryData
const& ,
119 amrex::Array4<amrex::Real const>
const& ,
120 amrex::Array4<amrex::Real const>
const& ,
121 amrex::Array4<amrex::Real const>
const& ,
125 amrex::Print() <<
"No perturbation to background fields supplied for "
126 <<
name() <<
" problem" << std::endl;
140 amrex::Vector<amrex::Real>& src,
141 amrex::Gpu::DeviceVector<amrex::Real>& d_src,
142 const amrex::Geometry& geom,
143 std::unique_ptr<amrex::MultiFab>& )
145 if (src.empty())
return;
147 amrex::Warning(
"Temperature forcing not defined for "+
name()+
" problem");
149 const int khi = geom.Domain().bigEnd()[2];
152 for (
int k = 0; k <= khi; k++)
160 amrex::Gpu::copy(amrex::Gpu::hostToDevice, src.begin(), src.end(), d_src.begin());
174 amrex::Vector<amrex::Real>& qsrc,
175 amrex::Gpu::DeviceVector<amrex::Real>& d_qsrc,
176 const amrex::Geometry& geom,
177 std::unique_ptr<amrex::MultiFab>& )
179 if (qsrc.empty())
return;
181 amrex::Warning(
"Moisture forcing not defined for "+
name()+
" problem");
183 const int khi = geom.Domain().bigEnd()[2];
186 for (
int k = 0; k <= khi; k++)
194 amrex::Gpu::copy(amrex::Gpu::hostToDevice, qsrc.begin(), qsrc.end(), d_qsrc.begin());
211 amrex::Vector<amrex::Real>&
wbar,
212 amrex::Gpu::DeviceVector<amrex::Real>& d_wbar,
213 const amrex::Geometry& geom,
214 std::unique_ptr<amrex::MultiFab>& )
216 if (
wbar.empty())
return;
218 amrex::Warning(
"Moisture forcing not defined for "+
name()+
" problem");
220 const int khi = geom.Domain().bigEnd()[2];
223 for (
int k = 0; k <= khi; k++)
231 amrex::Gpu::copy(amrex::Gpu::hostToDevice,
wbar.begin(),
wbar.end(), d_wbar.begin());
245 amrex::Vector<amrex::Real>& u_geos,
246 amrex::Gpu::DeviceVector<amrex::Real>& d_u_geos,
247 amrex::Vector<amrex::Real>& v_geos,
248 amrex::Gpu::DeviceVector<amrex::Real>& d_v_geos,
249 const amrex::Geometry& geom,
250 std::unique_ptr<amrex::MultiFab>& )
252 if (u_geos.empty())
return;
254 amrex::Warning(
"Geostrophic wind profile not defined for "+
name()+
" problem");
256 const int khi = geom.Domain().bigEnd()[2];
259 for (
int k = 0; k <= khi; k++)
268 amrex::Gpu::copy(amrex::Gpu::hostToDevice, u_geos.begin(), u_geos.end(), d_u_geos.begin());
269 amrex::Gpu::copy(amrex::Gpu::hostToDevice, v_geos.begin(), v_geos.end(), d_v_geos.begin());
281 amrex::FArrayBox& buildings_fab,
286 amrex::ParmParse
pp(
"erf");
287 auto valid_fname =
pp.query(
"buildings_file_name",fname);
306 amrex::FArrayBox& terrain_fab,
310 std::string fname, fname_usgs;
311 amrex::ParmParse
pp(
"erf");
312 auto valid_fname =
pp.query(
"terrain_file_name",fname);
313 auto valid_fname_USGS =
pp.query(
"terrain_file_name_USGS",fname_usgs);
321 }
else if (valid_fname_USGS) {
333 const amrex::Geometry& geom,
334 amrex::FArrayBox& terrain_fab,
337 amrex::Vector<amrex::Real> m_xterrain,m_yterrain,m_zterrain;
339 int nx = 0;
int ny = 0;
341 if (amrex::ParallelDescriptor::IOProcessor()) {
343 amrex::Print()<<
"Reading terrain file: "<< fname<< std::endl;
344 std::ifstream file(fname);
346 if (!file.is_open()) {
347 amrex::Abort(
"Error: Could not open the file " + fname+
"\n");
351 if (file.peek() == std::ifstream::traits_type::eof()) {
352 amrex::Abort(
"Error: The file " + fname+
" is empty.\n");
360 file >> lon_min >> lat_min;
361 if(std::fabs(lon_min) > 180.0) {
362 amrex::Error(
"The value of longitude for entry in the first line in " + fname
363 +
" should not exceed 180. It is " + std::to_string(lon_min));
365 if(std::fabs(lat_min) > 90.0) {
366 amrex::Error(
"The value of latitude for entry in the first line in " + fname
367 +
" should not exceed 90. It is " + std::to_string(lat_min));
373 while (file >> value1 >> value2 >> value3) {
374 m_xterrain.push_back(value1);
376 m_yterrain.push_back(value2);
378 m_zterrain.push_back(value3);
381 AMREX_ASSERT(m_xterrain.size() ==
static_cast<long int>(nx*ny));
382 AMREX_ASSERT(m_yterrain.size() ==
static_cast<long int>(ny));
383 AMREX_ASSERT(m_zterrain.size() ==
static_cast<long int>(nx*ny));
387 nx = erf_get_single_value<int>(file,cnt); cnt++;
388 ny = erf_get_single_value<int>(file,cnt); cnt++;
389 amrex::Print()<<
"Expecting " << nx <<
" values of x, " <<
390 ny <<
" values of y, and " <<
391 nx*ny <<
" values of z" << std::endl;
392 AMREX_ALWAYS_ASSERT(nx > 0);
393 AMREX_ALWAYS_ASSERT(ny > 0);
394 m_xterrain.resize(nx);
395 m_yterrain.resize(ny);
396 m_zterrain.resize(nx * ny);
397 for (
int n = 0; n < nx; n++) {
398 m_xterrain[n] = erf_get_single_value<amrex::Real>(file,cnt);
401 for (
int n = 0; n < ny; n++) {
402 m_yterrain[n] = erf_get_single_value<amrex::Real>(file,cnt);
405 for (
int n = 0; n < nx * ny; n++) {
406 m_zterrain[n] = erf_get_single_value<amrex::Real>(file,cnt);
415 amrex::ParallelDescriptor::Bcast(&nx,1,amrex::ParallelDescriptor::IOProcessorNumber());
416 amrex::ParallelDescriptor::Bcast(&ny,1,amrex::ParallelDescriptor::IOProcessorNumber());
420 m_xterrain.resize(nx);
421 m_yterrain.resize(ny);
422 m_zterrain.resize(nz);
424 amrex::ParallelDescriptor::Bcast(m_xterrain.data(),nx,amrex::ParallelDescriptor::IOProcessorNumber());
425 amrex::ParallelDescriptor::Bcast(m_yterrain.data(),ny,amrex::ParallelDescriptor::IOProcessorNumber());
426 amrex::ParallelDescriptor::Bcast(m_zterrain.data(),nz,amrex::ParallelDescriptor::IOProcessorNumber());
429 amrex::Gpu::DeviceVector<amrex::Real> d_xterrain(nx),d_yterrain(ny),d_zterrain(nz);
430 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_xterrain.begin(), m_xterrain.end(), d_xterrain.begin());
431 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_yterrain.begin(), m_yterrain.end(), d_yterrain.begin());
432 amrex::Gpu::copy(amrex::Gpu::hostToDevice, m_zterrain.begin(), m_zterrain.end(), d_zterrain.begin());
438 auto dx = geom.CellSizeArray();
439 auto ProbLoArr = geom.ProbLoArray();
441 int ilo = geom.Domain().smallEnd(0);
442 int jlo = geom.Domain().smallEnd(1);
443 int klo = geom.Domain().smallEnd(2);
444 int ihi = geom.Domain().bigEnd(0) + 1;
445 int jhi = geom.Domain().bigEnd(1) + 1;
447 amrex::Box
zbx = terrain_fab.box();
448 amrex::Array4<amrex::Real>
const& z_arr = terrain_fab.array();
450 amrex::ParallelFor(
zbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int )
453 int ii = amrex::min(amrex::max(i,ilo),ihi);
454 int jj = amrex::min(amrex::max(j,jlo),jhi);
460 int ind11, ind12, ind21, ind22;
463 int iindex_terrain=-1;
464 int jindex_terrain=-1;
470 for (
int it = 0; it < ny && jindex_terrain == -1; it++) {
472 jindex_terrain = it-1;
475 if (jindex_terrain == -1) {
476 jindex_terrain = ny-1;
479 int gstart = (jindex_terrain )*nx;
480 int gend = (jindex_terrain+1)*nx-1;
481 for (
int it = gstart; it <= gend && iindex_terrain == -1; it++) {
483 iindex_terrain = it-gstart;
488 ind11 = jindex_terrain*nx + iindex_terrain;
495 y1 = d_yt[jindex_terrain];
496 y2 = d_yt[jindex_terrain+1];
505 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];
509 for (
int it = 0; it < ny && jindex_terrain == -1; it++) {
511 jindex_terrain = it-1;
514 if (jindex_terrain == -1) {
515 jindex_terrain = ny-1;
518 for (
int it = 0; it < nx && iindex_terrain == -1; it++) {
520 iindex_terrain = it-1;
523 if (iindex_terrain == -1) {
524 iindex_terrain = nx-1;
528 x1 = d_xt[iindex_terrain];
529 x2 = d_xt[iindex_terrain+1];
530 y1 = d_yt[jindex_terrain];
531 y2 = d_yt[jindex_terrain+1];
537 ind11 = iindex_terrain * ny + jindex_terrain;
538 ind21 = std::min(iindex_terrain+1,nx-1) * ny + jindex_terrain;
540 ind12 = iindex_terrain * ny + std::min(jindex_terrain+1,ny-1);
541 ind22 = std::min(iindex_terrain+1,nx-1) * ny + std::min(jindex_terrain+1,ny-1);
547 ind11 = jindex_terrain * nx + iindex_terrain;
548 ind12 = std::min(jindex_terrain+1,ny-1) * nx + iindex_terrain;
550 ind21 = jindex_terrain * nx + std::min(iindex_terrain+1,nx-1);
551 ind22 = std::min(jindex_terrain+1,ny-1) * nx + std::min(iindex_terrain+1,nx-1);
554 if (iindex_terrain == nx-1 && jindex_terrain == ny-1)
556 z_arr(i,j,klo) = d_zt[ind11];
558 else if (iindex_terrain != nx-1 && jindex_terrain == ny-1)
563 z_arr(i,j,klo) = (w_11*d_zt[ind11] + w_21*d_zt[ind21])/denom;
565 else if (iindex_terrain == nx-1 && jindex_terrain != ny-1)
570 z_arr(i,j,klo) = (w_11*d_zt[ind11] + w_12*d_zt[ind12])/denom;
579 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;
596 amrex::FArrayBox& terrain_fab,
599 amrex::Print() <<
"Initializing flat terrain" << std::endl;
603 amrex::Print() <<
"Resetting mesh type to StretchedDz" << std::endl;
606 terrain_fab.template setVal<amrex::RunOn::Device>(0.0);
609 #ifdef ERF_USE_TERRAIN_VELOCITY
612 amrex::Error(
"Should never call compute_terrain_velocity for "+
name()+
" problem");
625 amrex::Geometry
const& ,
626 std::unique_ptr<amrex::MultiFab>& ,
629 amrex::Error(
"Should never call erf_init_rayleigh for "+
name()+
" problem");
636 init_uniform (
const amrex::Box& bx, amrex::Array4<amrex::Real>
const& state)
640 amrex::Print() <<
"Initializing uniform fields"
641 <<
" rho=" << rho_0 <<
" theta=" << T_0
644 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
665 virtual std::string
name () = 0;
674 const amrex_real* probhi) AMREX_ATTRIBUTE_WEAK;
@ wbar
Definition: ERF_DataStruct.H:96
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pp(amrex::Real y)
Definition: ERF_MicrophysicsUtils.H:233
T erf_get_single_value(std::istream &is, int n)
Definition: ERF_ProbCommon.H:20
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:44
virtual std::string name()=0
void init_uniform(const amrex::Box &bx, amrex::Array4< amrex::Real > const &state)
Definition: ERF_ProbCommon.H:636
void init_terrain_surface(const amrex::Geometry &geom, amrex::FArrayBox &terrain_fab, const amrex::Real &time)
Definition: ERF_ProbCommon.H:305
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:331
void init_buildings_surface(const amrex::Geometry &geom, amrex::FArrayBox &buildings_fab, const amrex::Real &time)
Definition: ERF_ProbCommon.H:280
virtual void update_w_subsidence(const amrex::Real &, amrex::Vector< amrex::Real > &wbar, amrex::Gpu::DeviceVector< amrex::Real > &d_wbar, const amrex::Geometry &geom, std::unique_ptr< amrex::MultiFab > &)
Definition: ERF_ProbCommon.H:210
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:624
void init_base_parms(amrex::Real rho_0, amrex::Real T_0)
Definition: ERF_ProbCommon.H:659
virtual void update_rhotheta_sources(const amrex::Real &, amrex::Vector< amrex::Real > &src, amrex::Gpu::DeviceVector< amrex::Real > &d_src, const amrex::Geometry &geom, std::unique_ptr< amrex::MultiFab > &)
Definition: ERF_ProbCommon.H:139
virtual void init_custom_terrain(const amrex::Geometry &, amrex::FArrayBox &terrain_fab, const amrex::Real &)
Definition: ERF_ProbCommon.H:595
virtual ~ProblemBase()=default
virtual void erf_init_dens_hse_moist(amrex::MultiFab &, std::unique_ptr< amrex::MultiFab > &, amrex::Geometry const &)
Definition: ERF_ProbCommon.H:74
ProbParmDefaults base_parms
Definition: ERF_ProbCommon.H:653
virtual void init_custom_pert(const amrex::Box &, const amrex::Box &, const amrex::Box &, 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 &, 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 &, amrex::Array4< amrex::Real const > const &, amrex::Array4< amrex::Real const > const &, const SolverChoice &, const int)
Definition: ERF_ProbCommon.H:105
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:61
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:244
virtual void update_rhoqt_sources(const amrex::Real &, amrex::Vector< amrex::Real > &qsrc, amrex::Gpu::DeviceVector< amrex::Real > &d_qsrc, const amrex::Geometry &geom, std::unique_ptr< amrex::MultiFab > &)
Definition: ERF_ProbCommon.H:173
@ T
Definition: ERF_IndexDefines.H:110
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:128
static MeshType mesh_type
Definition: ERF_DataStruct.H:983
static void set_mesh_type(MeshType new_mesh_type)
Definition: ERF_DataStruct.H:986