|
ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
|
Compact list of the wall faces of resolved buildings on one AMR level. More...
#include <AMReX_MultiFab.H>#include <AMReX_BoxArray.H>#include <AMReX_DistributionMapping.H>#include <AMReX_Geometry.H>#include <AMReX_GpuContainers.H>#include <vector>#include "ERF_IBSEBParams.H"#include "ERF_IBSEBMaterials.H"

Go to the source code of this file.
Classes | |
| class | IBFaceSet |
| struct | IBFaceSet::SunState |
| Sun and irradiances of the last compute_shortwave() call, for reports. More... | |
Compact list of the wall faces of resolved buildings on one AMR level.
What a face is. The immersed forcing marks every cell of a level as fluid or solid through the cell-centred blanking terrain_blanking (one minus the embedded-boundary volume fraction, so 0 in the air and 1 inside a building). A wall face is the cell face between a fluid cell (blanking below 0.5) and a solid cell (blanking at or above 0.5). Walls are x or y faces, roofs are z faces with the fluid above the solid.
Face convention. A face is identified by its fluid cell (i, j, k), its direction dir (0 = x, 1 = y, 2 = z) and its side (-1 when the solid neighbour is at i-1 / j-1 / k-1, +1 when it is at i+1 / j+1 / k+1). The outward unit normal of the wall, pointing into the fluid, is therefore -side along dir. The fluid cell is where every atmospheric input of the balance (wind, temperature, humidity, radiation) is read and where the wall's heat flux is deposited.
Ownership and layout. Each face is stored exactly once, on the rank that owns its fluid cell, so the per-step update of the balance is a kernel over this rank's faces with no communication; only the reports reduce across ranks. The faces are a struct of device arrays (one amrex::Gpu::DeviceVector per quantity, all indexed by the face number) and are stored contiguously per local fab in MFIter order: fab_start()[mfi.LocalIndex()] to fab_start()[mfi.LocalIndex()+1] are the faces whose fluid cell is in that fab, which is what lets a kernel scatter into that fab's arrays without a search.
Building ids. The solid columns of the blanking (any solid cell in the column) are labelled by 4-connectivity in the horizontal and numbered in scan order over (i, j), identically on every rank from a reduced column mask; a face carries the id of the column of its solid neighbour. Ids are 1-based, 0 is never assigned.
Output. The list is never written directly. scatter_diagnostics() puts the number of faces and their mean skin temperature into cell-centred fields for the plotfile; save_state() / load_state() move the skin temperature, the sensible flux and the slab temperatures through a cell-centred field with one slot per face of a cell (see state_ncomp()) for the checkpoint. On restart the list is rebuilt from the blanking and refilled from that field, so a restart does not depend on the rank count or on the order the faces were found in.
Per-step order. build() detects and stores the faces and compute_view_fractions() fills d_f_sky / d_f_ground / d_f_bldg once at initialisation; every step then runs compute_shortwave(), compute_longwave(), compute_sensible() and, with erf.ibseb.prognostic, solve_balance(), which finds the skin temperature closing the balance, advances the slab with it and rewrites the fluxes at the solution; without it compute_ground() advances the slab under the fixed skin. d_Q_ext is the hook through which an external incident flux (a fire's radiation) enters without the balance knowing its source: whoever owns it writes the array before solve_balance() runs.