GEOS
MimeticInnerProductHelpers.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_MIMETICINNERPRODUCTHELPERS_HPP
21 #define GEOS_FINITEVOLUME_MIMETICINNERPRODUCTS_MIMETICINNERPRODUCTHELPERS_HPP
22 
23 namespace geos
24 {
25 namespace mimeticInnerProduct
26 {
27 
33 {
34 
41  static
42  void makeFullTensor( real64 const (&values)[ 3 ],
43  real64 (& result)[ 3 ][ 3 ] )
44  {
45  LvArray::tensorOps::fill< 3, 3 >( result, 0.0 );
46  result[ 0 ][ 0 ] = values[ 0 ];
47  result[ 1 ][ 1 ] = values[ 1 ];
48  result[ 2 ][ 2 ] = values[ 2 ];
49  }
50 
59  template< localIndex NF >
61  static
62  void orthonormalize( real64 (& q0)[ NF ],
63  real64 (& q1)[ NF ],
64  real64 (& q2)[ NF ],
65  real64 (& cellToFaceMat)[ NF ][ 3 ] )
66  {
67  // modified Gram-Schmidt algorithm
68 
69  // q0
70  LvArray::tensorOps::scale< NF >( q0, 1.0/LvArray::tensorOps::l2Norm< NF >( q0 ) );
71 
72  // q1
73  real64 const q0Dotq1 = LvArray::tensorOps::AiBi< NF >( q0, q1 );
74  LvArray::tensorOps::scaledAdd< NF >( q1, q0, -q0Dotq1 );
75  LvArray::tensorOps::scale< NF >( q1, 1.0/LvArray::tensorOps::l2Norm< NF >( q1 ) );
76 
77  // q2
78  real64 const q0Dotq2 = LvArray::tensorOps::AiBi< NF >( q0, q2 );
79  LvArray::tensorOps::scaledAdd< NF >( q2, q0, -q0Dotq2 );
80  real64 const q1Dotq2 = LvArray::tensorOps::AiBi< NF >( q1, q2 );
81  LvArray::tensorOps::scaledAdd< NF >( q2, q1, -q1Dotq2 );
82  LvArray::tensorOps::scale< NF >( q2, 1.0/LvArray::tensorOps::l2Norm< NF >( q2 ) );
83 
84  for( localIndex i = 0; i < NF; ++i )
85  {
86  cellToFaceMat[ i ][ 0 ] = q0[ i ];
87  cellToFaceMat[ i ][ 1 ] = q1[ i ];
88  cellToFaceMat[ i ][ 2 ] = q2[ i ];
89  }
90  }
91 
103  template< localIndex NF >
105  static void
106  computeInvTPFATransWithMultiplier( real64 const (&elemPerm)[ 3 ],
107  real64 const (&faceNormal)[ 3 ],
108  real64 const & faceArea,
109  real64 const & transMult,
110  real64 const & weightToleranceInv,
111  real64 (& cellToFaceVec)[ 3 ],
112  real64 & tpTransInv )
113  {
114  real64 const c2fDistance = LvArray::tensorOps::normalize< 3 >( cellToFaceVec );
115  real64 const mult = transMult;
116  tpTransInv = c2fDistance / faceArea;
117 
118  real64 faceConormal[ 3 ] = { 0.0 };
119  LvArray::tensorOps::hadamardProduct< 3 >( faceConormal, elemPerm, faceNormal );
120  real64 halfWeight = LvArray::tensorOps::AiBi< 3 >( cellToFaceVec, faceConormal );
121  if( halfWeight < 0.0 )
122  {
123  LvArray::tensorOps::hadamardProduct< 3 >( faceConormal, elemPerm, cellToFaceVec );
124  halfWeight = LvArray::tensorOps::AiBi< 3 >( cellToFaceVec, faceConormal );
125  }
126  tpTransInv /= halfWeight;
127  tpTransInv = LvArray::math::min( tpTransInv, weightToleranceInv );
128  tpTransInv *= ( 1.0 - mult ) / mult;
129  }
130 
131 
138  template< localIndex NF >
140  static void
141  computeTransMatrixWithMultipliers( real64 const (&tpTransInv)[ NF ],
142  arraySlice2d< real64 > const & transMatrix )
143  {
144  // the inverse of the pertubed inverse is computed using the Sherman-Morrison formula
145  for( localIndex k = 0; k < NF; ++k )
146  {
147  real64 const mult = LvArray::math::sqrt( tpTransInv[k] );
148  real64 Tmult[ NF ] = { 0.0 };
149  for( localIndex i = 0; i < NF; ++i )
150  {
151  Tmult[i] = transMatrix[k][i] * mult;
152  }
153 
154  real64 const invDenom = 1.0 / ( 1.0 + Tmult[k] * mult );
155  for( localIndex i = 0; i < NF; ++i )
156  {
157  for( localIndex j = 0; j < NF; ++j )
158  {
159  transMatrix[i][j] -= Tmult[i]*Tmult[j]*invDenom;
160  }
161  }
162  }
163  }
164 
165 };
166 
167 } // namespace mimeticInnerProduct
168 
169 } // namespace geos
170 
171 #endif //GEOS_FINITEVOLUME_MIMETICINNERPRODUCTS_MIMETICINNERPRODUCTHELPERS_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
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
Helper struct handling inner product for hybrid finite volume schemes.
static GEOS_HOST_DEVICE void computeInvTPFATransWithMultiplier(real64 const (&elemPerm)[3], real64 const (&faceNormal)[3], real64 const &faceArea, real64 const &transMult, real64 const &weightToleranceInv, real64(&cellToFaceVec)[3], real64 &tpTransInv)
For a given face, compute the TPFA entry incorporating the multiplier.
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 computeTransMatrixWithMultipliers(real64 const (&tpTransInv)[NF], arraySlice2d< real64 > const &transMatrix)
Incorporate the transmissibility multiplier into the transmissibility matrix.
static GEOS_HOST_DEVICE void orthonormalize(real64(&q0)[NF], real64(&q1)[NF], real64(&q2)[NF], real64(&cellToFaceMat)[NF][3])
Orthonormalize a set of three vectors.