ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_IBFaceSet.H
Go to the documentation of this file.
1 #ifndef ERF_IB_FACE_SET_H
2 #define ERF_IB_FACE_SET_H
3 
4 #include <AMReX_MultiFab.H>
5 #include <AMReX_BoxArray.H>
6 #include <AMReX_DistributionMapping.H>
7 #include <AMReX_Geometry.H>
8 #include <AMReX_GpuContainers.H>
9 #include <vector>
10 #include "ERF_IBSEBParams.H"
11 #include "ERF_IBSEBMaterials.H"
12 
13 /**
14  * \file ERF_IBFaceSet.H
15  * \brief Compact list of the wall faces of resolved buildings on one AMR level.
16  *
17  * **What a face is.** The immersed forcing marks every cell of a level as
18  * fluid or solid through the cell-centred blanking ``terrain_blanking``
19  * (one minus the embedded-boundary volume fraction, so 0 in the air and 1
20  * inside a building). A wall face is the cell face between a fluid cell
21  * (blanking below 0.5) and a solid cell (blanking at or above 0.5). Walls
22  * are x or y faces, roofs are z faces with the fluid above the solid.
23  *
24  * **Face convention.** A face is identified by its *fluid* cell ``(i, j, k)``,
25  * its direction ``dir`` (0 = x, 1 = y, 2 = z) and its ``side`` (-1 when the
26  * solid neighbour is at ``i-1`` / ``j-1`` / ``k-1``, +1 when it is at
27  * ``i+1`` / ``j+1`` / ``k+1``). The outward unit normal of the wall, pointing
28  * into the fluid, is therefore ``-side`` along ``dir``. The fluid cell is where
29  * every atmospheric input of the balance (wind, temperature, humidity,
30  * radiation) is read and where the wall's heat flux is deposited.
31  *
32  * **Ownership and layout.** Each face is stored exactly once, on the rank
33  * that owns its fluid cell, so the per-step update of the balance is a kernel
34  * over this rank's faces with no communication; only the reports reduce
35  * across ranks. The faces are a struct of device arrays (one
36  * ``amrex::Gpu::DeviceVector`` per quantity, all indexed by the face number)
37  * and are stored contiguously per local fab in MFIter order:
38  * ``fab_start()[mfi.LocalIndex()]`` to ``fab_start()[mfi.LocalIndex()+1]``
39  * are the faces whose fluid cell is in that fab, which is what lets a kernel
40  * scatter into that fab's arrays without a search.
41  *
42  * **Building ids.** The solid columns of the blanking (any solid cell in the
43  * column) are labelled by 4-connectivity in the horizontal and numbered in
44  * scan order over ``(i, j)``, identically on every rank from a reduced column
45  * mask; a face carries the id of the column of its solid neighbour. Ids are
46  * 1-based, 0 is never assigned.
47  *
48  * **Output.** The list is never written directly. scatter_diagnostics() puts
49  * the number of faces and their mean skin temperature into cell-centred
50  * fields for the plotfile; save_state() / load_state() move the skin
51  * temperature, the sensible flux and the slab temperatures through a
52  * cell-centred field with one slot per face of a cell (see state_ncomp())
53  * for the checkpoint. On restart the list is rebuilt from the blanking and
54  * refilled from that field, so a restart does not depend on the rank count
55  * or on the order the faces were found in.
56  *
57  * **Per-step order.** build() detects and stores the faces and
58  * compute_view_fractions() fills ``d_f_sky`` / ``d_f_ground`` / ``d_f_bldg``
59  * once at initialisation; every step then runs compute_shortwave(),
60  * compute_longwave(), compute_sensible() and, with ``erf.ibseb.prognostic``,
61  * solve_balance(), which finds the skin temperature closing the balance,
62  * advances the slab with it and rewrites the fluxes at the solution; without
63  * it compute_ground() advances the slab under the fixed skin. ``d_Q_ext`` is
64  * the hook through which an external incident flux (a fire's radiation)
65  * enters without the balance knowing its source: whoever owns it writes the
66  * array before solve_balance() runs.
67  */
68 class IBFaceSet
69 {
70 public:
71  /**
72  * Construct an empty face set for one level; build() fills it.
73  * @param params Inputs of the balance (copied; the set never reads ParmParse).
74  * @param lev AMR level the set belongs to, for reports only.
75  */
76  IBFaceSet (const IBSEBParams& params, int lev) : m_params(params), m_lev(lev) {}
77 
78  /**
79  * Detect this rank's faces from the cell-centred blanking and allocate
80  * every per-face array.
81  *
82  * Runs on the host once at initialisation: the blanking is copied fab by
83  * fab (a pinned copy on GPU builds), the valid cells are scanned, and the
84  * arrays are uploaded to the device at the end. Must be called after the
85  * blanking has been built and its ghost cells filled, since the solid
86  * neighbour of a fluid cell on a box edge lives in a ghost cell.
87  *
88  * @param blanking Cell-centred blanking of the level (needs at least one
89  * ghost cell, filled).
90  * @param geom Geometry of the level: cell sizes for the face areas,
91  * domain and periodicity for the neighbour tests.
92  */
93  void build (const amrex::MultiFab& blanking, const amrex::Geometry& geom);
94 
95  /** Number of faces owned by this rank (not the global count; see report()). */
96  int n_faces () const { return m_nface; }
97  /** Number of buildings of the level, the same on every rank. */
98  int n_buildings () const { return m_nbld; }
99  /** Conduction layers per face, from ``erf.ibseb.n_slab_layers``. */
100  int n_layers () const { return m_params.n_slab_layers; }
101 
102  /**
103  * Number of components of the checkpoint state field.
104  *
105  * The field carries n_slots() slots of ``2 + n_layers()`` values per cell:
106  * component ``slot * (2 + n_layers())`` is the skin temperature of that
107  * slot, the next its sensible flux (read as the previous step's by the
108  * convective velocity scale), and the following ``n_layers()`` components
109  * are its slab layers.
110  *
111  * A cell carries one slot per face it owns, numbered in the ``(dir, side)``
112  * order in which build() finds them, so the width is the largest face
113  * count on any one cell of the level rather than the six a cell could hold
114  * in principle. Around ordinary buildings that maximum is two or three (an
115  * outside edge or corner); six needs a one-cell slot. build() rebuilds the
116  * numbering from the same blanking on restart, so the slots line up
117  * whatever the rank count.
118  */
119  int state_ncomp () const { return m_nslots * (2 + n_layers()); }
120 
121  /** Slots per cell of the checkpoint field: the largest face count on a cell of the level. */
122  int n_slots () const { return m_nslots; }
123 
124  /**
125  * Boxes of the checkpoint field: 4 x 4 column blocks clipped to the
126  * k-range that actually owns faces, so the field follows the shell of
127  * face-owning cells rather than the built volume. A block over the
128  * interior of a wide footprint keeps only the layer above the roof, while
129  * a block on a wall still spans its height. Built identically on every
130  * rank by build() from a reduced block k-range map; the same buildings
131  * give the same boxes on restart, whatever the rank count. Empty when the
132  * level has no faces.
133  */
134  const amrex::BoxArray& state_boxarray () const { return m_state_ba; }
135  /** Whether the level has a checkpoint field to write (any faces at all). */
136  bool has_state () const { return !m_state_ba.empty(); }
137  /** A field on state_boxarray() with state_ncomp() components, for the checkpoint. */
138  amrex::MultiFab make_state () const;
139 
140  /**
141  * View fractions: sample a cosine-weighted hemisphere around
142  * every face's outward normal with ``view_n_az x view_n_el`` rays through
143  * the column walk and count where they end: sky, ground or a building.
144  * The three fractions sum to one and are view factors. Called once at
145  * initialisation; the geometry is static.
146  */
147  void compute_view_fractions ();
148 
149  /**
150  * Longwave of the current step. Incoming on a face:
151  * ``f_sky LW_sky + f_ground eps_g sigma T_g^4 + f_bldg sigma T_skin^4``,
152  * the sky term fixed or gray (``sky_emissivity sigma T_air^4`` with the
153  * air temperature of the face's fluid cell), the building term the
154  * isothermal-surroundings approximation. Net:
155  * ``eps (LW_in - sigma T_skin^4)``, positive into the face.
156  * @param cons Conserved state of the level, for the air temperature.
157  */
158  void compute_longwave (const amrex::MultiFab& cons);
159 
160  /**
161  * Assign every face its material properties: from the material
162  * library by building id, or the uniform inputs. Called once after
163  * build(); fills d_mat, d_albedo, d_emis, d_k, d_rhocp, d_thick and
164  * initialises the slab layers to the skin temperature.
165  */
166  void assign_materials ();
167 
168  /**
169  * Ground heat flux of the current step: advance every face's
170  * slab by dt with the skin temperature at the top and the interior
171  * temperature at the bottom (implicit, ERF_IBSEBSlab.H) and store the
172  * conduction into the slab, G, positive into the wall.
173  */
174  void compute_ground (amrex::Real dt);
175 
176  /**
177  * Prognostic balance of the current step. Per face: the
178  * slab's linear response to the skin temperature for this step, the
179  * Newton solve of ERF_IBSEBBalance.H with the shortwave, the external
180  * flux, the sky and ground longwave, the frozen wall-function
181  * coefficient and the latent flux, the slab advanced with the solution,
182  * and the fluxes (LW_in, LW_net, H, G) rewritten at the solution. Fills
183  * d_resid (|balance| at the end, non-zero only at a bound or the
184  * iteration cap) and d_niter. Needs compute_shortwave(),
185  * compute_longwave() and compute_sensible() of the same step first.
186  * @param dt Atmospheric time step [s], the slab's step.
187  */
188  void solve_balance (amrex::Real dt);
189 
190  /**
191  * Sensible heat of the current step through a wall function on
192  * every face: the tangential wind of the fluid cell at half a cell from
193  * the wall gives u* with the roughness z0_wall, the skin-to-air
194  * potential-temperature difference gives theta* with z0h_wall, and
195  * H = rho c_p u* theta*, positive out of the face. Neutral, or with the
196  * surface layer's stability functions on roofs when asked. The latent
197  * flux is not modelled and stays zero.
198  *
199  * Beyond neutral: with ``convective_velocity = deardorff`` the
200  * wind is ``sqrt(U_tan^2 + (beta w*)^2)`` with w* from the previous
201  * step's H (zero when H is into the face) and a depth that is the mixed
202  * layer above a roof or the building height for a wall; with
203  * ``stability_correction`` the roofs iterate the similarity functions on
204  * the face's own Obukhov length, seeded from the ground surface layer's
205  * 2D field at the face's column when given.
206  *
207  * Fills d_H, d_ustar, d_U_tan, d_rho, d_theta_air, d_H_coeff (the
208  * coefficient of the skin-to-air potential-temperature difference that
209  * the balance keeps frozen), d_w_star, d_olen and d_z_i; T_air was read
210  * by compute_longwave(), which must run first in a step.
211  * @param cons Conserved state of the level (density, rho theta).
212  * @param xvel, yvel, zvel Face-centred velocities of the level.
213  * @param c_p Specific heat of air [J/kg/K].
214  * @param olen_ground Ground surface layer's Obukhov length (2D field on
215  * the level's box array collapsed to k = 0), or null.
216  * @param pblh_ground Its boundary-layer height field, or null.
217  * @param z_i_bulk Mixed-layer depth of the level from the bulk
218  * Richardson diagnostic or the fixed input [m].
219  */
220  void compute_sensible (const amrex::MultiFab& cons, const amrex::MultiFab& xvel,
221  const amrex::MultiFab& yvel, const amrex::MultiFab& zvel, amrex::Real c_p,
222  const amrex::MultiFab* olen_ground = nullptr,
223  const amrex::MultiFab* pblh_ground = nullptr,
224  amrex::Real z_i_bulk = 0.0);
225 
226  /**
227  * Add the face heat flux to the temperature equation: every face
228  * deposits ``H A / (c_p V Pi)`` into the rho-theta source of its fluid
229  * cell (Pi the Exner function, so the flux heats the cell by H A / (c_p V)
230  * in temperature). Called after the sources are rebuilt at every slow
231  * stage; adds, never overwrites, and uses atomic adds because a corner
232  * cell receives several faces.
233  */
234  void add_heat_flux_to_source (amrex::MultiFab& source, const amrex::MultiFab& cons,
235  const amrex::Geometry& geom, amrex::Real c_p, amrex::Real rdOcp) const;
236 
237  /**
238  * Shortwave of the current step: sun position and irradiances
239  * from the prescribed provider, then per face the direct beam on the
240  * face (zero when the ray toward the sun hits a building), the diffuse
241  * light through the view fractions, and the absorbed sum.
242  *
243  * Fills d_shadow, d_SW_direct_in, d_SW_diffuse_in and d_SW_abs; stores
244  * the sun vector and irradiances for the reports.
245  * @param time Simulation time [s]; with sun_mode = solar it is added to
246  * time_zero_utc_s.
247  */
248  void compute_shortwave (amrex::Real time);
249 
250  /**
251  * Scatter one per-face array into a cell-centred field as the mean over
252  * the faces touching each cell (zero where there are none).
253  */
254  void scatter_field (const amrex::Gpu::DeviceVector<amrex::Real>& v, amrex::MultiFab& out) const;
255 
256  /**
257  * Write every face of this rank to ``<prefix>.rank<N>.csv`` with its
258  * geometry, view fractions, shadow flag, shortwave terms and skin
259  * temperature, for the regression tests and for users who want the raw list.
260  */
261  void dump_faces (const std::string& prefix) const;
262 
263  /**
264  * Scatter the faces into two cell-centred diagnostics for the plotfile.
265  *
266  * @param[out] nfaces Number of wall faces touching each fluid cell (0 away
267  * from buildings; up to 3 at an outside corner, 6 in a
268  * one-cell slot).
269  * @param[out] tskin Mean skin temperature of those faces, 0 where there
270  * are none.
271  *
272  * Both fields must be on the level's box array with no ghost cells. Faces
273  * of one fab are accumulated with atomic adds because a corner cell
274  * receives several faces.
275  */
276  void scatter_diagnostics (amrex::MultiFab& nfaces, amrex::MultiFab& tskin) const;
277 
278  /**
279  * Write the face state (skin temperature, sensible flux and slab
280  * temperatures) into a field from make_state(), for the checkpoint.
281  *
282  * The faces of this rank are written into a transfer field on this
283  * rank's grids cut by the state boxes, which a ParallelCopy moves onto
284  * the state's own distribution. Each face writes its own slot (see
285  * state_ncomp()), so no two faces touch the same component of the same
286  * cell and no atomics are needed; cells without a face in a slot keep
287  * zero there.
288  */
289  void save_state (amrex::MultiFab& state) const;
290 
291  /**
292  * Read the face state (skin, flux, slab) back from a field written by
293  * save_state(), after build() has recreated the list from the blanking:
294  * the reverse ParallelCopy onto the transfer field, then each face reads
295  * its slot. Only the slots that correspond to a face of this list are read.
296  */
297  void load_state (const amrex::MultiFab& state);
298 
299  /**
300  * Print the ``[IBSEB]`` summary line and, when asked, append one row per
301  * building to ``erf.ibseb.csv_file``.
302  *
303  * The summary carries the global face counts per direction, the number of
304  * buildings, the total face area and the range of the skin temperature;
305  * the CSV rows carry per building the face count, the area, the
306  * area-weighted mean fluxes and skin temperature with its range, the
307  * largest balance residual, and the sun of the step (zenith, azimuth,
308  * direct-normal and diffuse irradiance). All numbers are reduced over the
309  * ranks; the file is written by the I/O rank only, with a header only
310  * when the file does not exist yet, so a restarted run appends.
311  *
312  * @param time Simulation time [s] written to the rows.
313  * @param step Step number written to the rows.
314  * @param write_csv Whether to append rows, or only print the summary.
315  */
316  void report (amrex::Real time, int step, bool write_csv) const;
317 
318  // ---- Per-face device arrays, indexed by face number ----------------------
319  // Static geometry, set by build():
320  amrex::Gpu::DeviceVector<int> d_i, d_j, d_k; ///< Fluid cell of the face
321  amrex::Gpu::DeviceVector<int> d_dir; ///< Face direction: 0 x, 1 y, 2 z
322  amrex::Gpu::DeviceVector<int> d_side; ///< Solid neighbour at -1 (low) or +1 (high) side
323  amrex::Gpu::DeviceVector<int> d_slot; ///< Slot of the face within its cell's checkpoint record
324  amrex::Gpu::DeviceVector<int> d_bid; ///< Building id (1-based)
325  amrex::Gpu::DeviceVector<int> d_mat; ///< Material id (0 = uniform inputs)
326  amrex::Gpu::DeviceVector<amrex::Real> d_albedo, d_emis;///< Optical properties of the face
327  amrex::Gpu::DeviceVector<amrex::Real> d_kth, d_rhocp, d_thick; ///< Slab conductivity [W/m/K], heat capacity [J/m3/K], thickness [m]
328  amrex::Gpu::DeviceVector<amrex::Real> d_area; ///< Face area [m2]
329  amrex::Gpu::DeviceVector<amrex::Real> d_xf, d_yf, d_zf;///< Face centre [m]
330  // State, advanced by the balance and checkpointed:
331  amrex::Gpu::DeviceVector<amrex::Real> d_T_skin; ///< Skin temperature [K]
332  amrex::Gpu::DeviceVector<amrex::Real> d_T_slab; ///< Slab layers [K], face-major: [face * n_layers + layer]
333  // Static radiative geometry:
334  amrex::Gpu::DeviceVector<amrex::Real> d_f_sky, d_f_ground, d_f_bldg; ///< View fractions, sum to 1
335  // Fluxes of the current step [W/m2]: SW_abs and LW_net positive into the
336  // face, H, LE and G positive out of it:
337  amrex::Gpu::DeviceVector<amrex::Real> d_SW_abs, d_LW_net, d_H, d_LE, d_G;
338  amrex::Gpu::DeviceVector<amrex::Real> d_Q_ext; ///< External incident flux [W/m2], e.g. fire radiation
339  // Shortwave detail, all [W/m2] except the flag:
340  amrex::Gpu::DeviceVector<amrex::Real> d_shadow; ///< 1 when the ray to the sun hits a building, else 0
341  amrex::Gpu::DeviceVector<amrex::Real> d_SW_direct_in; ///< Direct beam incident on the face
342  amrex::Gpu::DeviceVector<amrex::Real> d_SW_diffuse_in; ///< Sky and ground-reflected diffuse incident
343  // Longwave detail [W/m2] and the air temperature read [K]:
344  amrex::Gpu::DeviceVector<amrex::Real> d_LW_down_in; ///< Incoming longwave on the face (sky, ground and walls)
345  amrex::Gpu::DeviceVector<amrex::Real> d_T_air; ///< Air temperature of the fluid cell
346  // Sensible heat detail:
347  amrex::Gpu::DeviceVector<amrex::Real> d_theta_air; ///< Potential temperature of the fluid cell [K]
348  amrex::Gpu::DeviceVector<amrex::Real> d_rho; ///< Density of the fluid cell [kg/m3]
349  amrex::Gpu::DeviceVector<amrex::Real> d_U_tan; ///< Tangential wind speed at the fluid cell [m/s]
350  amrex::Gpu::DeviceVector<amrex::Real> d_ustar; ///< Friction velocity of the wall function [m/s]
351  amrex::Gpu::DeviceVector<amrex::Real> d_H_coeff; ///< H = H_coeff (theta_skin - theta_air) [W/m2/K]
352  // Wall function beyond neutral:
353  amrex::Gpu::DeviceVector<amrex::Real> d_hbld; ///< Height of the face's building column [m]
354  amrex::Gpu::DeviceVector<amrex::Real> d_w_star; ///< Convective velocity scale of the step [m/s]
355  amrex::Gpu::DeviceVector<amrex::Real> d_olen; ///< Obukhov length used [m] (1e30 when neutral)
356  amrex::Gpu::DeviceVector<amrex::Real> d_z_i; ///< Depth in w* [m]: mixed layer above a roof, building height for a wall
357  // Prognostic balance detail:
358  amrex::Gpu::DeviceVector<amrex::Real> d_LW_ext; ///< Incoming longwave from sky and ground only [W/m2]
359  amrex::Gpu::DeviceVector<amrex::Real> d_resid; ///< |balance| after the solve [W/m2]
360  amrex::Gpu::DeviceVector<int> d_niter; ///< Newton iterations of the last solve
361  // Column tops over the bounding box of the built columns (origin
362  // m_col_i0, m_col_j0 in 0-based domain columns, m_col_nx x m_col_ny
363  // values, index (ci - i0) * m_col_ny + (cj - j0)), replicated on every
364  // rank for the ray cast: 4 bytes per built column per rank. Each entry is
365  // the domain-relative k of the highest solid cell of its column, -1 where
366  // the column is fluid; ibseb::column_top() turns it into a height, and
367  // columns outside the box are open ground.
368  amrex::Gpu::DeviceVector<int> d_col_top;
369  int m_col_i0 = 0, m_col_j0 = 0, m_col_nx = 0, m_col_ny = 0;
370 
371  // Checkpoint layout (see state_boxarray()) and the transfer layer of
372  // save_state() / load_state(): this rank's grids cut by the state boxes,
373  // gathered into one global BoxArray owned box by box by the rank whose
374  // grid it came from, with the local grid index each box came from.
375  amrex::BoxArray m_state_ba;
376  amrex::BoxArray m_xfer_ba;
377  amrex::DistributionMapping m_xfer_dm;
378  std::vector<int> m_xfer_src;
379  amrex::Long m_domain_cells = 0; ///< Cells of the level, for the debug summary of the field
380 
381  /// Sun and irradiances of the last compute_shortwave() call, for reports.
382  struct SunState {
383  amrex::Real zenith = 0.0, azimuth = 0.0; ///< [rad]
384  amrex::Real sx = 0.0, sy = 0.0, sz = 1.0; ///< Unit vector toward the sun
385  amrex::Real dni = 0.0; ///< Direct-normal irradiance [W/m2]
386  amrex::Real diffuse_h = 0.0; ///< Diffuse on a horizontal surface [W/m2]
387  };
388  const SunState& sun () const { return m_sun; }
389 
390  /**
391  * Print the ``[IBSEB DEBUG]`` description of the set: the inputs, every
392  * rank's face count and per-fab ranges, the buildings with their footprint
393  * columns and bounding boxes, and the device memory of the arrays.
394  * Called once from build() when ``erf.ibseb.debug`` is set.
395  */
396  void print_debug_summary () const;
397 
398  /** Add the wall-clock time of one per-step update of this rank, for the cost line of report(). */
399  void add_cost (double seconds) { m_cost_s += seconds; ++m_cost_n; }
400  /** Record the wall-clock time of the initialisation (build and view fractions). */
401  void set_init_cost (double seconds) { m_init_cost_s = seconds; }
402 
403  /**
404  * First face of each local fab in MFIter order; size number of fabs + 1.
405  * Faces ``fab_start()[n]`` to ``fab_start()[n+1]-1`` belong to the fab with
406  * local index ``n``, which is what the scatter kernels rely on.
407  */
408  const std::vector<int>& fab_start () const { return m_fab_start; }
409 
410 private:
411  IBSEBParams m_params; ///< Copy of the inputs
412  int m_lev = 0; ///< AMR level, for reports
413  int m_nface = 0; ///< Faces owned by this rank
414  int m_nslots = 0; ///< Slots per cell of the checkpoint field (largest face count on a cell)
415  int m_nbld = 0; ///< Buildings of the level (global)
416  std::vector<int> m_fab_start; ///< See fab_start()
417 
418  // Static totals over all ranks, computed once in build(); building index 0 unused.
419  std::vector<amrex::Long> m_bld_nface; ///< Faces per building
420  std::vector<amrex::Real> m_bld_area; ///< Face area per building [m2]
421  amrex::Long m_nface_dir[3] = {0, 0, 0}; ///< Faces per direction
422  amrex::Real m_area_total = 0.0; ///< Total face area [m2]
423  // Footprint of each building (global): columns, and bounding box in cell indices.
424  std::vector<amrex::Long> m_bld_ncol;
425  std::vector<int> m_bld_ilo, m_bld_ihi, m_bld_jlo, m_bld_jhi;
426 
427  // Geometry kept for the ray cast and the reports.
428  int m_nx = 0, m_ny = 0; ///< Columns of the domain
429  amrex::Real m_x_lo = 0.0, m_y_lo = 0.0; ///< Domain origin [m]
430  amrex::Real m_dx[3] = {0.0, 0.0, 0.0}; ///< Cell sizes [m]
431  bool m_per_x = false, m_per_y = false; ///< Periodicity in x and y
432  amrex::Real m_col_top_max = 0.0; ///< Tallest column [m]
433  amrex::Real m_z_ground = 0.0; ///< Ground height [m] (flat, the domain bottom)
434  amrex::Real m_max_path = 0.0; ///< Ray path cap [m]
436  double m_cost_s = 0.0; ///< Wall-clock seconds spent in the per-step update on this rank
437  amrex::Long m_cost_n = 0; ///< Number of per-step updates timed
438  double m_init_cost_s = 0.0; ///< Wall-clock seconds of build() and compute_view_fractions()
439 };
440 
441 #endif
Material library of the building faces.
Inputs of the immersed-boundary surface energy balance (erf.ibseb.*).
const Real rdOcp
Definition: ERF_InitCustomPert_ABL.H:72
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_IBFaceSet.H:69
int m_lev
AMR level, for reports.
Definition: ERF_IBFaceSet.H:412
void save_state(amrex::MultiFab &state) const
Definition: ERF_IBFaceSet.cpp:1085
amrex::Gpu::DeviceVector< amrex::Real > d_resid
|balance| after the solve [W/m2]
Definition: ERF_IBFaceSet.H:359
amrex::Gpu::DeviceVector< amrex::Real > d_theta_air
Potential temperature of the fluid cell [K].
Definition: ERF_IBFaceSet.H:347
void dump_faces(const std::string &prefix) const
Definition: ERF_IBFaceSet.cpp:953
std::vector< int > m_bld_jhi
Definition: ERF_IBFaceSet.H:425
amrex::Gpu::DeviceVector< amrex::Real > d_hbld
Height of the face's building column [m].
Definition: ERF_IBFaceSet.H:353
int state_ncomp() const
Definition: ERF_IBFaceSet.H:119
int m_nslots
Slots per cell of the checkpoint field (largest face count on a cell)
Definition: ERF_IBFaceSet.H:414
int m_ny
Columns of the domain.
Definition: ERF_IBFaceSet.H:428
amrex::Gpu::DeviceVector< amrex::Real > d_shadow
1 when the ray to the sun hits a building, else 0
Definition: ERF_IBFaceSet.H:340
double m_cost_s
Wall-clock seconds spent in the per-step update on this rank.
Definition: ERF_IBFaceSet.H:436
amrex::Gpu::DeviceVector< amrex::Real > d_yf
Definition: ERF_IBFaceSet.H:329
std::vector< int > m_xfer_src
Definition: ERF_IBFaceSet.H:378
amrex::Gpu::DeviceVector< int > d_col_top
Definition: ERF_IBFaceSet.H:368
amrex::Gpu::DeviceVector< amrex::Real > d_thick
Slab conductivity [W/m/K], heat capacity [J/m3/K], thickness [m].
Definition: ERF_IBFaceSet.H:327
amrex::Gpu::DeviceVector< int > d_k
Fluid cell of the face.
Definition: ERF_IBFaceSet.H:320
amrex::Real m_max_path
Ray path cap [m].
Definition: ERF_IBFaceSet.H:434
void compute_shortwave(amrex::Real time)
Definition: ERF_IBFaceSet.cpp:850
amrex::Gpu::DeviceVector< amrex::Real > d_H
Definition: ERF_IBFaceSet.H:337
bool has_state() const
Definition: ERF_IBFaceSet.H:136
std::vector< amrex::Long > m_bld_ncol
Definition: ERF_IBFaceSet.H:424
amrex::Gpu::DeviceVector< amrex::Real > d_albedo
Definition: ERF_IBFaceSet.H:326
amrex::Gpu::DeviceVector< amrex::Real > d_SW_abs
Definition: ERF_IBFaceSet.H:337
const std::vector< int > & fab_start() const
Definition: ERF_IBFaceSet.H:408
amrex::Real m_col_top_max
Tallest column [m].
Definition: ERF_IBFaceSet.H:432
amrex::DistributionMapping m_xfer_dm
Definition: ERF_IBFaceSet.H:377
amrex::Gpu::DeviceVector< int > d_mat
Material id (0 = uniform inputs)
Definition: ERF_IBFaceSet.H:325
void print_debug_summary() const
Definition: ERF_IBFaceSet.cpp:1011
void compute_view_fractions()
Definition: ERF_IBFaceSet.cpp:441
amrex::Gpu::DeviceVector< amrex::Real > d_LW_ext
Incoming longwave from sky and ground only [W/m2].
Definition: ERF_IBFaceSet.H:358
int m_col_i0
Definition: ERF_IBFaceSet.H:369
const SunState & sun() const
Definition: ERF_IBFaceSet.H:388
IBFaceSet(const IBSEBParams &params, int lev)
Definition: ERF_IBFaceSet.H:76
void compute_sensible(const amrex::MultiFab &cons, const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &zvel, amrex::Real c_p, const amrex::MultiFab *olen_ground=nullptr, const amrex::MultiFab *pblh_ground=nullptr, amrex::Real z_i_bulk=0.0)
Definition: ERF_IBFaceSet.cpp:687
bool m_per_x
Definition: ERF_IBFaceSet.H:431
amrex::Long m_nface_dir[3]
Faces per direction.
Definition: ERF_IBFaceSet.H:421
std::vector< int > m_bld_jlo
Definition: ERF_IBFaceSet.H:425
amrex::Gpu::DeviceVector< amrex::Real > d_w_star
Convective velocity scale of the step [m/s].
Definition: ERF_IBFaceSet.H:354
amrex::Gpu::DeviceVector< amrex::Real > d_area
Face area [m2].
Definition: ERF_IBFaceSet.H:328
void compute_longwave(const amrex::MultiFab &cons)
Definition: ERF_IBFaceSet.cpp:491
amrex::Gpu::DeviceVector< amrex::Real > d_rho
Density of the fluid cell [kg/m3].
Definition: ERF_IBFaceSet.H:348
amrex::Gpu::DeviceVector< amrex::Real > d_T_skin
Skin temperature [K].
Definition: ERF_IBFaceSet.H:331
amrex::Gpu::DeviceVector< amrex::Real > d_LW_net
Definition: ERF_IBFaceSet.H:337
amrex::Gpu::DeviceVector< amrex::Real > d_emis
Optical properties of the face.
Definition: ERF_IBFaceSet.H:326
amrex::Gpu::DeviceVector< amrex::Real > d_z_i
Depth in w* [m]: mixed layer above a roof, building height for a wall.
Definition: ERF_IBFaceSet.H:356
void add_heat_flux_to_source(amrex::MultiFab &source, const amrex::MultiFab &cons, const amrex::Geometry &geom, amrex::Real c_p, amrex::Real rdOcp) const
Definition: ERF_IBFaceSet.cpp:809
amrex::BoxArray m_xfer_ba
Definition: ERF_IBFaceSet.H:376
void compute_ground(amrex::Real dt)
Definition: ERF_IBFaceSet.cpp:580
void solve_balance(amrex::Real dt)
Definition: ERF_IBFaceSet.cpp:606
amrex::Gpu::DeviceVector< int > d_side
Solid neighbour at -1 (low) or +1 (high) side.
Definition: ERF_IBFaceSet.H:322
SunState m_sun
Definition: ERF_IBFaceSet.H:435
std::vector< amrex::Real > m_bld_area
Face area per building [m2].
Definition: ERF_IBFaceSet.H:420
void build(const amrex::MultiFab &blanking, const amrex::Geometry &geom)
Definition: ERF_IBFaceSet.cpp:88
amrex::Gpu::DeviceVector< int > d_niter
Newton iterations of the last solve.
Definition: ERF_IBFaceSet.H:360
amrex::Gpu::DeviceVector< amrex::Real > d_SW_diffuse_in
Sky and ground-reflected diffuse incident.
Definition: ERF_IBFaceSet.H:342
amrex::Gpu::DeviceVector< amrex::Real > d_f_sky
Definition: ERF_IBFaceSet.H:334
amrex::Gpu::DeviceVector< amrex::Real > d_olen
Obukhov length used [m] (1e30 when neutral)
Definition: ERF_IBFaceSet.H:355
amrex::Real m_z_ground
Ground height [m] (flat, the domain bottom)
Definition: ERF_IBFaceSet.H:433
amrex::Gpu::DeviceVector< int > d_dir
Face direction: 0 x, 1 y, 2 z.
Definition: ERF_IBFaceSet.H:321
amrex::Gpu::DeviceVector< amrex::Real > d_f_bldg
View fractions, sum to 1.
Definition: ERF_IBFaceSet.H:334
double m_init_cost_s
Wall-clock seconds of build() and compute_view_fractions()
Definition: ERF_IBFaceSet.H:438
std::vector< int > m_bld_ilo
Definition: ERF_IBFaceSet.H:425
amrex::Gpu::DeviceVector< int > d_slot
Slot of the face within its cell's checkpoint record.
Definition: ERF_IBFaceSet.H:323
amrex::Long m_cost_n
Number of per-step updates timed.
Definition: ERF_IBFaceSet.H:437
const amrex::BoxArray & state_boxarray() const
Definition: ERF_IBFaceSet.H:134
amrex::Gpu::DeviceVector< amrex::Real > d_T_slab
Slab layers [K], face-major: [face * n_layers + layer].
Definition: ERF_IBFaceSet.H:332
int m_col_ny
Definition: ERF_IBFaceSet.H:369
int n_layers() const
Definition: ERF_IBFaceSet.H:100
void scatter_diagnostics(amrex::MultiFab &nfaces, amrex::MultiFab &tskin) const
Definition: ERF_IBFaceSet.cpp:1046
amrex::Real m_y_lo
Domain origin [m].
Definition: ERF_IBFaceSet.H:429
amrex::Gpu::DeviceVector< amrex::Real > d_SW_direct_in
Direct beam incident on the face.
Definition: ERF_IBFaceSet.H:341
int n_slots() const
Definition: ERF_IBFaceSet.H:122
void add_cost(double seconds)
Definition: ERF_IBFaceSet.H:399
int n_buildings() const
Definition: ERF_IBFaceSet.H:98
amrex::BoxArray m_state_ba
Definition: ERF_IBFaceSet.H:375
amrex::Long m_domain_cells
Cells of the level, for the debug summary of the field.
Definition: ERF_IBFaceSet.H:379
amrex::Gpu::DeviceVector< amrex::Real > d_G
Definition: ERF_IBFaceSet.H:337
void scatter_field(const amrex::Gpu::DeviceVector< amrex::Real > &v, amrex::MultiFab &out) const
Definition: ERF_IBFaceSet.cpp:924
amrex::Gpu::DeviceVector< amrex::Real > d_T_air
Air temperature of the fluid cell.
Definition: ERF_IBFaceSet.H:345
int m_nface
Faces owned by this rank.
Definition: ERF_IBFaceSet.H:413
amrex::Gpu::DeviceVector< amrex::Real > d_Q_ext
External incident flux [W/m2], e.g. fire radiation.
Definition: ERF_IBFaceSet.H:338
amrex::MultiFab make_state() const
Definition: ERF_IBFaceSet.cpp:1078
amrex::Real m_area_total
Total face area [m2].
Definition: ERF_IBFaceSet.H:422
int n_faces() const
Definition: ERF_IBFaceSet.H:96
bool m_per_y
Periodicity in x and y.
Definition: ERF_IBFaceSet.H:431
amrex::Gpu::DeviceVector< amrex::Real > d_f_ground
Definition: ERF_IBFaceSet.H:334
amrex::Gpu::DeviceVector< int > d_j
Definition: ERF_IBFaceSet.H:320
void set_init_cost(double seconds)
Definition: ERF_IBFaceSet.H:401
int m_nx
Definition: ERF_IBFaceSet.H:428
void report(amrex::Real time, int step, bool write_csv) const
Definition: ERF_IBFaceSet.cpp:1170
amrex::Gpu::DeviceVector< int > d_bid
Building id (1-based)
Definition: ERF_IBFaceSet.H:324
amrex::Gpu::DeviceVector< amrex::Real > d_LE
Definition: ERF_IBFaceSet.H:337
void load_state(const amrex::MultiFab &state)
Definition: ERF_IBFaceSet.cpp:1125
std::vector< int > m_fab_start
See fab_start()
Definition: ERF_IBFaceSet.H:416
amrex::Gpu::DeviceVector< amrex::Real > d_H_coeff
H = H_coeff (theta_skin - theta_air) [W/m2/K].
Definition: ERF_IBFaceSet.H:351
int m_nbld
Buildings of the level (global)
Definition: ERF_IBFaceSet.H:415
amrex::Real m_dx[3]
Cell sizes [m].
Definition: ERF_IBFaceSet.H:430
void assign_materials()
Definition: ERF_IBFaceSet.cpp:532
amrex::Gpu::DeviceVector< amrex::Real > d_xf
Definition: ERF_IBFaceSet.H:329
amrex::Gpu::DeviceVector< amrex::Real > d_zf
Face centre [m].
Definition: ERF_IBFaceSet.H:329
IBSEBParams m_params
Copy of the inputs.
Definition: ERF_IBFaceSet.H:411
std::vector< amrex::Long > m_bld_nface
Faces per building.
Definition: ERF_IBFaceSet.H:419
amrex::Gpu::DeviceVector< amrex::Real > d_LW_down_in
Incoming longwave on the face (sky, ground and walls)
Definition: ERF_IBFaceSet.H:344
int m_col_j0
Definition: ERF_IBFaceSet.H:369
std::vector< int > m_bld_ihi
Definition: ERF_IBFaceSet.H:425
amrex::Real m_x_lo
Definition: ERF_IBFaceSet.H:429
amrex::Gpu::DeviceVector< amrex::Real > d_rhocp
Definition: ERF_IBFaceSet.H:327
int m_col_nx
Definition: ERF_IBFaceSet.H:369
amrex::Gpu::DeviceVector< int > d_i
Definition: ERF_IBFaceSet.H:320
amrex::Gpu::DeviceVector< amrex::Real > d_ustar
Friction velocity of the wall function [m/s].
Definition: ERF_IBFaceSet.H:350
amrex::Gpu::DeviceVector< amrex::Real > d_kth
Definition: ERF_IBFaceSet.H:327
amrex::Gpu::DeviceVector< amrex::Real > d_U_tan
Tangential wind speed at the fluid cell [m/s].
Definition: ERF_IBFaceSet.H:349
@ xvel
Definition: ERF_IndexDefines.H:215
@ cons
Definition: ERF_IndexDefines.H:214
@ zvel
Definition: ERF_IndexDefines.H:217
@ yvel
Definition: ERF_IndexDefines.H:216
Sun and irradiances of the last compute_shortwave() call, for reports.
Definition: ERF_IBFaceSet.H:382
amrex::Real diffuse_h
Diffuse on a horizontal surface [W/m2].
Definition: ERF_IBFaceSet.H:386
amrex::Real dni
Direct-normal irradiance [W/m2].
Definition: ERF_IBFaceSet.H:385
amrex::Real zenith
Definition: ERF_IBFaceSet.H:383
amrex::Real sy
Definition: ERF_IBFaceSet.H:384
amrex::Real sx
Definition: ERF_IBFaceSet.H:384
amrex::Real azimuth
[rad]
Definition: ERF_IBFaceSet.H:383
amrex::Real sz
Unit vector toward the sun.
Definition: ERF_IBFaceSet.H:384
Definition: ERF_IBSEBParams.H:25
int n_slab_layers
Conduction layers per face.
Definition: ERF_IBSEBParams.H:27