(app_loci_face_orientation)= # Loci Face Orientation and Cell Incidence *Stream* uses *Loci* to assemble its finite-volume equations. *Loci* stores one orientation for each face. This appendix explains how *Loci* orients a face, how the `upper` and `lower` maps relate a cell to its faces, and how these conventions determine the sign of a face contribution to a cell balance. ## Stored Face Orientation For an internal face $f$, let $\operatorname{cl}(f)$ and $\operatorname{cr}(f)$ denote its left and right cells. The `cl` and `cr` maps take a face and return its left and right cells. The stored face area vector is ```{math} \vec S_f=A_f\hat{\vec n}_f, \qquad \hat{\vec n}_f:\operatorname{cl}(f)\longrightarrow\operatorname{cr}(f). ``` Put simply, the stored face normal points away from the `cl` cell and toward the `cr` cell. The mesh construction process chooses which adjacent cell is `cl` and which is `cr`; these labels do not denote fixed spatial directions. The ordered face nodes, the stored normal, and the `cl` and `cr` maps share this orientation. An oriented face flux $F_f$ is positive from $\operatorname{cl}(f)$ to $\operatorname{cr}(f)$. For example, ```{math} \Phi_f=\vec u_f\mathbin{\cdot}\vec S_f ``` is positive in the stored face direction. The face orientation is fixed, but it is not outward from both cells sharing the face. ## Upper and Lower Face Sets For a cell $P$, let $\mathcal F_P^{\mathrm{int}}$ denote all internal faces that touch the cell. *Loci* divides these faces into two lists. The upper list contains faces for which $P$ is the `cl` cell, and the lower list contains faces for which $P$ is the `cr` cell: ```{math} \mathcal U(P) = \left\{f\in\mathcal F_P^{\mathrm{int}}:\operatorname{cl}(f)=P\right\}, \qquad \mathcal L(P) = \left\{f\in\mathcal F_P^{\mathrm{int}}:\operatorname{cr}(f)=P\right\}. ``` These mathematical sets are exactly the face lists returned by the Loci multimaps `upper` and `lower`: ```{math} \mathcal U(P)=\operatorname{upper}(P)=\operatorname{cl}^{-1}(P), \qquad \mathcal L(P)=\operatorname{lower}(P)=\operatorname{cr}^{-1}(P). ``` Here, $\operatorname{cl}^{-1}(P)$ means "follow `cl` backward" and collect every internal face that `cl` maps to $P$; it is not a reciprocal. The same interpretation applies to $\operatorname{cr}^{-1}(P)$. Every internal face touching $P$ belongs to exactly one of the two lists: ```{math} \mathcal F_P^{\mathrm{int}} = \mathcal U(P)\mathbin{\dot\cup}\mathcal L(P). ``` The dot over the union sign states that the lists do not overlap. The names *upper* and *lower* come from the matrix ordering. In the equation row for $P$, an upper face connects to a neighbor with a higher equation number, while a lower face connects to a neighbor with a lower equation number. The corresponding off-diagonal coefficients lie in the upper and lower triangular parts of the matrix. The names do not describe physical directions in the mesh. The `upper` and `lower` multimaps contain faces. If two cells share more than one face, each connecting face remains a separate entry and contributes separately to a face sum. The cell across an internal face is ```{math} N_f(P)= \begin{cases} \operatorname{cr}(f), & f\in\mathcal U(P),\\ \operatorname{cl}(f), & f\in\mathcal L(P). \end{cases} ``` Across an upper face, $P$ is `cl`, so `cr` gives the neighboring cell. Across a lower face, $P$ is `cr`, so `cl` gives the neighbor. A Loci rule therefore reads a neighboring value through `upper->cr->X` or `lower->cl->X`. ### Splitting a Face-Based Neighbor Sum If $a_{Pf}$ is the coefficient contributed by face $f$, a neighbor term assembled face by face can be split over the two lists without changing the sum: ```{math} \sum_{f\in\mathcal F_P^{\mathrm{int}}} a_{Pf}\phi_{N_f(P)} = \sum_{f\in\mathcal U(P)} a_{Pf}\phi_{\operatorname{cr}(f)} + \sum_{f\in\mathcal L(P)} a_{Pf}\phi_{\operatorname{cl}(f)}. ``` The first term uses `upper->cr->phi`; the second uses `lower->cl->phi`. If the final algebraic equation uses one coefficient for each distinct neighbor, contributions from multiple faces connecting the same two cells are added into that coefficient. ### Boundary Faces For an ordinary non-periodic boundary face, the physical owner satisfies $\operatorname{ci}(f)=\operatorname{cl}(f)=P$, and the stored normal points outward from $P$. The boundary faces of $P$ are ```{math} \mathcal F_P^{\mathrm{bnd}} = \operatorname{boundary\_map}(P) = \left\{f\in\mathcal F^{\mathrm{bnd}}:\operatorname{ci}(f)=P\right\}. ``` The final expression says to collect every boundary face whose physical owner `ci` is cell $P$. ## Converting to the Cell-Outward Direction From the perspective of cell $P$, an upper-face quantity keeps its stored sign and a lower-face quantity changes sign. The incidence sign $\sigma_{Pf}$ records that choice: ```{math} \sigma_{Pf}= \begin{cases} +1, & f\in\mathcal U(P)\ \text{or}\ f\in\mathcal F_P^{\mathrm{bnd}},\\ -1, & f\in\mathcal L(P). \end{cases} ``` On an upper face, the stored normal already points out of $P$, so the sign is $+1$. On a lower face, the stored normal points into $P$, so the sign is $-1$. An ordinary boundary-face normal points out of its physical owner and also uses $+1$. The outward unit normal, area vector, and signed flux relative to cell $P$ are ```{math} \hat{\vec n}_{Pf}=\sigma_{Pf}\hat{\vec n}_f, \qquad \vec S_{Pf}=\sigma_{Pf}\vec S_f, \qquad F_{Pf}=\sigma_{Pf}F_f. ``` Therefore, $F_f>0$ means flow from `cl` to `cr`, while $F_{Pf}>0$ means flow leaving cell $P$. | Cell role at $f$ | Mathematical set | Loci map | $\sigma_{Pf}$ | Stored normal relative to $P$ | | --- | --- | --- | --- | --- | | $P=\operatorname{cl}(f)$ | $\mathcal U(P)$ | `upper(P)` | $+1$ | Outward | | $P=\operatorname{cr}(f)$ | $\mathcal L(P)$ | `lower(P)` | $-1$ | Inward | | Boundary owner | $\mathcal F_P^{\mathrm{bnd}}$ | `boundary_map(P)` | $+1$ | Outward | No incidence-sign field is stored in the fact database. The sign follows directly from the face-to-cell maps. ## Cell Balance and Conservation For the complete face set ```{math} \mathcal F_P = \mathcal U(P)\mathbin{\dot\cup}\mathcal L(P) \mathbin{\dot\cup}\mathcal F_P^{\mathrm{bnd}}, ``` This says that the upper faces, lower faces, and boundary faces together contain every face of $P$, exactly once. With this partition, the outward face sum is ```{math} :label: loci_cell_outward_face_sum \sum_{f\in\mathcal F_P}F_{Pf} = \sum_{f\in\mathcal U(P)}F_f - \sum_{f\in\mathcal L(P)}F_f + \sum_{f\in\mathcal F_P^{\mathrm{bnd}}}F_f. ``` In words: add the stored flux on upper and boundary faces, and subtract it on lower faces. The result is the net outward flux for cell $P$. An internal face contributes $+F_f$ to its left cell and $-F_f$ to its right cell: ```{math} F_{\operatorname{cl}(f),f}=+F_f, \qquad F_{\operatorname{cr}(f),f}=-F_f. ``` The two contributions cancel when the neighboring cell balances are added. One stored face flux can therefore be applied conservatively to both cell equations. ## Meaning in Loci Rules A mapping such as `(cl,cr)->(...)` supplies access to the two adjacent cells; it does not insert an algebraic sign. A reduction that assembles a divergence or outward residual must add $F_f$ to `cl` and subtract $F_f$ from `cr`. A right-hand side that stores the negative of that residual uses the opposite signs. When the outward sum is assembled by traversing the inverse maps, the rule adds `upper` contributions and subtracts `lower` contributions. The same convention applies to moving-grid quantities. Both `volFlux` and `gridVolFlux` use the stored `cl`-to-`cr` orientation, so their difference retains that orientation. ## Notation for Face-Based Derivations When a derivation distinguishes the stored and cell-outward orientations, a face-only subscript denotes the stored orientation: ```{math} \vec S_f,\quad \Phi_f,\quad \dot m_f,\quad F_f. ``` A cell-face subscript denotes the outward orientation of a particular cell: ```{math} \vec S_{Pf},\quad \Phi_{Pf},\quad \dot m_{Pf},\quad F_{Pf}. ``` A local two-cell derivation may set $P=\operatorname{cl}(f)$ and $N=\operatorname{cr}(f)$ explicitly. Under that stated choice, the stored face direction is also outward from $P$. Outward normals in continuum surface integrals and on physical domain boundaries remain outward geometric normals; they do not imply that every stored internal-face normal is outward from every incident cell.