ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
SLM Class Reference

#include <ERF_SLM.H>

Inheritance diagram for SLM:
Collaboration diagram for SLM:

Public Member Functions

 SLM ()
 
virtual ~SLM ()=default
 
void Define (SolverChoice &) override
 
void Init (const int &, const amrex::MultiFab &cons_in, const amrex::Geometry &geom, const amrex::Geometry &, amrex::Vector< amrex::BCRec > &, amrex::IntVect &, const amrex::Real &dt, amrex::Vector< amrex::Vector< std::string >> &) override
 
void Advance (const double &dt) override
 
void ComputeTsurf ()
 
void ComputeFluxes ()
 
void AdvanceSLM ()
 
amrex::MultiFab * Lsm_Data_Ptr (const int &varIdx) override
 
amrex::MultiFab * Lsm_Flux_Ptr (const int &varIdx) override
 
amrex::Geometry Lsm_Geom () override
 
int Lsm_Data_Size () override
 
std::string Lsm_DataName (const int &varIdx) override
 
- Public Member Functions inherited from NullSurf
 NullSurf ()
 
virtual ~NullSurf ()=default
 
virtual void Advance_With_State (const int &, amrex::MultiFab &, amrex::MultiFab &, amrex::MultiFab &, amrex::MultiFab *, amrex::MultiFab *, const SurfacePrecipAccumulationSources &, const amrex::Real &, const amrex::Real &, const int &, const bool)
 
virtual void Plot_Landfile (const int &)
 
virtual void Update_Micro_Vars (amrex::MultiFab &)
 
virtual void Update_State_Vars (amrex::MultiFab &)
 
virtual void Copy_State_to_Micro (const amrex::MultiFab &)
 
virtual void Copy_Micro_to_State (amrex::MultiFab &)
 
virtual int Lsm_Flux_Size ()
 
virtual std::string Lsm_FluxName (const int &)
 
virtual int Lsm_DataIndex (std::string)
 
virtual int Lsm_FluxIndex (std::string)
 
virtual std::unordered_map< std::string, std::string > & Lsm_WRFInputNames ()
 
virtual void Lsm_Set_Lev0_Data_Ptr (const int &, amrex::MultiFab *)
 
virtual void Lsm_Set_Lev0_Flux_Ptr (const int &, amrex::MultiFab *)
 
virtual bool Get_Update_Status ()
 
virtual int Get_LSM_Step () const
 
virtual void Set_LSM_Step (int)
 
virtual void Write_Lsm_Restart (const std::string &) const
 
virtual void Read_Lsm_Restart (const std::string &)
 

Private Types

using FabPtr = std::shared_ptr< amrex::MultiFab >
 

Private Attributes

int m_lsm_size = 1
 
amrex::Vector< int > LsmVarMap
 
amrex::Vector< std::string > LsmVarName
 
amrex::Geometry m_geom
 
amrex::Geometry m_lsm_geom
 
double m_dt
 
int khi_lsm
 
amrex::Array< FabPtr, LsmVar_SLM::NumVarslsm_fab_vars
 
amrex::Array< FabPtr, LsmVar_SLM::NumVarslsm_fab_flux
 
int m_nz_lsm = 30
 
amrex::Real m_dz_lsm = amrex::Real(0.1)
 
amrex::Real m_cp_soil = amrex::Real(1.26e6)
 
amrex::Real m_k_soil = amrex::Real(0.2)
 
amrex::Real m_theta_dir = amrex::Real(400.0)
 
amrex::Real m_d_soil = m_k_soil / m_cp_soil
 

Member Typedef Documentation

◆ FabPtr

using SLM::FabPtr = std::shared_ptr<amrex::MultiFab>
private

Constructor & Destructor Documentation

◆ SLM()

SLM::SLM ( )
inline
32 {}

◆ ~SLM()

virtual SLM::~SLM ( )
virtualdefault

Member Function Documentation

◆ Advance()

void SLM::Advance ( const double &  dt)
inlineoverridevirtual

Reimplemented from NullSurf.

60  {
61  m_dt = dt;
62  this->ComputeFluxes();
63  this->AdvanceSLM();
64  this->ComputeTsurf();
65  }
void ComputeTsurf()
Definition: ERF_SLM.cpp:68
double m_dt
Definition: ERF_SLM.H:131
void ComputeFluxes()
Definition: ERF_SLM.cpp:87
void AdvanceSLM()
Definition: ERF_SLM.cpp:112
Here is the call graph for this function:

◆ AdvanceSLM()

void SLM::AdvanceSLM ( )
113 {
114  // Expose for GPU copy
115  Real dt = static_cast<Real>(m_dt);
116  Real dzInv = m_lsm_geom.InvCellSize(2);
117 
118  for ( MFIter mfi(*(lsm_fab_vars[LsmVar_SLM::theta])); mfi.isValid(); ++mfi) {
119  auto box3d = mfi.tilebox();
120 
121  auto theta_array = lsm_fab_vars[LsmVar_SLM::theta]->array(mfi);
122  auto theta_flux = lsm_fab_flux[LsmVar_SLM::theta]->array(mfi);
123 
124  ParallelFor( box3d, [=] AMREX_GPU_DEVICE (int i, int j, int k)
125  {
126  theta_array(i,j,k) += dt * ( theta_flux(i,j,k+1) - theta_flux(i,j,k) ) * dzInv;
127  });
128  }
129 }
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
amrex::Array< FabPtr, LsmVar_SLM::NumVars > lsm_fab_flux
Definition: ERF_SLM.H:145
amrex::Array< FabPtr, LsmVar_SLM::NumVars > lsm_fab_vars
Definition: ERF_SLM.H:142
amrex::Geometry m_lsm_geom
Definition: ERF_SLM.H:128
@ theta
Definition: ERF_SLM.H:20

Referenced by Advance().

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

◆ ComputeFluxes()

void SLM::ComputeFluxes ( )
88 {
89  // Expose for GPU copy
90  int khi = khi_lsm;
91  Real Dsoil = m_d_soil;
92  Real dzInv = m_lsm_geom.InvCellSize(2);
93 
94  for ( MFIter mfi(*(lsm_fab_flux[LsmVar_SLM::theta])); mfi.isValid(); ++mfi) {
95  auto box3d = mfi.tilebox();
96 
97  // Do not overwrite the flux at the top (comes from MOST BC)
98  if (box3d.bigEnd(2) == khi+1) box3d.setBig(2,khi);
99 
100  auto theta_array = lsm_fab_vars[LsmVar_SLM::theta]->array(mfi);
101  auto theta_flux = lsm_fab_flux[LsmVar_SLM::theta]->array(mfi);
102 
103  ParallelFor( box3d, [=] AMREX_GPU_DEVICE (int i, int j, int k)
104  {
105  theta_flux(i,j,k) = Dsoil * ( theta_array(i,j,k) - theta_array(i,j,k-1) ) * dzInv;
106  });
107  }
108 }
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
int khi_lsm
Definition: ERF_SLM.H:134
amrex::Real m_d_soil
Definition: ERF_SLM.H:165

Referenced by Advance().

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

◆ ComputeTsurf()

void SLM::ComputeTsurf ( )
69 {
70  // Expose for GPU copy
71  int khi = khi_lsm;
72 
73  for ( MFIter mfi(*(lsm_fab_vars[LsmVar_SLM::theta])); mfi.isValid(); ++mfi) {
74  auto box2d = mfi.tilebox(); box2d.makeSlab(2,khi);
75 
76  auto theta_array = lsm_fab_vars[LsmVar_SLM::theta]->array(mfi);
77 
78  ParallelFor( box2d, [=] AMREX_GPU_DEVICE (int i, int j, int )
79  {
80  theta_array(i,j,khi+1) = Real(1.5)*theta_array(i,j,khi) - myhalf*theta_array(i,j,khi-1);
81  });
82  }
83 }
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13

Referenced by Advance().

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

◆ Define()

void SLM::Define ( SolverChoice )
inlineoverridevirtual

Reimplemented from NullSurf.

40  {
41  // NOTE: We should parse things from sc here,
42  // but they are hard coded because this
43  // is a demonstration for now.
44  }

◆ Init()

void SLM::Init ( const int &  ,
const amrex::MultiFab &  cons_in,
const amrex::Geometry &  geom,
const amrex::Geometry &  ,
amrex::Vector< amrex::BCRec > &  ,
amrex::IntVect &  ,
const amrex::Real dt,
amrex::Vector< amrex::Vector< std::string >> &   
)
overridevirtual

Reimplemented from NullSurf.

15 {
16  m_dt = dt;
17  m_geom = geom;
18 
19  Box domain = geom.Domain();
20  khi_lsm = domain.smallEnd(2) - 1;
21 
22  LsmVarMap.resize(m_lsm_size);
24 
25  LsmVarName.resize(m_lsm_size);
26  LsmVarName = {"theta"};
27 
28  // NOTE: All boxes in ba extend from zlo to zhi, so this transform is valid.
29  // If that were to change, the dm and new ba are no longer valid and
30  // direct copying between lsm data/flux vars cannot be done in a parfor.
31 
32  // Set box array for lsm data
33  IntVect ng(0,0,1);
34  BoxArray ba = cons_in.boxArray();
35  DistributionMapping dm = cons_in.DistributionMap();
36  BoxList bl_lsm = ba.boxList();
37  for (auto& b : bl_lsm) {
38  b.setBig(2,khi_lsm); // First point below the surface
39  b.setSmall(2,khi_lsm - m_nz_lsm + 1); // Last point below the surface
40  }
41  BoxArray ba_lsm(std::move(bl_lsm));
42 
43  // Set up lsm geometry
44  const RealBox& dom_rb = m_geom.ProbDomain();
45  const Real* dom_dx = m_geom.CellSize();
46  RealBox lsm_rb = dom_rb;
47  Real lsm_dx[AMREX_SPACEDIM] = {AMREX_D_DECL(dom_dx[0],dom_dx[1],m_dz_lsm)};
48  Real lsm_z_hi = dom_rb.lo(2);
49  Real lsm_z_lo = lsm_z_hi - Real(m_nz_lsm)*lsm_dx[2];
50  lsm_rb.setHi(2,lsm_z_hi); lsm_rb.setLo(2,lsm_z_lo);
51  m_lsm_geom.define( ba_lsm.minimalBox(), lsm_rb, m_geom.Coord(), m_geom.isPeriodic() );
52 
53  // Create the data and fluxes
54  for (auto ivar = 0; ivar < LsmVar_SLM::NumVars; ++ivar) {
55  // State vars are CC
57  lsm_fab_vars[ivar] = std::make_shared<MultiFab>(ba_lsm, dm, 1, ng);
58  lsm_fab_vars[ivar]->setVal(theta_0);
59 
60  // Fluxes are nodal in z
61  lsm_fab_flux[ivar] = std::make_shared<MultiFab>(convert(ba_lsm, IntVect(0,0,1)), dm, 1, IntVect(0,0,0));
62  lsm_fab_flux[ivar]->setVal(0.);
63  }
64 }
Real theta_0
Definition: ERF_InitCustomPert_SquallLine.H:46
amrex::Vector< std::string > LsmVarName
Definition: ERF_SLM.H:122
int m_lsm_size
Definition: ERF_SLM.H:116
amrex::Real m_dz_lsm
Definition: ERF_SLM.H:153
amrex::Geometry m_geom
Definition: ERF_SLM.H:125
int m_nz_lsm
Definition: ERF_SLM.H:150
amrex::Vector< int > LsmVarMap
Definition: ERF_SLM.H:119
amrex::Real m_theta_dir
Definition: ERF_SLM.H:162
@ NumVars
Definition: ERF_SLM.H:21
@ ng
Definition: ERF_Morrison.H:49

◆ Lsm_Data_Ptr()

amrex::MultiFab* SLM::Lsm_Data_Ptr ( const int &  varIdx)
inlineoverridevirtual

Reimplemented from NullSurf.

82  {
83  int lsmIdx = LsmVarMap[varIdx];
84  AMREX_ALWAYS_ASSERT(lsmIdx < SLM::m_lsm_size && lsmIdx>=0);
85  return lsm_fab_vars[lsmIdx].get();
86  }
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
Here is the call graph for this function:

◆ Lsm_Data_Size()

int SLM::Lsm_Data_Size ( )
inlineoverridevirtual

Reimplemented from NullSurf.

103 { return SLM::m_lsm_size; }

◆ Lsm_DataName()

std::string SLM::Lsm_DataName ( const int &  varIdx)
inlineoverridevirtual

Reimplemented from NullSurf.

108  {
109  int lsmIdx = LsmVarMap[varIdx];
110  AMREX_ALWAYS_ASSERT(lsmIdx < SLM::m_lsm_size && lsmIdx>=0);
111  return LsmVarName[lsmIdx];
112  }
Here is the call graph for this function:

◆ Lsm_Flux_Ptr()

amrex::MultiFab* SLM::Lsm_Flux_Ptr ( const int &  varIdx)
inlineoverridevirtual

Reimplemented from NullSurf.

91  {
92  int lsmIdx = LsmVarMap[varIdx];
93  AMREX_ALWAYS_ASSERT(lsmIdx < SLM::m_lsm_size && lsmIdx>=0);
94  return lsm_fab_flux[lsmIdx].get();
95  }
Here is the call graph for this function:

◆ Lsm_Geom()

amrex::Geometry SLM::Lsm_Geom ( )
inlineoverridevirtual

Reimplemented from NullSurf.

99 { return m_lsm_geom; }

Member Data Documentation

◆ khi_lsm

int SLM::khi_lsm
private

◆ lsm_fab_flux

amrex::Array<FabPtr, LsmVar_SLM::NumVars> SLM::lsm_fab_flux
private

Referenced by Lsm_Flux_Ptr().

◆ lsm_fab_vars

amrex::Array<FabPtr, LsmVar_SLM::NumVars> SLM::lsm_fab_vars
private

Referenced by Lsm_Data_Ptr().

◆ LsmVarMap

amrex::Vector<int> SLM::LsmVarMap
private

◆ LsmVarName

amrex::Vector<std::string> SLM::LsmVarName
private

Referenced by Lsm_DataName().

◆ m_cp_soil

amrex::Real SLM::m_cp_soil = amrex::Real(1.26e6)
private

◆ m_d_soil

amrex::Real SLM::m_d_soil = m_k_soil / m_cp_soil
private

◆ m_dt

double SLM::m_dt
private

Referenced by Advance().

◆ m_dz_lsm

amrex::Real SLM::m_dz_lsm = amrex::Real(0.1)
private

◆ m_geom

amrex::Geometry SLM::m_geom
private

◆ m_k_soil

amrex::Real SLM::m_k_soil = amrex::Real(0.2)
private

◆ m_lsm_geom

amrex::Geometry SLM::m_lsm_geom
private

Referenced by Lsm_Geom().

◆ m_lsm_size

int SLM::m_lsm_size = 1
private

Referenced by Lsm_Data_Size().

◆ m_nz_lsm

int SLM::m_nz_lsm = 30
private

◆ m_theta_dir

amrex::Real SLM::m_theta_dir = amrex::Real(400.0)
private

The documentation for this class was generated from the following files: