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 <AMReX_iMultiFab.H>
10 #include <cmath>
11 #include <string>
12 #include <vector>
13 #include "ERF_IBSEBParams.H"
14 #include "ERF_IBSEBMaterials.H"
15 #include "ERF_IBSEBSolar.H"
17 
18 /**
19  * \file ERF_IBFaceSet.H
20  * \brief Compact list of the wall faces of resolved buildings on one AMR level.
21  *
22  * **What a face is.** The immersed forcing marks every cell of a level as
23  * fluid or solid through the cell-centred blanking ``terrain_blanking``
24  * (one minus the embedded-boundary volume fraction, so 0 in the air and 1
25  * inside a building). A wall face is the cell face between a fluid cell
26  * (blanking below 0.5) and a solid cell (blanking at or above 0.5). Walls
27  * are x or y faces, roofs are z faces with the fluid above the solid.
28  *
29  * **Face convention.** A face is identified by its *fluid* cell ``(i, j, k)``,
30  * its direction ``dir`` (0 = x, 1 = y, 2 = z) and its ``side`` (-1 when the
31  * solid neighbour is at ``i-1`` / ``j-1`` / ``k-1``, +1 when it is at
32  * ``i+1`` / ``j+1`` / ``k+1``). The outward unit normal of the wall, pointing
33  * into the fluid, is therefore ``-side`` along ``dir``. The fluid cell is where
34  * every atmospheric input of the balance (wind, temperature, humidity,
35  * radiation) is read and where the wall's heat flux is deposited.
36  *
37  * **Ownership and layout.** Each face is stored exactly once, on the rank
38  * that owns its fluid cell, so the per-step update of the balance is a kernel
39  * over this rank's faces with no communication; only the reports reduce
40  * across ranks. The faces are a struct of device arrays (one
41  * ``amrex::Gpu::DeviceVector`` per quantity, all indexed by the face number)
42  * and are stored contiguously per local fab in MFIter order:
43  * ``fab_start()[mfi.LocalIndex()]`` to ``fab_start()[mfi.LocalIndex()+1]``
44  * are the faces whose fluid cell is in that fab, which is what lets a kernel
45  * scatter into that fab's arrays without a search.
46  *
47  * **Column maps.** The solid columns of the blanking (any solid cell in the
48  * column) are kept as a k-collapsed ``amrex::iMultiFab`` on the level's own
49  * boxes, one integer per column: the domain-relative k of its highest solid
50  * cell, -1 where it is fluid. Nothing about the columns is replicated across
51  * the ranks (erf-model/ERF#4020): the building labelling exchanges labels
52  * through the map's ghost cells, and the ray cast of the shortwave and the
53  * view fractions reads a per-rank *patch* of the map, this rank's boxes
54  * grown by a halo that holds every column a ray from one of its faces can
55  * reach (build_ray_map()).
56  *
57  * **Building ids.** The solid columns are labelled by 4-connectivity in the
58  * horizontal (across the periodic seams too) and numbered in scan order over
59  * ``(i, j)``, the same on every rank and whatever the decomposition: every
60  * column starts with its own scan index as its label, each box takes the
61  * lowest label of its connected pieces, and the pieces exchange labels
62  * through one ghost cell until nothing changes, so a building ends with the
63  * scan index of its first column; the distinct labels, gathered once, give
64  * the numbering. A face carries the id of the column of its solid neighbour.
65  * Ids are 1-based, 0 is never assigned.
66  *
67  * **Output.** The list is never written directly. scatter_diagnostics() puts
68  * the number of faces and their mean skin temperature into cell-centred
69  * fields for the plotfile; write_state() / read_state() move the skin
70  * temperature, the sensible flux and the slab temperatures through one
71  * record per face, keyed by the face's cell, direction and side, for the
72  * checkpoint. On restart the list is rebuilt from the blanking and every
73  * face finds its record by its key, so a restart does not depend on the
74  * rank count or on the order the faces were found in.
75  *
76  * **Per-step order.** build() detects and stores the faces and
77  * compute_view_fractions() fills ``d_f_sky`` / ``d_f_ground`` / ``d_f_bldg``
78  * once at initialisation; every step then runs compute_shortwave(),
79  * compute_longwave(), compute_sensible() and, with ``erf.ibseb.prognostic``,
80  * solve_balance(), which finds the skin temperature closing the balance,
81  * advances the slab with it and rewrites the fluxes at the solution; without
82  * it compute_ground() advances the slab under the fixed skin. ``d_Q_ext`` is
83  * the hook through which an external incident flux (a fire's radiation)
84  * enters without the balance knowing its source: whoever owns it writes the
85  * array before solve_balance() runs.
86  */
87 class IBFaceSet
88 {
89 public:
90  /**
91  * Construct an empty face set for one level; build() fills it.
92  * @param params Inputs of the balance (copied; the set never reads ParmParse).
93  * @param lev AMR level the set belongs to, for reports only.
94  * @param qv_comp State component of rho qv (SolverChoice::moisture_indices.qv),
95  * negative without a moisture model. The air temperature and the
96  * Exner function of a fluid cell take its vapour through the
97  * equation of state, as the rest of ERF does; with no moisture
98  * model they take none.
99  */
100  IBFaceSet (const IBSEBParams& params, int lev, int qv_comp = -1)
101  : m_params(params), m_lev(lev), m_qv_comp(qv_comp) {}
102 
103  /**
104  * Detect this rank's faces from the cell-centred blanking and allocate
105  * every per-face array.
106  *
107  * Runs on the host once at initialisation: the blanking is copied fab by
108  * fab (a pinned copy on GPU builds), the valid cells are scanned, and the
109  * arrays are uploaded to the device at the end. Must be called after the
110  * blanking has been built and its ghost cells filled, since the solid
111  * neighbour of a fluid cell on a box edge lives in a ghost cell. Stops
112  * when a solid cell outside the level's grids neighbours a cell of the
113  * level, fluid or solid: a building across the edge of a refined level.
114  *
115  * @param blanking Cell-centred blanking of the level (needs at least one
116  * ghost cell, filled).
117  * @param geom Geometry of the level: cell sizes for the face areas,
118  * domain and periodicity for the neighbour tests.
119  */
120  void build (const amrex::MultiFab& blanking, const amrex::Geometry& geom);
121 
122  /**
123  * Add the buildings this refined level does not hold to the ray map of
124  * its ray cast, from the column maps of the levels below.
125  *
126  * build() takes the map from the level's own cells, so on a refined level
127  * that covers part of the domain the rays of the shortwave and the view
128  * fractions would pass through every building outside it. The ray map
129  * is rebuilt with the halo for the tallest column of every level, and
130  * each column of the patch that this level's grids do not cover takes
131  * the top of the finest level below that covers it
132  * (ERF::ibseb_check_refined_levels() has made sure a building is wholly
133  * inside or wholly outside each level), on the ratio x ratio columns of
134  * this level beneath the coarse one, at the same height. Only the ray
135  * cast reads the result: the building ids, the face heights of the wall
136  * function and the reports keep the level's own buildings. Call after
137  * build() of every level involved and before compute_view_fractions().
138  *
139  * @param below Face sets of levels 0 to this level's minus one, in that order.
140  */
141  void add_outside_occluders (const std::vector<const IBFaceSet*>& below);
142 
143  /**
144  * Give the sun of the next compute_shortwave() with
145  * ``erf.ibseb.sun_mode = two_stream``: the two-stream radiation's
146  * declination and hour angle at that time, its site latitude and its
147  * top-of-atmosphere irradiance (the date's distance factor included).
148  * ERF::ibseb_set_two_stream_sun() calls it before every call; the call
149  * uses it up, so a shortwave without a fresh sun stops rather than reusing
150  * an old one.
151  */
152  void set_two_stream_sun (amrex::Real declination, amrex::Real hour_angle,
153  amrex::Real latitude_deg, amrex::Real toa_irradiance)
154  {
155  m_ts_sun = {true, declination, hour_angle, latitude_deg, toa_irradiance};
156  }
157 
158  /**
159  * Number this refined level's buildings as level 0 numbers them.
160  *
161  * Each level labels its buildings from its own cells, so the ids of a
162  * refined level differ from level 0's wherever the levels see different
163  * buildings: a building outside the refined level, or two that level 0
164  * merges into one. Inputs that go by building (erf.ibseb.material_by_building)
165  * and the report's ``building_level0`` column use level 0's numbering, so
166  * every building of this level is looked up in the labels of the level
167  * below, and through that level's own map in level 0's: each of its
168  * columns votes with the id under it and the majority wins. A building
169  * only this level resolves maps to 0 (the default material), with a
170  * warning.
171  * Call after build() of both levels; the level below keeps its labels until
172  * release_labels().
173  *
174  * @param coarser Face set of the level below, already mapped.
175  * @param ratio Refinement ratio from the level below to this one.
176  */
177  void map_buildings_to_level0 (const IBFaceSet& coarser, const amrex::IntVect& ratio);
178 
179  /** Level 0's number for building ``b`` of this level (1-based; 0 for one only this level resolves). */
180  int building_level0 (int b) const { return m_to_lev0.at(b); }
181 
182  /** Free the column labels once the level above has been mapped (map_buildings_to_level0()). */
183  void release_labels () { m_lab.clear(); }
184 
185  /**
186  * The ray map of this rank for the kernels of the shortwave and the view
187  * fractions: the column tops over this rank's patch and the grid they are
188  * drawn on (ibseb::RayMap). A rank without boxes has no patch and no faces.
189  */
190  ibseb::RayMap ray_map () const;
191 
192  /** Halo of the ray map in cells (x, y), from the last build_ray_map(). */
193  amrex::IntVect ray_halo () const { return m_halo; }
194 
195  /** Whether every rank's patch spans the whole domain, so every ray is followed to its end. */
196  bool ray_map_spans_domain () const { return m_map_spans_domain; }
197 
198  /** Number of faces owned by this rank (not the global count; see report()). */
199  int n_faces () const { return m_nface; }
200  /** Number of buildings of the level, the same on every rank. */
201  int n_buildings () const { return m_nbld; }
202  /** Conduction layers per face, from ``erf.ibseb.n_slab_layers``. */
203  int n_layers () const { return m_params.n_slab_layers; }
204 
205  /**
206  * View fractions: sample a cosine-weighted hemisphere around
207  * every face's outward normal with ``view_n_az x view_n_el`` rays through
208  * the column walk and count where they end: sky, ground or a building.
209  * The three fractions sum to one and are view factors. Called once at
210  * initialisation; the geometry is static.
211  */
212  void compute_view_fractions ();
213 
214  /**
215  * Longwave of the current step. Incoming on a face:
216  * ``f_sky LW_sky + f_ground LW_ground + f_bldg sigma T_skin^4``,
217  * the sky term fixed or gray (``sky_emissivity sigma T_air^4`` with the
218  * air temperature of the face's fluid cell, its water vapour included)
219  * with the ground term
220  * ``eps_g sigma T_g^4``, or with ``lw_mode = two_stream`` the longwave
221  * down and up at the face's height in the face's column
222  * (``canopy``); the building term is the isothermal-surroundings
223  * approximation. Net: ``eps (LW_in - sigma T_skin^4)``, positive into the face.
224  * @param cons Conserved state of the level, for the air temperature.
225  * @param canopy With ``lw_mode = two_stream``, this step's two-stream view of the
226  * level (ERF_TwoStreamCanopyForcing.H), or an empty one before the
227  * first sweep, when the incoming and net longwave are zero.
228  */
229  void compute_longwave (const amrex::MultiFab& cons, const TwoStreamCanopyView& canopy = TwoStreamCanopyView{});
230 
231  /**
232  * Assign every face its material properties: from the material
233  * library by building id, or the uniform inputs. Called once after
234  * build(); fills d_mat, d_albedo, d_emis, d_k, d_rhocp, d_thick and
235  * initialises the slab layers to the skin temperature.
236  */
237  void assign_materials ();
238 
239  /**
240  * Ground heat flux of the current step: advance every face's
241  * slab by dt with the skin temperature at the top and the interior
242  * temperature at the bottom (implicit, ERF_IBSEBSlab.H) and store the
243  * conduction into the slab, G, positive into the wall.
244  */
245  void compute_ground (amrex::Real dt);
246 
247  /**
248  * Prognostic balance of the current step. Per face: the
249  * slab's linear response to the skin temperature for this step, the
250  * Newton solve of ERF_IBSEBBalance.H with the shortwave, the external
251  * flux, the sky and ground longwave, the frozen wall-function
252  * coefficient and the latent flux, the slab advanced with the solution,
253  * and the fluxes (LW_in, LW_net, H, G) rewritten at the solution. Fills
254  * d_resid (|balance| at the end, non-zero only at a bound or the
255  * iteration cap) and d_niter. Needs compute_shortwave(),
256  * compute_longwave() and compute_sensible() of the same step first.
257  * @param dt Atmospheric time step [s], the slab's step.
258  */
259  void solve_balance (amrex::Real dt);
260 
261  /**
262  * Sensible heat of the current step through a wall function on
263  * every face: the tangential wind of the fluid cell at half a cell from
264  * the wall gives u* with the roughness z0_wall, the skin-to-air
265  * potential-temperature difference gives theta* with z0h_wall, and
266  * H = rho c_p u* theta*, positive out of the face. Neutral, or with the
267  * surface layer's stability functions on roofs when asked. The latent
268  * flux is not modelled and stays zero.
269  *
270  * Beyond neutral: with ``convective_velocity = deardorff`` the
271  * wind is ``sqrt(U_tan^2 + (beta w*)^2)`` with w* from the previous
272  * step's H (zero when H is into the face) and a depth that is the mixed
273  * layer above a roof or the building height for a wall; with
274  * ``stability_correction`` the roofs iterate the similarity functions on
275  * the face's own Obukhov length, seeded from the ground surface layer's
276  * 2D field at the face's column when given.
277  *
278  * Fills d_H, d_ustar, d_U_tan, d_rho, d_theta_air, d_H_coeff (the
279  * coefficient of the skin-to-air potential-temperature difference that
280  * the balance keeps frozen), d_w_star, d_olen and d_z_i; T_air was read
281  * by compute_longwave(), which must run first in a step.
282  * @param cons Conserved state of the level (density, rho theta).
283  * @param xvel, yvel, zvel Face-centred velocities of the level.
284  * @param c_p Specific heat of air [J/kg/K].
285  * @param olen_ground Ground surface layer's Obukhov length (2D field on
286  * the level's box array collapsed to k = 0), or null.
287  * @param pblh_ground Its boundary-layer height field, or null.
288  * @param z_i_bulk Mixed-layer depth of the level from the bulk
289  * Richardson diagnostic or the fixed input [m].
290  */
291  void compute_sensible (const amrex::MultiFab& cons, const amrex::MultiFab& xvel,
292  const amrex::MultiFab& yvel, const amrex::MultiFab& zvel, amrex::Real c_p,
293  const amrex::MultiFab* olen_ground = nullptr,
294  const amrex::MultiFab* pblh_ground = nullptr,
295  amrex::Real z_i_bulk = 0.0);
296 
297  /**
298  * Add the face heat flux to the temperature equation: every face
299  * deposits ``H A / (c_p V Pi)`` into the rho-theta source of its fluid
300  * cell (Pi the Exner function, so the flux heats the cell by H A / (c_p V)
301  * in temperature). Called after the sources are rebuilt at every slow
302  * stage; adds, never overwrites, and uses atomic adds because a corner
303  * cell receives several faces.
304  */
305  void add_heat_flux_to_source (amrex::MultiFab& source, const amrex::MultiFab& cons,
306  const amrex::Geometry& geom, amrex::Real c_p, amrex::Real rdOcp) const;
307 
308  /**
309  * Shortwave of the current step: the sun's position (sun_mode), the
310  * irradiances of the prescribed provider or, with ``radiation =
311  * two_stream``, those of the face's own column at its height (``canopy``),
312  * then per face
313  * the direct beam on the face (zero when the ray toward the sun hits a
314  * building), the diffuse light through the view fractions, and the
315  * absorbed sum.
316  *
317  * Fills d_shadow, d_SW_direct_in, d_SW_diffuse_in and d_SW_abs; stores
318  * the sun vector and irradiances for the reports (with two_stream the
319  * means over all the level's faces of the direct-normal and diffuse
320  * irradiance each takes, written to every row of the level).
321  * @param time Simulation time [s]; with sun_mode = solar it is added to
322  * time_zero_utc_s (with sun_mode = two_stream the sun comes
323  * from set_two_stream_sun()).
324  * @param canopy With ``radiation = two_stream``, this step's two-stream view of
325  * the level (see compute_longwave()), or an empty one before the
326  * first sweep, when every face gets no shortwave.
327  */
329 
330  /**
331  * The highest interface of the level's vertical grid that any of its faces
332  * samples with radiation = two_stream (a roof the bottom of its fluid cell, a
333  * ceiling and a wall the top of its cell too), counted from the domain bottom, over all
334  * ranks; -1 when the level has no faces. The two-stream beam the faces read
335  * holds the interfaces up to there.
336  */
337  int top_sample_interface () const { return m_top_sample; }
338 
339  /** Whether the level has faces on any rank. */
340  bool has_faces () const { return m_top_sample >= 0; }
341 
342  /**
343  * Stop unless the fields of ``canopy`` (this level's two-stream view) lie on
344  * the columns of ``cons``, with the same distribution: the two-stream kernels
345  * read the column of a face from the fabs with the local index of the face's
346  * own fab.
347  */
348  void check_canopy_layout (const amrex::MultiFab& cons, const TwoStreamCanopyView& canopy) const;
349 
350  // The two-stream branches of compute_shortwave() (once the sun is placed) and
351  // compute_longwave(). Public only because a CUDA extended lambda cannot sit in
352  // a private member function; call the two functions above instead.
354  void compute_longwave_two_stream (const amrex::MultiFab& cons, const TwoStreamCanopyView& canopy);
355 
356  /**
357  * Scatter one per-face array into a cell-centred field as the mean over
358  * the faces touching each cell (zero where there are none).
359  */
360  void scatter_field (const amrex::Gpu::DeviceVector<amrex::Real>& v, amrex::MultiFab& out) const;
361 
362  /**
363  * Write every face of this rank to ``<prefix>.rank<N>.csv`` with its
364  * geometry, view fractions, shadow flag, shortwave terms and skin
365  * temperature, for the regression tests and for users who want the raw list.
366  */
367  void dump_faces (const std::string& prefix) const;
368 
369  /**
370  * Scatter the faces into two cell-centred diagnostics for the plotfile.
371  *
372  * @param[out] nfaces Number of wall faces touching each fluid cell (0 away
373  * from buildings; up to 3 at an outside corner, 6 in a
374  * one-cell slot).
375  * @param[out] tskin Mean skin temperature of those faces, 0 where there
376  * are none.
377  *
378  * Both fields must be on the level's box array with no ghost cells. Faces
379  * of one fab are accumulated with atomic adds because a corner cell
380  * receives several faces.
381  */
382  void scatter_diagnostics (amrex::MultiFab& nfaces, amrex::MultiFab& tskin) const;
383 
384  /**
385  * Write the face state (skin temperature, sensible flux and slab
386  * temperatures) to ``file`` for the checkpoint: one record per face of
387  * the level, in one global order, written by the I/O rank.
388  *
389  * The file holds one text line, ``IBSEBFaces 1 <nface> <n_layers> <nx>
390  * <ny> <nz>`` (the format version, the level's face count, the slab
391  * layers per face and the domain size in cells), then in binary a marker
392  * word (``0x0102030405060708`` as a 64-bit integer, so a file from a
393  * machine with another byte order is refused), the ``nface`` keys as
394  * 64-bit integers in ascending order, then the
395  * ``nface x (2 + n_layers)`` values as doubles: a face's skin
396  * temperature, its sensible flux (read as the previous step's by the
397  * convective velocity scale) and its slab layers from the skin inward.
398  * The key of a face is ``((i ny + j) nz + k) 6 + 2 dir + (side > 0)``
399  * with ``(i, j, k)`` counted from the domain's low corner, so it names
400  * the face whatever the rank count. The values are doubles whatever
401  * ``amrex::Real`` is, so a single-precision run reads a double-precision
402  * checkpoint and the other way round. The file costs ``8 (3 + n_layers)``
403  * bytes per face beyond its header line and marker, which is the data itself: the cell field it replaces
404  * covered the face-owning cells with whole boxes and was about eleven
405  * times larger on the FaceStorage skyscraper (erf-model/ERF#4019).
406  *
407  * Every rank copies its faces to the host and sorts them by key; the I/O
408  * rank gathers the records, orders them and writes the file. Collective:
409  * every rank must call it.
410  */
411  void write_state (const std::string& file) const;
412 
413  /**
414  * Read the face state back from a file written by write_state(), after
415  * build() has recreated the list from the blanking.
416  *
417  * The I/O rank reads the table; every rank sends it the keys of its own
418  * faces; the I/O rank finds each one by binary search and sends the
419  * records back. Only the I/O rank ever holds the whole table, and a
420  * restart on any number of ranks finds every face. Stops when the file
421  * holds another number of slab layers than the deck's
422  * ``erf.ibseb.n_slab_layers``, another domain size or another number of
423  * faces, or when a face of this list has no record: a checkpoint of other
424  * buildings. Collective: every rank must call it.
425  */
426  void read_state (const std::string& file);
427 
428  /**
429  * Print the ``[IBSEB]`` summary line and, when asked, append one row per
430  * building to ``erf.ibseb.csv_file``.
431  *
432  * The summary carries the global face counts per direction, the number of
433  * buildings, the total face area and the range of the skin temperature;
434  * the CSV rows carry per building the face count, the area, the
435  * area-weighted mean fluxes and skin temperature with its range, the
436  * largest balance residual, and the sun the step used, from its start
437  * (zenith, azimuth, direct-normal and diffuse irradiance), on a row
438  * stamped with the time at the end of the step. All numbers are reduced over the
439  * ranks; the file is written by the I/O rank only, with a header only
440  * when the file does not exist yet, so a restarted run appends. Every
441  * level appends to the same file, its rows marked by the level column.
442  * With ``erf.ibseb.dump_faces_file`` the rows come with a face dump,
443  * dump_faces() to ``<prefix>[.levN][.stepNNNNNN].rank<N>.csv``: a refined
444  * level N adds ``.levN`` so it does not overwrite the level below, and
445  * ``erf.ibseb.dump_faces_tag_step`` the step.
446  *
447  * @param time Simulation time [s] written to the rows.
448  * @param step Step number written to the rows.
449  * @param write_csv Whether to append rows, or only print the summary.
450  */
451  void report (amrex::Real time, int step, bool write_csv) const;
452 
453  // ---- Per-face device arrays, indexed by face number ----------------------
454  // Static geometry, set by build():
455  amrex::Gpu::DeviceVector<int> d_i, d_j, d_k; ///< Fluid cell of the face
456  amrex::Gpu::DeviceVector<int> d_dir; ///< Face direction: 0 x, 1 y, 2 z
457  amrex::Gpu::DeviceVector<int> d_side; ///< Solid neighbour at -1 (low) or +1 (high) side
458  amrex::Gpu::DeviceVector<int> d_bid; ///< Building id (1-based)
459  amrex::Gpu::DeviceVector<int> d_mat; ///< Material id (0 = uniform inputs)
460  amrex::Gpu::DeviceVector<amrex::Real> d_albedo, d_emis;///< Optical properties of the face
461  amrex::Gpu::DeviceVector<amrex::Real> d_kth, d_rhocp, d_thick; ///< Slab conductivity [W/m/K], heat capacity [J/m3/K], thickness [m]
462  amrex::Gpu::DeviceVector<amrex::Real> d_area; ///< Face area [m2]
463  amrex::Gpu::DeviceVector<amrex::Real> d_xf, d_yf, d_zf;///< Face centre [m]
464  // State, advanced by the balance and checkpointed:
465  amrex::Gpu::DeviceVector<amrex::Real> d_T_skin; ///< Skin temperature [K]
466  amrex::Gpu::DeviceVector<amrex::Real> d_T_slab; ///< Slab layers [K], face-major: [face * n_layers + layer]
467  // Static radiative geometry:
468  amrex::Gpu::DeviceVector<amrex::Real> d_f_sky, d_f_ground, d_f_bldg; ///< View fractions, sum to 1
469  // Fluxes of the current step [W/m2]: SW_abs and LW_net positive into the
470  // face, H, LE and G positive out of it:
471  amrex::Gpu::DeviceVector<amrex::Real> d_SW_abs, d_LW_net, d_H, d_LE, d_G;
472  amrex::Gpu::DeviceVector<amrex::Real> d_Q_ext; ///< External incident flux [W/m2], e.g. fire radiation
473  // Shortwave detail, all [W/m2] except the flag:
474  amrex::Gpu::DeviceVector<amrex::Real> d_shadow; ///< 1 when the ray to the sun hits a building, else 0
475  amrex::Gpu::DeviceVector<amrex::Real> d_SW_direct_in; ///< Direct beam incident on the face
476  amrex::Gpu::DeviceVector<amrex::Real> d_SW_diffuse_in; ///< Sky and ground-reflected diffuse incident
477  // Longwave detail [W/m2] and the air temperature read [K]:
478  amrex::Gpu::DeviceVector<amrex::Real> d_LW_down_in; ///< Incoming longwave on the face (sky, ground and walls)
479  amrex::Gpu::DeviceVector<amrex::Real> d_T_air; ///< Air temperature of the fluid cell
480  // Sensible heat detail:
481  amrex::Gpu::DeviceVector<amrex::Real> d_theta_air; ///< Potential temperature of the fluid cell [K]
482  amrex::Gpu::DeviceVector<amrex::Real> d_rho; ///< Density of the fluid cell [kg/m3]
483  amrex::Gpu::DeviceVector<amrex::Real> d_U_tan; ///< Tangential wind speed at the fluid cell [m/s]
484  amrex::Gpu::DeviceVector<amrex::Real> d_ustar; ///< Friction velocity of the wall function [m/s]
485  amrex::Gpu::DeviceVector<amrex::Real> d_H_coeff; ///< H = H_coeff (theta_skin - theta_air) [W/m2/K]
486  // Wall function beyond neutral:
487  amrex::Gpu::DeviceVector<amrex::Real> d_hbld; ///< Height of the face's building column [m]
488  amrex::Gpu::DeviceVector<amrex::Real> d_w_star; ///< Convective velocity scale of the step [m/s]
489  amrex::Gpu::DeviceVector<amrex::Real> d_olen; ///< Obukhov length used [m] (1e30 when neutral)
490  amrex::Gpu::DeviceVector<amrex::Real> d_z_i; ///< Depth in w* [m]: mixed layer above a roof, building height for a wall
491  // Prognostic balance detail:
492  amrex::Gpu::DeviceVector<amrex::Real> d_LW_ext; ///< Incoming longwave from sky and ground only [W/m2]
493  amrex::Gpu::DeviceVector<amrex::Real> d_resid; ///< |balance| after the solve [W/m2]
494  amrex::Gpu::DeviceVector<int> d_niter; ///< Newton iterations of the last solve
495  // Column tops of the level's own columns: a k-collapsed map on the level's
496  // boxes (the grids with their k range collapsed to one cell) with one
497  // ghost cell, filled across boxes and periodic seams. Each entry is the
498  // domain-relative k of the highest solid cell of its column, -1 where the
499  // column is fluid. Kept after build() so the ray map can be rebuilt with
500  // the buildings of the levels below (add_outside_occluders()).
501  amrex::iMultiFab m_col_valid;
502  // The ray map: one box per rank (the ranks with boxes), this rank's boxes
503  // grown by m_halo, clipped to the domain where it is not periodic and
504  // reduced to one domain width (with wrapping) where it is. Holds the
505  // level's own tops, the periodic images and, after add_outside_occluders(),
506  // the tops of the levels below outside this level.
507  amrex::iMultiFab m_ray_patch;
508  amrex::Box m_patch_box; ///< This rank's patch (empty without boxes)
509  amrex::IntVect m_halo{AMREX_D_DECL(0, 0, 0)}; ///< Halo of the patch in cells
510  bool m_wrap_x = false, m_wrap_y = false; ///< The patch spans the periodic domain in x / y
511  bool m_map_spans_domain = false; ///< Every rank's patch spans the domain
512  int m_max_steps = 0; ///< Columns a walk is followed for: the halo's reach in x plus y, before the domain cap
513 
514  /// Sun and irradiances of the last compute_shortwave() call, for reports.
515  struct SunState {
516  amrex::Real zenith = 0.0, azimuth = 0.0; ///< [rad]
517  amrex::Real sx = 0.0, sy = 0.0, sz = 1.0; ///< Unit vector toward the sun
518  amrex::Real dni = 0.0; ///< Direct-normal irradiance [W/m2]
519  amrex::Real diffuse_h = 0.0; ///< Diffuse on a horizontal surface [W/m2]
520  };
521  const SunState& sun () const { return m_sun; }
522 
523  /**
524  * Print the ``[IBSEB DEBUG]`` description of the set: the inputs, every
525  * rank's face count and per-fab ranges, the buildings with their footprint
526  * columns and bounding boxes, and the device memory of the arrays.
527  * Called once from build() when ``erf.ibseb.debug`` is set.
528  */
529  void print_debug_summary () const;
530 
531  /** Add the wall-clock time of one per-step update of this rank, for the cost line of report(). */
532  void add_cost (double seconds) { m_cost_s += seconds; ++m_cost_n; }
533  /** Record the wall-clock time of the initialisation (build and view fractions). */
534  void set_init_cost (double seconds) { m_init_cost_s = seconds; }
535 
536  /**
537  * First face of each local fab in MFIter order; size number of fabs + 1.
538  * Faces ``fab_start()[n]`` to ``fab_start()[n+1]-1`` belong to the fab with
539  * local index ``n``, which is what the scatter kernels rely on.
540  */
541  const std::vector<int>& fab_start () const { return m_fab_start; }
542 
543  /**
544  * Build the ray map (m_ray_patch) from m_col_valid and the levels below.
545  * The halo is sized for the shallowest ray the map must follow to its
546  * end: the shallowest ray of the hemisphere sampling
547  * (ibseb::hemisphere_min_sz()) and a sun ``erf.ibseb.sun_min_elev_deg``
548  * above the horizon, over the tallest column of this level and the levels
549  * below, ``height / tan(elevation)`` cells in x and in y
550  * (ibseb::ray_halo_cells()). A rising ray stops above the tallest column
551  * and a falling one at the ground, so within that reach the walk is exact,
552  * and beyond it only a sun lower than the floor is concerned, whose
553  * direct beam the clear-sky attenuation has all but removed; a building
554  * farther than the halo from a face then casts no shadow on it (the far
555  * field is open ground). The patch is this rank's boxes grown by the
556  * halo, clipped to the domain where it is not periodic and, where it is,
557  * reduced to one domain width when the grown box is at least that wide,
558  * in which case the walk wraps round and is exact for any reach.
559  * @param below Face sets of the levels below (empty on level 0), each with its build() done.
560  *
561  * Public because it launches a GPU lambda, which nvcc rejects in a
562  * private member function.
563  */
564  void build_ray_map (const std::vector<const IBFaceSet*>& below);
565 
566 private:
567  IBSEBParams m_params; ///< Copy of the inputs
568  int m_lev = 0; ///< AMR level, for reports
569  int m_qv_comp = -1; ///< State component of rho qv, -1 without a moisture model
570  int m_nface = 0; ///< Faces owned by this rank
571  int m_top_sample = -1; ///< Highest interface a face samples, over all ranks (-1: no faces)
572  int m_nbld = 0; ///< Buildings of the level (global)
573  std::vector<int> m_fab_start; ///< See fab_start()
574 
575  // Static totals over all ranks, computed once in build(); building index 0 unused.
576  std::vector<amrex::Long> m_bld_nface; ///< Faces per building
577  std::vector<amrex::Real> m_bld_area; ///< Face area per building [m2]
578  amrex::Long m_nface_dir[3] = {0, 0, 0}; ///< Faces per direction
579  amrex::Real m_area_total = 0.0; ///< Total face area [m2]
580  // Footprint of each building (global): columns, and bounding box in cell indices.
581  std::vector<amrex::Long> m_bld_ncol;
582  std::vector<int> m_bld_ilo, m_bld_ihi, m_bld_jlo, m_bld_jhi;
583  // Level-0 numbering (map_buildings_to_level0()): the level-0 id of each
584  // building of this level (identity on level 0), and the building id of
585  // every column on the level's own boxes (0 where fluid), kept until the
586  // level above has been mapped.
587  std::vector<int> m_to_lev0;
588  amrex::iMultiFab m_lab;
589 
590  // Geometry kept for the ray cast and the reports.
591  amrex::Geometry m_geom; ///< Geometry of the level
592  int m_nx = 0, m_ny = 0, m_nz = 0; ///< Cells of the domain in x, y and z
593  amrex::IntVect m_dom_lo{AMREX_D_DECL(0, 0, 0)}; ///< Low corner of the level's domain
594  amrex::Real m_x_lo = 0.0, m_y_lo = 0.0; ///< Domain origin [m]
595  amrex::Real m_dx[3] = {0.0, 0.0, 0.0}; ///< Cell sizes [m]
596  bool m_per_x = false, m_per_y = false; ///< Periodicity in x and y
597  amrex::Real m_col_top_max = 0.0; ///< Tallest column the ray map holds [m] (the levels below included after add_outside_occluders())
598  amrex::Real m_z_ground = 0.0; ///< Ground height [m] (flat, the domain bottom)
600  /// The two-stream sun of the next compute_shortwave() (sun_mode = two_stream).
601  struct TwoStreamSun { bool set = false; amrex::Real decl = 0.0, hour_angle = 0.0, lat_deg = 0.0, S0 = 0.0; };
603  double m_cost_s = 0.0; ///< Wall-clock seconds spent in the per-step update on this rank
604  amrex::Long m_cost_n = 0; ///< Number of per-step updates timed
605  double m_init_cost_s = 0.0; ///< Wall-clock seconds of build() and compute_view_fractions()
606 
607  /** Warn once when a fixed sun stands below ``erf.ibseb.sun_min_elev_deg`` and the map does not span the domain. */
608  void warn_fixed_sun_below_floor () const;
609 };
610 
611 #endif
Material library of the building faces.
Inputs of the immersed-boundary surface energy balance (erf.ibseb.*).
Sun position, clear-sky shortwave, and the ray cast that decides whether a building face is in shadow...
const Real rdOcp
Definition: ERF_InitCustomPert_ABL.H:72
amrex::Real Real
Definition: ERF_ShocInterface.H:19
What the two-stream sweep hands the building faces of the immersed-boundary surface energy balance (e...
Definition: ERF_IBFaceSet.H:88
int m_lev
AMR level, for reports.
Definition: ERF_IBFaceSet.H:568
ibseb::RayMap ray_map() const
Definition: ERF_IBFaceSet.cpp:768
amrex::Gpu::DeviceVector< amrex::Real > d_resid
|balance| after the solve [W/m2]
Definition: ERF_IBFaceSet.H:493
amrex::Gpu::DeviceVector< amrex::Real > d_theta_air
Potential temperature of the fluid cell [K].
Definition: ERF_IBFaceSet.H:481
void dump_faces(const std::string &prefix) const
Definition: ERF_IBFaceSet.cpp:1630
void release_labels()
Definition: ERF_IBFaceSet.H:183
IBFaceSet(const IBSEBParams &params, int lev, int qv_comp=-1)
Definition: ERF_IBFaceSet.H:100
std::vector< int > m_bld_jhi
Definition: ERF_IBFaceSet.H:582
amrex::Gpu::DeviceVector< amrex::Real > d_hbld
Height of the face's building column [m].
Definition: ERF_IBFaceSet.H:487
amrex::iMultiFab m_ray_patch
Definition: ERF_IBFaceSet.H:507
int m_ny
Definition: ERF_IBFaceSet.H:592
amrex::Gpu::DeviceVector< amrex::Real > d_shadow
1 when the ray to the sun hits a building, else 0
Definition: ERF_IBFaceSet.H:474
double m_cost_s
Wall-clock seconds spent in the per-step update on this rank.
Definition: ERF_IBFaceSet.H:603
amrex::Gpu::DeviceVector< amrex::Real > d_yf
Definition: ERF_IBFaceSet.H:463
amrex::Gpu::DeviceVector< amrex::Real > d_thick
Slab conductivity [W/m/K], heat capacity [J/m3/K], thickness [m].
Definition: ERF_IBFaceSet.H:461
amrex::iMultiFab m_lab
Definition: ERF_IBFaceSet.H:588
amrex::Gpu::DeviceVector< int > d_k
Fluid cell of the face.
Definition: ERF_IBFaceSet.H:455
amrex::Gpu::DeviceVector< amrex::Real > d_H
Definition: ERF_IBFaceSet.H:471
std::vector< amrex::Long > m_bld_ncol
Definition: ERF_IBFaceSet.H:581
amrex::Gpu::DeviceVector< amrex::Real > d_albedo
Definition: ERF_IBFaceSet.H:460
amrex::Gpu::DeviceVector< amrex::Real > d_SW_abs
Definition: ERF_IBFaceSet.H:471
const std::vector< int > & fab_start() const
Definition: ERF_IBFaceSet.H:541
int building_level0(int b) const
Definition: ERF_IBFaceSet.H:180
amrex::Real m_col_top_max
Tallest column the ray map holds [m] (the levels below included after add_outside_occluders())
Definition: ERF_IBFaceSet.H:597
void compute_longwave_two_stream(const amrex::MultiFab &cons, const TwoStreamCanopyView &canopy)
Definition: ERF_IBFaceSet.cpp:988
amrex::Gpu::DeviceVector< int > d_mat
Material id (0 = uniform inputs)
Definition: ERF_IBFaceSet.H:459
void print_debug_summary() const
Definition: ERF_IBFaceSet.cpp:1688
void compute_view_fractions()
Definition: ERF_IBFaceSet.cpp:886
amrex::Gpu::DeviceVector< amrex::Real > d_LW_ext
Incoming longwave from sky and ground only [W/m2].
Definition: ERF_IBFaceSet.H:492
const SunState & sun() const
Definition: ERF_IBFaceSet.H:521
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:1234
bool m_per_x
Definition: ERF_IBFaceSet.H:596
amrex::Long m_nface_dir[3]
Faces per direction.
Definition: ERF_IBFaceSet.H:578
std::vector< int > m_bld_jlo
Definition: ERF_IBFaceSet.H:582
int m_nz
Cells of the domain in x, y and z.
Definition: ERF_IBFaceSet.H:592
std::vector< int > m_to_lev0
Definition: ERF_IBFaceSet.H:587
amrex::Box m_patch_box
This rank's patch (empty without boxes)
Definition: ERF_IBFaceSet.H:508
amrex::IntVect m_halo
Halo of the patch in cells.
Definition: ERF_IBFaceSet.H:509
amrex::Gpu::DeviceVector< amrex::Real > d_w_star
Convective velocity scale of the step [m/s].
Definition: ERF_IBFaceSet.H:488
amrex::Gpu::DeviceVector< amrex::Real > d_area
Face area [m2].
Definition: ERF_IBFaceSet.H:462
void compute_shortwave_two_stream(const TwoStreamCanopyView &canopy)
Definition: ERF_IBFaceSet.cpp:1508
amrex::Gpu::DeviceVector< amrex::Real > d_rho
Density of the fluid cell [kg/m3].
Definition: ERF_IBFaceSet.H:482
void read_state(const std::string &file)
Definition: ERF_IBFaceSet.cpp:1909
void build_ray_map(const std::vector< const IBFaceSet * > &below)
Definition: ERF_IBFaceSet.cpp:624
amrex::Gpu::DeviceVector< amrex::Real > d_T_skin
Skin temperature [K].
Definition: ERF_IBFaceSet.H:465
amrex::Gpu::DeviceVector< amrex::Real > d_LW_net
Definition: ERF_IBFaceSet.H:471
amrex::Gpu::DeviceVector< amrex::Real > d_emis
Optical properties of the face.
Definition: ERF_IBFaceSet.H:460
void add_outside_occluders(const std::vector< const IBFaceSet * > &below)
Definition: ERF_IBFaceSet.cpp:791
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:490
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:1357
void compute_ground(amrex::Real dt)
Definition: ERF_IBFaceSet.cpp:1123
void solve_balance(amrex::Real dt)
Definition: ERF_IBFaceSet.cpp:1151
amrex::Gpu::DeviceVector< int > d_side
Solid neighbour at -1 (low) or +1 (high) side.
Definition: ERF_IBFaceSet.H:457
SunState m_sun
Definition: ERF_IBFaceSet.H:599
int m_top_sample
Highest interface a face samples, over all ranks (-1: no faces)
Definition: ERF_IBFaceSet.H:571
std::vector< amrex::Real > m_bld_area
Face area per building [m2].
Definition: ERF_IBFaceSet.H:577
void build(const amrex::MultiFab &blanking, const amrex::Geometry &geom)
Definition: ERF_IBFaceSet.cpp:178
amrex::Gpu::DeviceVector< int > d_niter
Newton iterations of the last solve.
Definition: ERF_IBFaceSet.H:494
amrex::Gpu::DeviceVector< amrex::Real > d_SW_diffuse_in
Sky and ground-reflected diffuse incident.
Definition: ERF_IBFaceSet.H:476
amrex::Gpu::DeviceVector< amrex::Real > d_f_sky
Definition: ERF_IBFaceSet.H:468
amrex::iMultiFab m_col_valid
Definition: ERF_IBFaceSet.H:501
amrex::Gpu::DeviceVector< amrex::Real > d_olen
Obukhov length used [m] (1e30 when neutral)
Definition: ERF_IBFaceSet.H:489
amrex::Real m_z_ground
Ground height [m] (flat, the domain bottom)
Definition: ERF_IBFaceSet.H:598
amrex::Gpu::DeviceVector< int > d_dir
Face direction: 0 x, 1 y, 2 z.
Definition: ERF_IBFaceSet.H:456
int m_qv_comp
State component of rho qv, -1 without a moisture model.
Definition: ERF_IBFaceSet.H:569
amrex::Gpu::DeviceVector< amrex::Real > d_f_bldg
View fractions, sum to 1.
Definition: ERF_IBFaceSet.H:468
int m_max_steps
Columns a walk is followed for: the halo's reach in x plus y, before the domain cap.
Definition: ERF_IBFaceSet.H:512
void warn_fixed_sun_below_floor() const
Definition: ERF_IBFaceSet.cpp:754
void check_canopy_layout(const amrex::MultiFab &cons, const TwoStreamCanopyView &canopy) const
Definition: ERF_IBFaceSet.cpp:1039
double m_init_cost_s
Wall-clock seconds of build() and compute_view_fractions()
Definition: ERF_IBFaceSet.H:605
bool has_faces() const
Definition: ERF_IBFaceSet.H:340
bool m_wrap_y
The patch spans the periodic domain in x / y.
Definition: ERF_IBFaceSet.H:510
std::vector< int > m_bld_ilo
Definition: ERF_IBFaceSet.H:582
amrex::Long m_cost_n
Number of per-step updates timed.
Definition: ERF_IBFaceSet.H:604
TwoStreamSun m_ts_sun
Definition: ERF_IBFaceSet.H:602
void map_buildings_to_level0(const IBFaceSet &coarser, const amrex::IntVect &ratio)
Definition: ERF_IBFaceSet.cpp:814
amrex::Gpu::DeviceVector< amrex::Real > d_T_slab
Slab layers [K], face-major: [face * n_layers + layer].
Definition: ERF_IBFaceSet.H:466
amrex::IntVect ray_halo() const
Definition: ERF_IBFaceSet.H:193
int n_layers() const
Definition: ERF_IBFaceSet.H:203
void scatter_diagnostics(amrex::MultiFab &nfaces, amrex::MultiFab &tskin) const
Definition: ERF_IBFaceSet.cpp:1730
amrex::Real m_y_lo
Domain origin [m].
Definition: ERF_IBFaceSet.H:594
amrex::Gpu::DeviceVector< amrex::Real > d_SW_direct_in
Direct beam incident on the face.
Definition: ERF_IBFaceSet.H:475
void compute_longwave(const amrex::MultiFab &cons, const TwoStreamCanopyView &canopy=TwoStreamCanopyView{})
Definition: ERF_IBFaceSet.cpp:935
void add_cost(double seconds)
Definition: ERF_IBFaceSet.H:532
bool m_map_spans_domain
Every rank's patch spans the domain.
Definition: ERF_IBFaceSet.H:511
int n_buildings() const
Definition: ERF_IBFaceSet.H:201
amrex::Gpu::DeviceVector< amrex::Real > d_G
Definition: ERF_IBFaceSet.H:471
void scatter_field(const amrex::Gpu::DeviceVector< amrex::Real > &v, amrex::MultiFab &out) const
Definition: ERF_IBFaceSet.cpp:1601
amrex::Gpu::DeviceVector< amrex::Real > d_T_air
Air temperature of the fluid cell.
Definition: ERF_IBFaceSet.H:479
int m_nface
Faces owned by this rank.
Definition: ERF_IBFaceSet.H:570
int top_sample_interface() const
Definition: ERF_IBFaceSet.H:337
amrex::Gpu::DeviceVector< amrex::Real > d_Q_ext
External incident flux [W/m2], e.g. fire radiation.
Definition: ERF_IBFaceSet.H:472
amrex::Real m_area_total
Total face area [m2].
Definition: ERF_IBFaceSet.H:579
int n_faces() const
Definition: ERF_IBFaceSet.H:199
bool m_per_y
Periodicity in x and y.
Definition: ERF_IBFaceSet.H:596
amrex::Gpu::DeviceVector< amrex::Real > d_f_ground
Definition: ERF_IBFaceSet.H:468
amrex::Gpu::DeviceVector< int > d_j
Definition: ERF_IBFaceSet.H:455
void set_init_cost(double seconds)
Definition: ERF_IBFaceSet.H:534
int m_nx
Definition: ERF_IBFaceSet.H:592
void report(amrex::Real time, int step, bool write_csv) const
Definition: ERF_IBFaceSet.cpp:2066
amrex::Gpu::DeviceVector< int > d_bid
Building id (1-based)
Definition: ERF_IBFaceSet.H:458
amrex::Gpu::DeviceVector< amrex::Real > d_LE
Definition: ERF_IBFaceSet.H:471
std::vector< int > m_fab_start
See fab_start()
Definition: ERF_IBFaceSet.H:573
amrex::Gpu::DeviceVector< amrex::Real > d_H_coeff
H = H_coeff (theta_skin - theta_air) [W/m2/K].
Definition: ERF_IBFaceSet.H:485
int m_nbld
Buildings of the level (global)
Definition: ERF_IBFaceSet.H:572
amrex::Real m_dx[3]
Cell sizes [m].
Definition: ERF_IBFaceSet.H:595
void assign_materials()
Definition: ERF_IBFaceSet.cpp:1073
amrex::Gpu::DeviceVector< amrex::Real > d_xf
Definition: ERF_IBFaceSet.H:463
void set_two_stream_sun(amrex::Real declination, amrex::Real hour_angle, amrex::Real latitude_deg, amrex::Real toa_irradiance)
Definition: ERF_IBFaceSet.H:152
bool m_wrap_x
Definition: ERF_IBFaceSet.H:510
amrex::Gpu::DeviceVector< amrex::Real > d_zf
Face centre [m].
Definition: ERF_IBFaceSet.H:463
IBSEBParams m_params
Copy of the inputs.
Definition: ERF_IBFaceSet.H:567
void write_state(const std::string &file) const
Definition: ERF_IBFaceSet.cpp:1818
amrex::Geometry m_geom
Geometry of the level.
Definition: ERF_IBFaceSet.H:591
void compute_shortwave(amrex::Real time, const TwoStreamCanopyView &canopy=TwoStreamCanopyView{})
Definition: ERF_IBFaceSet.cpp:1402
std::vector< amrex::Long > m_bld_nface
Faces per building.
Definition: ERF_IBFaceSet.H:576
amrex::Gpu::DeviceVector< amrex::Real > d_LW_down_in
Incoming longwave on the face (sky, ground and walls)
Definition: ERF_IBFaceSet.H:478
amrex::IntVect m_dom_lo
Low corner of the level's domain.
Definition: ERF_IBFaceSet.H:593
std::vector< int > m_bld_ihi
Definition: ERF_IBFaceSet.H:582
amrex::Real m_x_lo
Definition: ERF_IBFaceSet.H:594
amrex::Gpu::DeviceVector< amrex::Real > d_rhocp
Definition: ERF_IBFaceSet.H:461
bool ray_map_spans_domain() const
Definition: ERF_IBFaceSet.H:196
amrex::Gpu::DeviceVector< int > d_i
Definition: ERF_IBFaceSet.H:455
amrex::Gpu::DeviceVector< amrex::Real > d_ustar
Friction velocity of the wall function [m/s].
Definition: ERF_IBFaceSet.H:484
amrex::Gpu::DeviceVector< amrex::Real > d_kth
Definition: ERF_IBFaceSet.H:461
amrex::Gpu::DeviceVector< amrex::Real > d_U_tan
Tangential wind speed at the fluid cell [m/s].
Definition: ERF_IBFaceSet.H:483
@ xvel
Definition: ERF_IndexDefines.H:255
@ cons
Definition: ERF_IndexDefines.H:254
@ zvel
Definition: ERF_IndexDefines.H:257
@ yvel
Definition: ERF_IndexDefines.H:256
Sun and irradiances of the last compute_shortwave() call, for reports.
Definition: ERF_IBFaceSet.H:515
amrex::Real diffuse_h
Diffuse on a horizontal surface [W/m2].
Definition: ERF_IBFaceSet.H:519
amrex::Real dni
Direct-normal irradiance [W/m2].
Definition: ERF_IBFaceSet.H:518
amrex::Real zenith
Definition: ERF_IBFaceSet.H:516
amrex::Real sy
Definition: ERF_IBFaceSet.H:517
amrex::Real sx
Definition: ERF_IBFaceSet.H:517
amrex::Real azimuth
[rad]
Definition: ERF_IBFaceSet.H:516
amrex::Real sz
Unit vector toward the sun.
Definition: ERF_IBFaceSet.H:517
The two-stream sun of the next compute_shortwave() (sun_mode = two_stream).
Definition: ERF_IBFaceSet.H:601
amrex::Real lat_deg
Definition: ERF_IBFaceSet.H:601
amrex::Real S0
Definition: ERF_IBFaceSet.H:601
amrex::Real decl
Definition: ERF_IBFaceSet.H:601
amrex::Real hour_angle
Definition: ERF_IBFaceSet.H:601
bool set
Definition: ERF_IBFaceSet.H:601
Definition: ERF_IBSEBParams.H:25
int n_slab_layers
Conduction layers per face.
Definition: ERF_IBSEBParams.H:27
The fields a level's faces read for one step: the beam and the cosine of the zenith the sweep of that...
Definition: ERF_TwoStreamCanopyForcing.H:45
Definition: ERF_IBSEBSolar.H:219