GEOSX
MimeticInnerProductHelpers.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 TotalEnergies
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 
19 #ifndef GEOS_FINITEVOLUME_MIMETICINNERPRODUCTS_MIMETICINNERPRODUCTHELPERS_HPP
20 #define GEOS_FINITEVOLUME_MIMETICINNERPRODUCTS_MIMETICINNERPRODUCTHELPERS_HPP
21 
22 namespace geos
23 {
24 namespace mimeticInnerProduct
25 {
26 
32 {
33 
40  static
41  void makeFullTensor( real64 const (&values)[ 3 ],
42  real64 (& result)[ 3 ][ 3 ] )
43  {
44  LvArray::tensorOps::fill< 3, 3 >( result, 0.0 );
45  result[ 0 ][ 0 ] = values[ 0 ];
46  result[ 1 ][ 1 ] = values[ 1 ];
47  result[ 2 ][ 2 ] = values[ 2 ];
48  }
49 
58  template< localIndex NF >
60  static
61  void orthonormalize( real64 (& q0)[ NF ],
62  real64 (& q1)[ NF ],
63  real64 (& q2)[ NF ],
64  real64 (& cellToFaceMat)[ NF ][ 3 ] )
65  {
66  // modified Gram-Schmidt algorithm
67 
68  // q0
69  LvArray::tensorOps::scale< NF >( q0, 1.0/LvArray::tensorOps::l2Norm< NF >( q0 ) );
70 
71  // q1
72  real64 const q0Dotq1 = LvArray::tensorOps::AiBi< NF >( q0, q1 );
73  LvArray::tensorOps::scaledAdd< NF >( q1, q0, -q0Dotq1 );
74  LvArray::tensorOps::scale< NF >( q1, 1.0/LvArray::tensorOps::l2Norm< NF >( q1 ) );
75 
76  // q2
77  real64 const q0Dotq2 = LvArray::tensorOps::AiBi< NF >( q0, q2 );
78  LvArray::tensorOps::scaledAdd< NF >( q2, q0, -q0Dotq2 );
79  real64 const q1Dotq2 = LvArray::tensorOps::AiBi< NF >( q1, q2 );
80  LvArray::tensorOps::scaledAdd< NF >( q2, q1, -q1Dotq2 );
81  LvArray::tensorOps::scale< NF >( q2, 1.0/LvArray::tensorOps::l2Norm< NF >( q2 ) );
82 
83  for( localIndex i = 0; i < NF; ++i )
84  {
85  cellToFaceMat[ i ][ 0 ] = q0[ i ];
86  cellToFaceMat[ i ][ 1 ] = q1[ i ];
87  cellToFaceMat[ i ][ 2 ] = q2[ i ];
88  }
89  }
90 
102  template< localIndex NF >
104  static void
105  computeInvTPFATransWithMultiplier( real64 const (&elemPerm)[ 3 ],
106  real64 const (&faceNormal)[ 3 ],
107  real64 const & faceArea,
108  real64 const & transMult,
109  real64 const & weightToleranceInv,
110  real64 (& cellToFaceVec)[ 3 ],
111  real64 & tpTransInv )
112  {
113  real64 const c2fDistance = LvArray::tensorOps::normalize< 3 >( cellToFaceVec );
114  real64 const mult = transMult;
115  tpTransInv = c2fDistance / faceArea;
116 
117  real64 faceConormal[ 3 ] = { 0.0 };
118  LvArray::tensorOps::hadamardProduct< 3 >( faceConormal, elemPerm, faceNormal );
119  real64 halfWeight = LvArray::tensorOps::AiBi< 3 >( cellToFaceVec, faceConormal );
120  if( halfWeight < 0.0 )
121  {
122  LvArray::tensorOps::hadamardProduct< 3 >( faceConormal, elemPerm, cellToFaceVec );
123  halfWeight = LvArray::tensorOps::AiBi< 3 >( cellToFaceVec, faceConormal );
124  }
125  tpTransInv /= halfWeight;
126  tpTransInv = LvArray::math::min( tpTransInv, weightToleranceInv );
127  tpTransInv *= ( 1.0 - mult ) / mult;
128  }
129 
130 
137  template< localIndex NF >
139  static void
140  computeTransMatrixWithMultipliers( real64 const (&tpTransInv)[ NF ],
141  arraySlice2d< real64 > const & transMatrix )
142  {
143  // the inverse of the pertubed inverse is computed using the Sherman-Morrison formula
144  for( localIndex k = 0; k < NF; ++k )
145  {
146  real64 const mult = LvArray::math::sqrt( tpTransInv[k] );
147  real64 Tmult[ NF ] = { 0.0 };
148  for( localIndex i = 0; i < NF; ++i )
149  {
150  Tmult[i] = transMatrix[k][i] * mult;
151  }
152 
153  real64 const invDenom = 1.0 / ( 1.0 + Tmult[k] * mult );
154  for( localIndex i = 0; i < NF; ++i )
155  {
156  for( localIndex j = 0; j < NF; ++j )
157  {
158  transMatrix[i][j] -= Tmult[i]*Tmult[j]*invDenom;
159  }
160  }
161  }
162  }
163 
164 };
165 
166 } // namespace mimeticInnerProduct
167 
168 } // namespace geos
169 
170 #endif //GEOS_FINITEVOLUME_MIMETICINNERPRODUCTS_MIMETICINNERPRODUCTHELPERS_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:48
ArraySlice< T, 2, USD > arraySlice2d
Alias for 2D array slice.
Definition: DataTypes.hpp:240
double real64
64-bit floating point type.
Definition: DataTypes.hpp:139
GEOSX_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
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.