ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
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_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:34
amrex::Vector< amrex::Real > m_laimax_forest
Definition: ERF_ForestDrag.H:37
amrex::Vector< amrex::Real > m_lai_forest
Definition: ERF_ForestDrag.H:36
amrex::Vector< amrex::Real > m_x_forest
Definition: ERF_ForestDrag.H:31
amrex::Vector< amrex::Real > m_height_forest
Definition: ERF_ForestDrag.H:33
amrex::Vector< amrex::Real > m_cd_forest
Definition: ERF_ForestDrag.H:35
amrex::Vector< amrex::Real > m_type_forest
Definition: ERF_ForestDrag.H:30
amrex::Vector< amrex::Real > m_y_forest
Definition: ERF_ForestDrag.H:32

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

◆ get_drag_field()

amrex::MultiFab* ForestDrag::get_drag_field ( )
inline
27 { 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: