GEOS
MimeticInnerProductBase.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 TotalEnergies
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
20 #ifndef GEOS_FINITEVOLUME_MIMETICINNERPRODUCTS_MIMETICINNERPRODUCTBASE_HPP_
21 #define GEOS_FINITEVOLUME_MIMETICINNERPRODUCTS_MIMETICINNERPRODUCTBASE_HPP_
22 
23 #include "codingUtilities/Utilities.hpp"
26 
27 namespace geos
28 {
29 namespace mimeticInnerProduct
30 {
31 
38 {
39 public:
40 
41  MimeticInnerProductBase() = default;
42 
47  MimeticInnerProductBase( MimeticInnerProductBase const & source ) = default;
48 
51 
57 
63 
67  virtual ~MimeticInnerProductBase() = default;
68 
86  template< localIndex NF >
88  static void
90  arrayView1d< real64 const > const & transMultiplier,
91  ArrayOfArraysView< localIndex const > const & faceToNodes,
92  arraySlice1d< localIndex const > const & elemToFaces,
93  arraySlice1d< real64 const > const & elemCenter,
94  real64 const & elemVolume,
95  real64 const (&elemPerm)[ 3 ],
96  real64 const & tParam,
97  real64 const & lengthTolerance,
98  arraySlice2d< real64 > const & transMatrix );
99 
100 };
101 
102 template< localIndex NF >
104 void
106  arrayView1d< real64 const > const & transMultiplier,
107  ArrayOfArraysView< localIndex const > const & faceToNodes,
108  arraySlice1d< localIndex const > const & elemToFaces,
109  arraySlice1d< real64 const > const & elemCenter,
110  real64 const & elemVolume,
111  real64 const (&elemPerm)[ 3 ],
112  real64 const & tParam,
113  real64 const & lengthTolerance,
114  arraySlice2d< real64 > const & transMatrix )
115 {
116  real64 const areaTolerance = lengthTolerance * lengthTolerance;
117  real64 const weightToleranceInv = 1e30 / lengthTolerance;
118 
119  real64 cellToFaceMat[ NF ][ 3 ] = {{ 0 }};
120  real64 normalsMat[ NF ][ 3 ] = {{ 0 }};
121  real64 permMat[ 3 ][ 3 ] = {{ 0 }};
122 
123  real64 work_dimByNumFaces[ 3 ][ NF ] = {{ 0 }};
124  real64 worka_numFacesByNumFaces[ NF ][ NF ] = {{ 0 }};
125  real64 workb_numFacesByNumFaces[ NF ][ NF ] = {{ 0 }};
126  real64 workc_numFacesByNumFaces[ NF ][ NF ] = {{ 0 }};
127 
128  real64 tpTransInv[ NF ] = { 0.0 };
129 
130  real64 q0[ NF ], q1[ NF ], q2[ NF ];
131 
132  // 0) assemble full coefficient tensor from principal axis/components
133  MimeticInnerProductHelpers::makeFullTensor( elemPerm, permMat );
134 
135  // 1) fill the matrices cellToFaceMat and normalsMat row by row
136  for( localIndex ifaceLoc = 0; ifaceLoc < NF; ++ifaceLoc )
137  {
138  real64 faceCenter[ 3 ], faceNormal[ 3 ], cellToFaceVec[ 3 ];
139  // compute the face geometry data: center, normal, vector from cell center to face center
140  real64 const faceArea =
141  computationalGeometry::centroid_3DPolygon( faceToNodes[elemToFaces[ifaceLoc]],
142  nodePosition,
143  faceCenter,
144  faceNormal,
145  areaTolerance );
146 
147  LvArray::tensorOps::copy< 3 >( cellToFaceVec, faceCenter );
148  LvArray::tensorOps::subtract< 3 >( cellToFaceVec, elemCenter );
149 
150  // we save this for the orthonormalization
151  q0[ ifaceLoc ] = cellToFaceVec[0];
152  q1[ ifaceLoc ] = cellToFaceVec[1];
153  q2[ ifaceLoc ] = cellToFaceVec[2];
154 
155  if( LvArray::tensorOps::AiBi< 3 >( cellToFaceVec, faceNormal ) < 0.0 )
156  {
157  LvArray::tensorOps::scale< 3 >( faceNormal, -1 );
158  }
159 
160  // the two-point transmissibility is computed to computed here because it is needed
161  // in the implementation of the transmissibility multiplier (see below)
162  // TODO: see what it would take to bring the (harmonically averaged) two-point trans here
163  real64 diagEntry = 0.0;
164  MimeticInnerProductHelpers::computeInvTPFATransWithMultiplier< NF >( elemPerm,
165  faceNormal,
166  faceArea,
167  transMultiplier[elemToFaces[ifaceLoc]],
168  weightToleranceInv,
169  cellToFaceVec,
170  diagEntry );
171  tpTransInv[ifaceLoc] = diagEntry;
172 
173  LvArray::tensorOps::scale< 3 >( faceNormal, faceArea );
174  normalsMat[ ifaceLoc ][ 0 ] = faceNormal[ 0 ];
175  normalsMat[ ifaceLoc ][ 1 ] = faceNormal[ 1 ];
176  normalsMat[ ifaceLoc ][ 2 ] = faceNormal[ 2 ];
177 
178  }
179 
180  // 2) compute N K N'
181  LvArray::tensorOps::Rij_eq_AikBjk< 3, NF, 3 >( work_dimByNumFaces,
182  permMat,
183  normalsMat );
184  LvArray::tensorOps::Rij_eq_AikBkj< NF, NF, 3 >( transMatrix,
185  normalsMat,
186  work_dimByNumFaces );
187 
188  // 3) compute the orthonormalization of the matrix cellToFaceVec
189  MimeticInnerProductHelpers::orthonormalize< NF >( q0, q1, q2, cellToFaceMat );
190 
191  // 4) compute P_Q = I - QQ'
192  // note: we compute -P_Q and then at 6) ( - P_Q ) D ( - P_Q )
193  LvArray::tensorOps::addIdentity< NF >( worka_numFacesByNumFaces, -1 );
194  LvArray::tensorOps::Rij_add_AikAjk< NF, 3 >( worka_numFacesByNumFaces,
195  cellToFaceMat );
196 
197  // 5) compute P_Q D P_Q where D = diag(diag(N K N'))
198  // 6) compute T = ( N K N' + t U diag(diag(N K N')) U ) / elemVolume
199  real64 const scale = tParam / elemVolume;
200  for( localIndex i = 0; i < NF; ++i )
201  {
202  workb_numFacesByNumFaces[ i ][ i ] = scale * transMatrix[ i ][ i ];
203  }
204 
205  LvArray::tensorOps::Rij_eq_AikBkj< NF, NF, NF >( workc_numFacesByNumFaces,
206  workb_numFacesByNumFaces,
207  worka_numFacesByNumFaces );
208  LvArray::tensorOps::scale< NF, NF >( transMatrix, 1 / elemVolume );
209  LvArray::tensorOps::Rij_add_AikBkj< NF, NF, NF >( transMatrix,
210  worka_numFacesByNumFaces,
211  workc_numFacesByNumFaces );
212 
213  // 7) incorporate the transmissibility multipliers
214  // Ref: Nilsen, H. M., J. R. Natvig, and K.-A Lie.,
215  // "Accurate modeling of faults by multipoint, mimetic, and mixed methods." SPEJ
216 
217  if( !isZero( LvArray::tensorOps::l2NormSquared< NF >( tpTransInv ) ) )
218  {
219  MimeticInnerProductHelpers::computeTransMatrixWithMultipliers< NF >( tpTransInv,
220  transMatrix );
221  }
222 
223 }
224 
225 } // end namespace mimeticInnerProduct
226 
227 } // end namespace geos
228 
229 #endif //GEOS_FINITEVOLUME_MIMETICINNERPRODUCTS_MIMETICINNERPRODUCTBASE_HPP_
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
static GEOS_HOST_DEVICE void computeParametricInnerProduct(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 &tParam, real64 const &lengthTolerance, arraySlice2d< real64 > const &transMatrix)
In a given element, recompute the transmissibility matrix using a consistent inner product.
MimeticInnerProductBase(MimeticInnerProductBase const &source)=default
Copy Constructor.
MimeticInnerProductBase & operator=(MimeticInnerProductBase &&)=delete
Deleted move assignment operator.
MimeticInnerProductBase & operator=(MimeticInnerProductBase const &)=delete
Deleted copy assignment operator.
virtual ~MimeticInnerProductBase()=default
Destructor.
MimeticInnerProductBase(MimeticInnerProductBase &&)=default
Default Move constructor.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
LvArray::ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, LvArray::ChaiBuffer > ArrayOfArraysView
View of array of variable-sized arrays. See LvArray::ArrayOfArraysView for details.
Definition: DataTypes.hpp:286
ArraySlice< T, 2, USD > arraySlice2d
Alias for 2D array slice.
Definition: DataTypes.hpp:200
double real64
64-bit floating point type.
Definition: DataTypes.hpp:99
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:85
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
Definition: DataTypes.hpp:184
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
static GEOS_HOST_DEVICE void makeFullTensor(real64 const (&values)[3], real64(&result)[3][3])
Create a full tensor from an array.