ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ForestDrag Class Reference

#include <ERF_ForestDrag.H>

Collaboration diagram for ForestDrag:

Public Member Functions

 ForestDrag (std::string forestfile)
 
 ~ForestDrag ()=default
 
void define_drag_field (const amrex::BoxArray &ba, const amrex::DistributionMapping &dm, amrex::Geometry &geom, amrex::MultiFab *z_phys_cc, amrex::MultiFab *z_phys_nd)
 
amrex::MultiFab * get_drag_field ()
 

Private Attributes

amrex::Vector< amrex::Real > m_type_forest
 
amrex::Vector< amrex::Real > m_x_forest
 
amrex::Vector< amrex::Real > m_y_forest
 
amrex::Vector< amrex::Real > m_height_forest
 
amrex::Vector< amrex::Real > m_diameter_forest
 
amrex::Vector< amrex::Real > m_cd_forest
 
amrex::Vector< amrex::Real > m_lai_forest
 
amrex::Vector< amrex::Real > m_laimax_forest
 
std::unique_ptr< amrex::MultiFab > m_forest_drag
 

Constructor & Destructor Documentation

◆ ForestDrag()

ForestDrag::ForestDrag ( std::string  forestfile)
explicit
10 {
11  std::ifstream file(forestfile, std::ios::in);
12  if (!file.good()) {
13  Abort("Cannot find forest file: " + forestfile);
14  }
15  // TreeType xc yc height diameter cd lai laimax
16  Real value1, value2, value3, value4, value5, value6, value7, value8;
17  while (file >> value1 >> value2 >> value3 >> value4 >> value5 >> value6 >>
18  value7 >> value8) {
19  m_type_forest.push_back(value1);
20  m_x_forest.push_back(value2);
21  m_y_forest.push_back(value3);
22  m_height_forest.push_back(value4);
23  m_diameter_forest.push_back(value5);
24  m_cd_forest.push_back(value6);
25  m_lai_forest.push_back(value7);
26  m_laimax_forest.push_back(value8);
27  }
28  file.close();
29 }
amrex::Vector< amrex::Real > m_diameter_forest
Definition: ERF_ForestDrag.H:35
amrex::Vector< amrex::Real > m_laimax_forest
Definition: ERF_ForestDrag.H:38
amrex::Vector< amrex::Real > m_lai_forest
Definition: ERF_ForestDrag.H:37
amrex::Vector< amrex::Real > m_x_forest
Definition: ERF_ForestDrag.H:32
amrex::Vector< amrex::Real > m_height_forest
Definition: ERF_ForestDrag.H:34
amrex::Vector< amrex::Real > m_cd_forest
Definition: ERF_ForestDrag.H:36
amrex::Vector< amrex::Real > m_type_forest
Definition: ERF_ForestDrag.H:31
amrex::Vector< amrex::Real > m_y_forest
Definition: ERF_ForestDrag.H:33

◆ ~ForestDrag()

ForestDrag::~ForestDrag ( )
default

Member Function Documentation

◆ define_drag_field()

void ForestDrag::define_drag_field ( const amrex::BoxArray &  ba,
const amrex::DistributionMapping &  dm,
amrex::Geometry &  geom,
amrex::MultiFab *  z_phys_cc,
amrex::MultiFab *  z_phys_nd 
)
37 {
38  // Geometry params
39  const auto& dx = geom.CellSizeArray();
40  const auto& prob_lo = geom.ProbLoArray();
41 
42  bool all_boxes_touch_bottom = true;
43  for (int i = 0; i < ba.size(); i++) {
44  if (ba[i].smallEnd(2) != geom.ProbLo(2)) {
45  all_boxes_touch_bottom = false;
46  }
47  }
48  AMREX_ALWAYS_ASSERT(all_boxes_touch_bottom);
49 
50  // Allocate the forest drag MF
51  // NOTE: 1 ghost cell for averaging to faces
52  m_forest_drag.reset();
53  m_forest_drag = std::make_unique<MultiFab>(ba,dm,1,1);
54  m_forest_drag->setVal(0.);
55 
56  // Loop over forest types and pre-compute factors
57  for (unsigned ii = 0; ii < m_x_forest.size(); ++ii)
58  {
59  // Expose CPU data for GPU capture
60  Real af; // Depends upon the type of forest (tf)
61  Real treeZm = 0.0; // Only for forest type 2
62  int tf = int(m_type_forest[ii]);
63  Real hf = m_height_forest[ii];
64  Real xf = m_x_forest[ii];
65  Real yf = m_y_forest[ii];
66  Real df = m_diameter_forest[ii];
67  Real cdf = m_cd_forest[ii];
68  Real laif = m_lai_forest[ii];
69  Real laimaxf = m_laimax_forest[ii];
70  if (tf == 1) {
71  // Constant factor
72  af = laif / hf;
73  } else {
74  // Discretize integral with 100 points and pre-compute
75  int nk = 100;
76  Real ztree = 0;
77  Real expFun = 0;
78  Real ratio = 0;
79  const Real dz = hf / Real(nk);
80  treeZm = laimaxf * hf;
81  for (int k(0); k<nk; ++k) {
82  ratio = (hf - treeZm) / (hf - ztree);
83  if (ztree < treeZm) {
84  expFun += std::pow(ratio, 6.0) *
85  std::exp(6 * (1 - ratio));
86  } else {
87  expFun += std::pow(ratio, 0.5) *
88  std::exp(0.5 * (1 - ratio));
89  }
90  ztree += dz;
91  }
92  af = laif / (expFun * dz);
93  }
94 
95  // Set the forest drag data
96  for (MFIter mfi(*m_forest_drag); mfi.isValid(); ++mfi) {
97  Box gtbx = mfi.growntilebox();
98  const Array4<Real>& levelDrag = m_forest_drag->array(mfi);
99  const Array4<const Real>& z_cc = z_phys_cc->const_array(mfi);
100  const Array4<const Real>& z_nd = z_phys_nd->const_array(mfi);
101 
102  ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
103  {
104  // Physical positions of cell-centers
105  const Real x = prob_lo[0] + (i + 0.5) * dx[0];
106  const Real y = prob_lo[1] + (j + 0.5) * dx[1];
107 
108  // "z" is measured as distance from cell center to ground
109  const Real z_sfc = 0.25 * ( z_nd(i,j ,0) + z_nd(i+1,j ,0)
110  +z_nd(i,j+1,0) + z_nd(i+1,j+1,0));
111  const Real z = std::max((z_cc(i,j,k)-z_sfc),0.0);
112 
113  // Proximity to the forest
114  const Real radius = std::sqrt((x - xf) * (x - xf) +
115  (y - yf) * (y - yf));
116 
117  // Hit for canopy region
118  Real factor = 1;
119  if ((z <= hf) && (radius <= (0.5 * df))) {
120  if (tf == 2) {
121  Real ratio = (hf - treeZm) / (hf - z);
122  if (z < treeZm) {
123  factor = std::pow(ratio, 6.0) *
124  std::exp(6.0 * (1.0 - ratio));
125  } else if (z <= hf) {
126  factor = std::pow(ratio, 0.5) *
127  std::exp(0.5 * (1.0 - ratio));
128  }
129  }
130  levelDrag(i, j, k) = cdf * af * factor;
131  }
132  });
133  } // mfi
134  } // ii (forest type)
135 
136  // Fillboundary for periodic ghost cell copy
137  m_forest_drag->FillBoundary(geom.periodicity());
138 
139 } // init_drag_field
std::unique_ptr< amrex::MultiFab > m_forest_drag
Definition: ERF_ForestDrag.H:39

◆ get_drag_field()

amrex::MultiFab* ForestDrag::get_drag_field ( )
inline
28 { return m_forest_drag.get(); }

Member Data Documentation

◆ m_cd_forest

amrex::Vector<amrex::Real> ForestDrag::m_cd_forest
private

◆ m_diameter_forest

amrex::Vector<amrex::Real> ForestDrag::m_diameter_forest
private

◆ m_forest_drag

std::unique_ptr<amrex::MultiFab> ForestDrag::m_forest_drag
private

Referenced by get_drag_field().

◆ m_height_forest

amrex::Vector<amrex::Real> ForestDrag::m_height_forest
private

◆ m_lai_forest

amrex::Vector<amrex::Real> ForestDrag::m_lai_forest
private

◆ m_laimax_forest

amrex::Vector<amrex::Real> ForestDrag::m_laimax_forest
private

◆ m_type_forest

amrex::Vector<amrex::Real> ForestDrag::m_type_forest
private

◆ m_x_forest

amrex::Vector<amrex::Real> ForestDrag::m_x_forest
private

◆ m_y_forest

amrex::Vector<amrex::Real> ForestDrag::m_y_forest
private

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