Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "MooseTypes.h" 13 : #include "ElemInfo.h" 14 : #include "MooseError.h" 15 : 16 : #include "libmesh/vector_value.h" 17 : #include "libmesh/remote_elem.h" 18 : 19 : #include <map> 20 : #include <set> 21 : #include <memory> 22 : 23 : class MooseMesh; 24 : namespace libMesh 25 : { 26 : class Elem; 27 : class Node; 28 : } 29 : 30 : /// This data structure is used to store geometric and variable related 31 : /// metadata about each cell face in the mesh. This info is used by face loops 32 : /// (e.g. for finite volumes method numerical flux loop). These objects can be 33 : /// created and cached up front. Since it only stores information that changes 34 : /// when the mesh is modified it only needs an update whenever the mesh 35 : /// changes. 36 : class FaceInfo 37 : { 38 : public: 39 : FaceInfo(const ElemInfo * const elem_info, const unsigned int side, const dof_id_type id); 40 : 41 : /// This enum is used to indicate which side(s) of a face a particular 42 : /// variable is defined on. This is important for certain BC-related finite 43 : /// volume calculations. Because of the way side-sets and variable 44 : /// block-restriction work in MOOSE, there may be boundary conditions applied 45 : /// to internal faces on the mesh where a variable is only active on one or 46 : /// even zero sides of the face. For such faces, FV needs to know which 47 : /// sides (if any) to add BC residual contributions to. 48 : enum class VarFaceNeighbors 49 : { 50 : BOTH, 51 : NEITHER, 52 : ELEM, 53 : NEIGHBOR 54 : }; 55 : 56 : /// Return the ID of the face 57 : dof_id_type id() const { return _id; } 58 : 59 : /// Returns the face area of face id 60 114651487 : Real faceArea() const { return _face_area; } 61 : 62 : /// Sets/gets the coordinate transformation factor (for e.g. rz, spherical 63 : /// coords) to be used for integration over faces. 64 2092344 : Real & faceCoord() { return _face_coord; } 65 36811962 : Real faceCoord() const { return _face_coord; } 66 : 67 : /// Returns the unit normal vector for the face oriented outward from the face's elem element. 68 130139575 : const Point & normal() const { return _normal; } 69 : 70 : /// Returns the coordinates of the face centroid. 71 90150817 : const Point & faceCentroid() const { return _face_centroid; } 72 : 73 : /// Returns the skewness-correction vector (vector between the approximate and real face 74 : /// centroids). 75 : Point skewnessCorrectionVector() const; 76 : 77 : ///@{ 78 : /// Returns the elem and neighbor elements adjacent to the face. 79 : /// If a face is on a mesh boundary, the neighborPtr 80 : /// will return nullptr - the elem will never be null. 81 415054644 : const Elem & elem() const { return *(_elem_info->elem()); } 82 11041021 : const Elem * elemPtr() const { return _elem_info->elem(); } 83 : const Elem & neighbor() const; 84 649848165 : const Elem * neighborPtr() const { return _neighbor_info ? _neighbor_info->elem() : nullptr; } 85 16164773 : const ElemInfo * elemInfo() const { return _elem_info; } 86 15355863 : const ElemInfo * neighborInfo() const { return _neighbor_info; } 87 : ///@} 88 : 89 : /// Returns the element centroids of the elements on the elem and neighbor sides of the face. 90 : /// If no neighbor face is defined, a "ghost" neighbor centroid is calculated by 91 : /// reflecting/extrapolating from the elem centroid through the face centroid 92 : /// - i.e. the vector from the elem element centroid to the face centroid is 93 : /// doubled in length. The tip of this new vector is the neighbor centroid. 94 : /// This is important for FV dirichlet BCs. 95 6037184 : const Point & elemCentroid() const { return _elem_info->centroid(); } 96 : const Point & neighborCentroid() const; 97 : ///@} 98 : 99 : ///@{ 100 : /// Returns the elem and neighbor subdomain IDs. If no neighbor element exists, then 101 : /// an invalid ID is returned for the neighbor subdomain ID. 102 32130939 : SubdomainID elemSubdomainID() const { return _elem_info->subdomain_id(); } 103 : SubdomainID neighborSubdomainID() const; 104 : ///@} 105 : 106 : ///@{ 107 : /// Returns the elem and neighbor centroids. If no neighbor element exists, then 108 : /// the maximum unsigned int is returned for the neighbor side ID. 109 28702027 : unsigned int elemSideID() const { return _elem_side_id; } 110 26447363 : unsigned int neighborSideID() const { return _neighbor_side_id; } 111 : ///@} 112 : 113 : /// Returns which side(s) the given variable-system number pair is defined on for this face. 114 : VarFaceNeighbors faceType(const std::pair<unsigned int, unsigned int> & var_sys) const; 115 : /// Mutably returns which side(s) the given variable-system number pair is defined on for this 116 : /// face. 117 : VarFaceNeighbors & faceType(const std::pair<unsigned int, unsigned int> & var_sys); 118 : 119 : /// Const getter for every associated boundary ID 120 336872499 : const std::set<BoundaryID> & boundaryIDs() const { return _boundary_ids; } 121 : 122 : /// Returns the set of boundary ids for all boundaries that include this face. 123 2092380 : std::set<BoundaryID> & boundaryIDs() { return _boundary_ids; } 124 : 125 : /// Return the element volume 126 1380515 : Real elemVolume() const { return _elem_info->volume(); } 127 : 128 : /// Return the neighbor volume 129 : Real neighborVolume() const; 130 : 131 : /// Return the geometric weighting factor 132 220459118 : Real gC() const { return _gc; } 133 : 134 : /** 135 : * @return the distance vector drawn from centroid C to N, or in terms of MOOSE implementation, 136 : * the distance vector obtained from subtracting the element centroid from the neighbor centroid 137 : */ 138 11932390 : const Point & dCN() const { return _d_cn; } 139 : 140 : /** 141 : * @return the magnitude of the distance vector between centroids C and N, or in terms of MOOSE 142 : * implementation, the magnitude of the distance vector between neighbor and element centroids 143 : */ 144 15402942 : Real dCNMag() const { return _d_cn_mag; } 145 : 146 : /** 147 : * @return the normalized (e.g. unit) distance vector drawn from centroid C to N, or in terms of 148 : * MOOSE implementation, the normalized (e.g. unit) distance vector obtained from subtracting the 149 : * element centroid from the neighbor centroid 150 : */ 151 40477482 : const Point & eCN() const { return _e_cn; } 152 : 153 : /** 154 : * @return the ID of the processor that owns this object 155 : */ 156 32201961 : processor_id_type processor_id() const { return _processor_id; } 157 : 158 : /** 159 : * Takes the ElemInfo of the neighbor cell and computes interpolation weights 160 : * together with other quantities used to generate spatial operators. 161 : */ 162 : void computeInternalCoefficients(const ElemInfo * const neighbor_info); 163 : 164 : /** 165 : * Computes the interpolation weights and similar quantities with the assumption 166 : * that the face is on a boundary. 167 : */ 168 : void computeBoundaryCoefficients(); 169 : 170 : private: 171 : /// Getter for the face type for every stored variable. 172 : /// This will be a friend of MooseMesh to make sure we can only access it from there. 173 2092320 : std::vector<std::vector<VarFaceNeighbors>> & faceType() { return _face_types_by_var; } 174 : 175 : /// the elem and neighbor elems 176 : const ElemInfo * const _elem_info; 177 : const ElemInfo * _neighbor_info; 178 : 179 : const dof_id_type _id; 180 : 181 : Real _face_coord = 0; 182 : Point _normal; 183 : 184 : const processor_id_type _processor_id; 185 : 186 : /// the elem local side id 187 : const unsigned int _elem_side_id; 188 : unsigned int _neighbor_side_id; 189 : 190 : Real _face_area; 191 : Point _face_centroid; 192 : 193 : /// the distance vector between neighbor and element centroids 194 : Point _d_cn; 195 : Point _e_cn; 196 : 197 : /// the distance norm between neighbor and element centroids 198 : Real _d_cn_mag; 199 : 200 : /// Geometric weighting factor for face value interpolation 201 : Real _gc; 202 : 203 : /// A vector that provides the information about what face type this is for each variable. The first 204 : /// index is the system number; the second index of the key is the variable number within the 205 : /// system. 206 : std::vector<std::vector<VarFaceNeighbors>> _face_types_by_var; 207 : 208 : /// the set of boundary ids that this face is associated with 209 : std::set<BoundaryID> _boundary_ids; 210 : 211 : /// Allows access to private members from moose mesh only 212 : friend MooseMesh; 213 : }; 214 : 215 : inline const Elem & 216 19151188 : FaceInfo::neighbor() const 217 : { 218 : mooseAssert(_neighbor_info, 219 : "FaceInfo object 'const Elem & neighbor()' is called but neighbor element pointer " 220 : "is null. This occurs for faces at the domain boundary"); 221 19151188 : return *(_neighbor_info->elem()); 222 : } 223 : 224 : inline FaceInfo::VarFaceNeighbors 225 69226769 : FaceInfo::faceType(const std::pair<unsigned int, unsigned int> & var_sys) const 226 : { 227 : mooseAssert(var_sys.second < _face_types_by_var.size(), "System number out of bounds!"); 228 : mooseAssert(var_sys.first < _face_types_by_var[var_sys.second].size(), 229 : "Variable number out of bounds!"); 230 69226769 : return _face_types_by_var[var_sys.second][var_sys.first]; 231 : } 232 : 233 : inline FaceInfo::VarFaceNeighbors & 234 : FaceInfo::faceType(const std::pair<unsigned int, unsigned int> & var_sys) 235 : { 236 : mooseAssert(var_sys.second < _face_types_by_var.size(), "System number out of bounds!"); 237 : mooseAssert(var_sys.first < _face_types_by_var[var_sys.second].size(), 238 : "Variable number out of bounds!"); 239 : return _face_types_by_var[var_sys.second][var_sys.first]; 240 : } 241 : 242 : inline const Point & 243 21502674 : FaceInfo::neighborCentroid() const 244 : { 245 : mooseAssert(_neighbor_info, 246 : "The neighbor is not defined on this faceInfo! A possible explanation is that the " 247 : "face is a (physical/processor) boundary face."); 248 21502674 : return _neighbor_info->centroid(); 249 : } 250 : 251 : inline SubdomainID 252 32103181 : FaceInfo::neighborSubdomainID() const 253 : { 254 32103181 : return _neighbor_info ? _neighbor_info->subdomain_id() : Moose::INVALID_BLOCK_ID; 255 : } 256 : 257 : inline Real 258 18099898 : FaceInfo::neighborVolume() const 259 : { 260 : mooseAssert(_neighbor_info, 261 : "The neighbor is not defined on this faceInfo! A possible explanation is that the " 262 : "face is a (physical/processor) boundary face."); 263 18099898 : return _neighbor_info->volume(); 264 : }