20 #ifndef GEOS_FINITEVOLUME_MIMETICINNERPRODUCTS_SIMPLEINNERPRODUCT_HPP_
21 #define GEOS_FINITEVOLUME_MIMETICINNERPRODUCTS_SIMPLEINNERPRODUCT_HPP_
29 namespace mimeticInnerProduct
55 template< localIndex NF >
64 real64 const (&elemPerm)[ 3 ],
65 real64 const & lengthTolerance,
81 template< localIndex NF >
89 real64 const (&elemPerm)[ 3 ],
90 real64 const & lengthTolerance,
94 template< localIndex NF >
102 real64 const & elemVolume,
103 real64 const (&elemPerm)[ 3 ],
104 real64 const & lengthTolerance,
107 real64 const areaTolerance = lengthTolerance * lengthTolerance;
108 real64 const weightToleranceInv = 1e30 / lengthTolerance;
110 real64 cellToFaceMat[ NF ][ 3 ] = {{ 0 }};
111 real64 normalsMat[ NF ][ 3 ] = {{ 0 }};
112 real64 permMat[ 3 ][ 3 ] = {{ 0 }};
114 real64 work_dimByNumFaces[ 3 ][ NF ] = {{ 0 }};
115 real64 worka_numFacesByNumFaces[ NF ][ NF ] = {{ 0 }};
116 real64 workb_numFacesByNumFaces[ NF ][ NF ] = {{ 0 }};
117 real64 workc_numFacesByNumFaces[ NF ][ NF ] = {{ 0 }};
119 real64 tpTransInv[ NF ] = { 0.0 };
121 real64 q0[ NF ], q1[ NF ], q2[ NF ];
129 for(
localIndex ifaceLoc = 0; ifaceLoc < NF; ++ifaceLoc )
131 real64 faceCenter[ 3 ], faceNormal[ 3 ], cellToFaceVec[ 3 ];
133 faceArea[ ifaceLoc ] =
134 computationalGeometry::centroid_3DPolygon( faceToNodes[elemToFaces[ifaceLoc]],
143 q0[ ifaceLoc ] = faceArea[ ifaceLoc ] * cellToFaceVec[ 0 ];
144 q1[ ifaceLoc ] = faceArea[ ifaceLoc ] * cellToFaceVec[ 1 ];
145 q2[ ifaceLoc ] = faceArea[ ifaceLoc ] * cellToFaceVec[ 2 ];
151 MimeticInnerProductHelpers::computeInvTPFATransWithMultiplier< NF >( elemPerm,
154 transMultiplier[elemToFaces[ifaceLoc]],
158 tpTransInv[ifaceLoc] = diagEntry;
160 LvArray::tensorOps::scale< 3 >( faceNormal, faceArea[ ifaceLoc ] );
161 normalsMat[ ifaceLoc ][ 0 ] = faceNormal[ 0 ];
162 normalsMat[ ifaceLoc ][ 1 ] = faceNormal[ 1 ];
163 normalsMat[ ifaceLoc ][ 2 ] = faceNormal[ 2 ];
168 real64 const tParam = 2 * LvArray::tensorOps::trace< 3 >( permMat );
171 LvArray::tensorOps::Rij_eq_AikBjk< 3, NF, 3 >( work_dimByNumFaces,
174 LvArray::tensorOps::Rij_eq_AikBkj< NF, NF, 3 >( transMatrix,
176 work_dimByNumFaces );
179 MimeticInnerProductHelpers::orthonormalize< NF >( q0, q1, q2, cellToFaceMat );
183 LvArray::tensorOps::addIdentity< NF >( worka_numFacesByNumFaces, -1 );
184 LvArray::tensorOps::Rij_add_AikAjk< NF, 3 >( worka_numFacesByNumFaces,
191 workb_numFacesByNumFaces[ i ][ i ] = faceArea[ i ];
194 LvArray::tensorOps::Rij_eq_AikBkj< NF, NF, NF >( workc_numFacesByNumFaces,
195 workb_numFacesByNumFaces,
196 worka_numFacesByNumFaces );
199 LvArray::tensorOps::scale< NF, NF >( transMatrix, 1 / elemVolume );
200 LvArray::tensorOps::scale< NF, NF >( workc_numFacesByNumFaces, -tParam / elemVolume );
201 LvArray::tensorOps::Rij_add_AikBkj< NF, NF, NF >( transMatrix,
202 workc_numFacesByNumFaces,
203 workb_numFacesByNumFaces );
209 if( !isZero( LvArray::tensorOps::l2NormSquared< NF >( tpTransInv ) ) )
211 MimeticInnerProductHelpers::computeTransMatrixWithMultipliers< NF >( tpTransInv,
217 template< localIndex NF >
224 real64 const & elemVolume,
225 real64 const (&elemPerm)[ 3 ],
226 real64 const & lengthTolerance,
229 real64 const areaTolerance = lengthTolerance * lengthTolerance;
232 real64 C[ NF ][ 3 ] = {{ 0 }};
233 real64 N[ NF ][ 3 ] = {{ 0 }};
235 real64 CKCt[ NF ][ NF ] = {{0}};
237 MimeticInnerProductHelpers::computeCellToFaceGeometry< NF >( nodePosition, faceToNodes, elemToFaces,
238 elemCenter, areaTolerance, C, N, A );
239 MimeticInnerProductHelpers::computeConsistencyTerm< NF >( C, elemVolume, elemPerm, CKCt );
242 real64 q0[ NF ], q1[ NF ], q2[ NF ];
246 q0[i] = N[i][0] / A[i];
247 q1[i] = N[i][1] / A[i];
248 q2[i] = N[i][2] / A[i];
251 MimeticInnerProductHelpers::orthonormalize< NF >( q0, q1, q2, Qmat );
257 invA[i] =
real64( 1 ) / A[i];
261 real64 const tParam =
real64( 2 ) * (elemPerm[0] + elemPerm[1] + elemPerm[2]);
262 real64 const scale = elemVolume / tParam;
266 real64 const invAiScaled = scale * invA[i];
268 real64 const qi0 = Qmat[i][0];
269 real64 const qi1 = Qmat[i][1];
270 real64 const qi2 = Qmat[i][2];
275 real64 const qdot = qi0*Qmat[j][0] + qi1*Qmat[j][1] + qi2*Qmat[j][2];
279 real64 const mij = CKCt[i][j] + (invAiScaled * invA[j]) * u;
#define GEOS_HOST_DEVICE
Marks a host-device function.
static GEOS_HOST_DEVICE void computeM(arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const &nodePosition, ArrayOfArraysView< localIndex const > const &faceToNodes, arraySlice1d< localIndex const > const &elemToFaces, arraySlice1d< real64 const > const &elemCenter, real64 const &elemVolume, real64 const (&elemPerm)[3], real64 const &lengthTolerance, arraySlice2d< real64 > const &M)
Compute the mimetic inner product matrix M in a given element using the Simple inner product.
static GEOS_HOST_DEVICE void compute(arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const &nodePosition, arrayView1d< real64 const > const &transMultiplier, ArrayOfArraysView< localIndex const > const &faceToNodes, arraySlice1d< localIndex const > const &elemToFaces, arraySlice1d< real64 const > const &elemCenter, real64 const &elemVolume, real64 const (&elemPerm)[3], real64 const &lengthTolerance, arraySlice2d< real64 > const &transMatrix)
In a given element, recompute the transmissibility matrix in a cell using the Simple inner product.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
LvArray::ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, LvArray::ChaiBuffer > ArrayOfArraysView
View of array of variable-sized arrays. See LvArray::ArrayOfArraysView for details.
ArraySlice< T, 2, USD > arraySlice2d
Alias for 2D array slice.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
static GEOS_HOST_DEVICE void makeFullTensor(real64 const (&values)[3], real64(&result)[3][3])
Create a full tensor from an array.
static GEOS_HOST_DEVICE void orientNormalOutward(real64 const (&cellToFacetVec)[3], real64(&faceNormal)[3])
Ensure the facet normal points outward from the cell.
static GEOS_HOST_DEVICE void computeCellToFacetVector(real64(&cellToFacetVec)[3], real64 const (&facetCenter)[3], arraySlice1d< real64 const > const &cellCenter)
Compute the vector from cell center to facet center.