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