ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_ForestDrag.H
Go to the documentation of this file.
1 #ifndef ERF_FORESTDRAG_H_
2 #define ERF_FORESTDRAG_H_
3 
4 #include <memory>
5 #include <AMReX_MultiFab.H>
6 
7 /**
8  * Build canopy leaf-area-density and momentum-drag fields.
9  *
10  * The vertical leaf-area-density profiles follow Lalic and Mihailovic (2004),
11  * https://doi.org/10.1175/1520-0450(2004)043%3C0641:AERDLD%3E2.0.CO;2.
12  * Canopies may be supplied as discrete patches in a text file or as gridded
13  * LAI, height, and drag-coefficient NetCDF fields.
14  */
16 {
17 public:
18 
19  /** Construct a discrete-patch canopy from a text file. */
20  explicit ForestDrag (std::string forestfile);
21 
22  /**
23  * Construct a gridded canopy with drag coefficient read from NetCDF.
24  * @param lai_file NetCDF file containing the horizontal ``LAI`` field.
25  * @param height_file NetCDF file containing canopy ``height``.
26  * @param cd_file NetCDF file containing the ``cd`` field.
27  * @param tree_type LAD profile selector (1 uniform, 2 Lalic--Mihailovic).
28  * @param laimax Fractional height of maximum LAD for profile type 2.
29  */
30  ForestDrag (std::string lai_file,
31  std::string height_file,
32  std::string cd_file,
33  int tree_type = 1,
34  amrex::Real laimax = 0.8);
35 
36  /**
37  * Construct a gridded canopy with a spatially constant drag coefficient.
38  * @param lai_file NetCDF file containing the horizontal ``LAI`` field.
39  * @param height_file NetCDF file containing canopy ``height``.
40  * @param cd_const Spatially constant drag coefficient.
41  * @param tree_type LAD profile selector (1 uniform, 2 Lalic--Mihailovic).
42  * @param laimax Fractional height of maximum LAD for profile type 2.
43  */
44  ForestDrag (std::string lai_file,
45  std::string height_file,
46  amrex::Real cd_const,
47  int tree_type = 1,
48  amrex::Real laimax = 0.8);
49 
50  ~ForestDrag () = default;
51 
52  /** Allocate and fill drag and, optionally, frontal-area-density fields.
53  *
54  * @param need_frontal_area Allocate the frontal-area-density field, which
55  * is only consumed by the fixed-leaf-temperature path.
56  * @param level Level index, used only in diagnostic messages.
57  *
58  * Neither argument is defaulted on purpose: every caller must state
59  * whether the frontal-area field is needed, so that a new call site cannot
60  * silently allocate and fill it when forest biophysics is off, nor report
61  * a placeholder level in the coverage warning.
62  */
63  void
64  define_drag_field (const amrex::BoxArray& ba,
65  const amrex::DistributionMapping& dm,
66  amrex::Geometry& geom,
67  amrex::MultiFab* z_phys_cc,
68  amrex::MultiFab* z_phys_nd,
69  bool need_frontal_area,
70  int level);
71 
72  /** Return the cell-centered product of drag coefficient and LAD. */
73  amrex::MultiFab*
74  get_drag_field () { return m_forest_drag.get(); }
75 
76  /** Return cell-centered leaf/frontal area density without drag coefficient. */
77  amrex::MultiFab*
78  get_frontal_area () { return m_frontal_area.get(); }
79 
80 private:
81  // Mode flag: true for gridded NetCDF, false for discrete patches
82  bool m_use_gridded_data{false};
83 
84  // Frontal-area storage is only needed by the fixed-leaf-temperature path.
85  bool m_need_frontal_area{true};
86 
87  // Constant Cd mode (skips Cd file; used when forest_cd = value is specified)
88  bool m_use_const_cd{false};
90 
91  // Discrete patch data (for text file mode)
92  amrex::Vector<amrex::Real> m_type_forest;
93  amrex::Vector<amrex::Real> m_x_forest;
94  amrex::Vector<amrex::Real> m_y_forest;
95  amrex::Vector<amrex::Real> m_height_forest;
96  amrex::Vector<amrex::Real> m_diameter_forest;
97  amrex::Vector<amrex::Real> m_cd_forest;
98  amrex::Vector<amrex::Real> m_lai_forest;
99  amrex::Vector<amrex::Real> m_laimax_forest;
100 
101  // Gridded data (for NetCDF mode) - stored on CPU
102  amrex::Vector<amrex::Real> m_gridded_lai;
103  amrex::Vector<amrex::Real> m_gridded_height;
104  amrex::Vector<amrex::Real> m_gridded_cd;
105  // Grid metadata for gridded data
106  int m_grid_nx{0};
107  int m_grid_ny{0};
112 
113  // Tree type and LAImax for gridded data (applies to entire domain)
114  int m_tree_type{1};
116  // Dimensionless integral of the type-2 Lalic--Mihailovic profile. It is
117  // independent of horizontal position and canopy height, so compute it
118  // once on the host rather than once per canopy cell.
120 
121  // Output drag field: Cd * a(z)
122  std::unique_ptr<amrex::MultiFab> m_forest_drag;
123 
124  // Frontal area density a(z) (without Cd factor)
125  std::unique_ptr<amrex::MultiFab> m_frontal_area;
126 
127  // Helper: read gridded data from a NetCDF file
128  void read_netcdf_file (const std::string& filename,
129  const std::string& varname,
130  amrex::Vector<amrex::Real>& data,
131  int& nx, int& ny,
133  amrex::Real& xmin, amrex::Real& ymin);
134 
135 };
136 #endif
const Real dy
Definition: ERF_InitCustomPert_ABL.H:45
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_ForestDrag.H:16
ForestDrag(std::string forestfile)
Definition: ERF_ForestDrag.cpp:116
amrex::Real m_lad_normalization
Definition: ERF_ForestDrag.H:119
amrex::Vector< amrex::Real > m_diameter_forest
Definition: ERF_ForestDrag.H:96
bool m_need_frontal_area
Definition: ERF_ForestDrag.H:85
amrex::Real m_grid_xmin
Definition: ERF_ForestDrag.H:110
amrex::Real m_grid_dy
Definition: ERF_ForestDrag.H:109
amrex::Vector< amrex::Real > m_laimax_forest
Definition: ERF_ForestDrag.H:99
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, bool need_frontal_area, int level)
Definition: ERF_ForestDrag.cpp:283
int m_grid_nx
Definition: ERF_ForestDrag.H:106
void read_netcdf_file(const std::string &filename, const std::string &varname, amrex::Vector< amrex::Real > &data, int &nx, int &ny, amrex::Real &dx, amrex::Real &dy, amrex::Real &xmin, amrex::Real &ymin)
amrex::Vector< amrex::Real > m_gridded_lai
Definition: ERF_ForestDrag.H:102
int m_tree_type
Definition: ERF_ForestDrag.H:114
amrex::Vector< amrex::Real > m_gridded_height
Definition: ERF_ForestDrag.H:103
amrex::Vector< amrex::Real > m_lai_forest
Definition: ERF_ForestDrag.H:98
amrex::Vector< amrex::Real > m_x_forest
Definition: ERF_ForestDrag.H:93
amrex::Vector< amrex::Real > m_height_forest
Definition: ERF_ForestDrag.H:95
amrex::Real m_grid_dx
Definition: ERF_ForestDrag.H:108
amrex::Real m_laimax
Definition: ERF_ForestDrag.H:115
std::unique_ptr< amrex::MultiFab > m_frontal_area
Definition: ERF_ForestDrag.H:125
amrex::Vector< amrex::Real > m_gridded_cd
Definition: ERF_ForestDrag.H:104
amrex::Vector< amrex::Real > m_cd_forest
Definition: ERF_ForestDrag.H:97
amrex::MultiFab * get_drag_field()
Definition: ERF_ForestDrag.H:74
amrex::Real m_cd_const
Definition: ERF_ForestDrag.H:89
bool m_use_gridded_data
Definition: ERF_ForestDrag.H:82
std::unique_ptr< amrex::MultiFab > m_forest_drag
Definition: ERF_ForestDrag.H:122
~ForestDrag()=default
amrex::Vector< amrex::Real > m_type_forest
Definition: ERF_ForestDrag.H:92
int m_grid_ny
Definition: ERF_ForestDrag.H:107
bool m_use_const_cd
Definition: ERF_ForestDrag.H:88
amrex::Real m_grid_ymin
Definition: ERF_ForestDrag.H:111
amrex::MultiFab * get_frontal_area()
Definition: ERF_ForestDrag.H:78
amrex::Vector< amrex::Real > m_y_forest
Definition: ERF_ForestDrag.H:94