GEOS
LAIHelperFunctions.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_LINEARALGEBRA_UTILITIES_LAIHELPERFUNCTIONS_HPP_
21 #define GEOS_LINEARALGEBRA_UTILITIES_LAIHELPERFUNCTIONS_HPP_
22 
23 #include "common/DataTypes.hpp"
26 #include "mesh/MeshBody.hpp"
27 #include "mesh/NodeManager.hpp"
29 
30 namespace geos
31 {
32 namespace LAIHelperFunctions
33 {
34 
42 template< typename MATRIX >
43 void makeIdentity( localIndex const n,
44  MPI_Comm const & comm,
45  MATRIX & mat )
46 {
47  mat.createWithLocalSize( n, 1, comm );
48  mat.open();
49  for( globalIndex i = mat.ilower(); i < mat.iupper(); ++i )
50  {
51  mat.insert( i, i, 1.0 );
52  }
53  mat.close();
54 }
55 
64 template< typename MATRIX >
65 void createPermutationMatrix( NodeManager const & nodeManager,
66  int const nDofPerNode,
67  string const & dofKey,
68  MATRIX & permutationMatrix )
69 {
70  /* Crates a permutation matrix for a given nodal variable specified by the DofKey.
71  * It consider that nDofPerNode dofs are associated with each node (e.g., nDofPerNode = 3 for the displacement).
72  *
73  * The permutation matrix maps from the dofs ordering set by the DOFManager to the ordering based on the global
74  * indexes of the nodes.
75  */
76 
77  localIndex const numLocalRows = nodeManager.getNumberOfLocalIndices() * nDofPerNode;
78  permutationMatrix.createWithLocalSize( numLocalRows, numLocalRows, 1, MPI_COMM_GEOS );
79 
80  arrayView1d< globalIndex const > const & dofNumber = nodeManager.getReference< globalIndex_array >( dofKey );
81  arrayView1d< globalIndex const > const & localToGlobal = nodeManager.localToGlobalMap();
82 
83  permutationMatrix.open();
84  for( localIndex a = 0; a < nodeManager.size(); ++a )
85  {
86  if( dofNumber[a] >= 0 )
87  {
88  for( int d = 0; d < nDofPerNode; ++d )
89  {
90  globalIndex const rowIndex = localToGlobal[a] * nDofPerNode + d;
91  globalIndex const columnIndex = dofNumber[a] + d;
92  permutationMatrix.insert( rowIndex, columnIndex, 1.0 );
93  }
94  }
95  }
96  permutationMatrix.close();
97  permutationMatrix.set( 1.0 );
98 }
99 
108 template< typename MATRIX >
110  int const nDofPerCell,
111  string const & dofKey,
112  MATRIX & permutationMatrix )
113 {
114  /* Crates a permutation matrix for a given cell centered variable specified by the DofKey.
115  * It consider that nDofPerCell dofs are associated with each cell (e.g., nDofPerCell = 3 for the displacement).
116  *
117  * The permutation matrix maps from the dofs ordering set by the DOFManager to the ordering based on the global
118  * indexes of the cells.
119  */
120 
121  // Create permutation matrix
122  localIndex numLocalRows = 0;
123  elemManager.forElementSubRegions< ElementSubRegionBase >( [&]( ElementSubRegionBase const & elementSubRegion )
124  {
125  if( elementSubRegion.hasWrapper( dofKey ) )
126  {
127  numLocalRows += elementSubRegion.getNumberOfLocalIndices() * nDofPerCell;
128  }
129  } );
130  permutationMatrix.createWithLocalSize( numLocalRows, numLocalRows, 1, MPI_COMM_GEOS );
131 
132  permutationMatrix.open();
133  elemManager.forElementSubRegions< ElementSubRegionBase >( [&]( ElementSubRegionBase const & elementSubRegion )
134  {
135  localIndex const numElems = elementSubRegion.size();
136  arrayView1d< globalIndex const > const & dofNumber = elementSubRegion.getReference< array1d< globalIndex > >( dofKey );
137  arrayView1d< globalIndex const > const & localToGlobal = elementSubRegion.localToGlobalMap();
138 
139  for( localIndex k = 0; k < numElems; ++k )
140  {
141  if( dofNumber[k] >= 0 )
142  {
143  for( int d = 0; d < nDofPerCell; ++d )
144  {
145  globalIndex const rowIndex = localToGlobal[k] * nDofPerCell + d;
146  globalIndex const columnIndex = dofNumber[k] + d;
147  permutationMatrix.insert( rowIndex, columnIndex, 1.0 );
148  }
149  }
150  }
151  } );
152  permutationMatrix.close();
153  permutationMatrix.set( 1.0 );
154 }
155 
164 template< typename VECTOR, typename MATRIX >
165 VECTOR permuteVector( VECTOR const & vector,
166  MATRIX const & permutationMatrix )
167 {
168  VECTOR permutedVector;
169  permutedVector.create( vector.localSize(), permutationMatrix.comm() );
170  permutationMatrix.apply( vector, permutedVector );
171  return permutedVector;
172 }
173 
180 template< typename MATRIX >
181 MATRIX permuteMatrix( MATRIX const & matrix,
182  MATRIX const & permutationMatrix )
183 {
184  MATRIX permutedMatrix;
185  matrix.multiplyRARt( permutationMatrix, permutedMatrix );
186  return matrix;
187 }
188 
196 template< typename MATRIX >
197 MATRIX permuteMatrix( MATRIX const & matrix,
198  MATRIX const & permutationMatrixLeft,
199  MATRIX const & permutationMatrixRight )
200 {
201  MATRIX permutedMatrix;
202  matrix.multiplyRAP( permutationMatrixLeft, permutationMatrixRight, permutedMatrix );
203  return matrix;
204 }
205 
215 template< typename VECTOR >
218  arrayView1d< globalIndex const > const & dofIndex,
219  globalIndex const dofOffset,
220  localIndex const numLocalDof )
221 {
222  GEOS_ASSERT_EQ( nodePosition.size( 0 ), dofIndex.size() );
223  integer const numComponents = nodePosition.size( 1 );
224  integer const numRidigBodyModes = numComponents * ( numComponents + 1 ) / 2;
225 
226  array1d< VECTOR > rigidBodyModes( numRidigBodyModes );
227 
228  // Translation RBMs
229  for( localIndex k = 0; k < numComponents; ++k )
230  {
231  rigidBodyModes[k].create( numLocalDof, MPI_COMM_GEOS );
232  arrayView1d< real64 > const values = rigidBodyModes[k].open();
233  forAll< parallelHostPolicy >( dofIndex.size(), [=]( localIndex const i )
234  {
235  localIndex const localDof = LvArray::integerConversion< localIndex >( dofIndex[i] - dofOffset );
236  if( 0 <= localDof && localDof < numLocalDof )
237  {
238  values[localDof + k] = 1.0;
239  }
240  } );
241  rigidBodyModes[k].close();
242  rigidBodyModes[k].scale( 1.0 / rigidBodyModes[k].norm2() );
243  }
244 
245  // Rotation RBMs
246  for( localIndex k = numComponents; k < numRidigBodyModes; ++k )
247  {
248  rigidBodyModes[k].create( numLocalDof, MPI_COMM_GEOS );
249  arrayView1d< real64 > const values = rigidBodyModes[k].open();
250  integer const ind[2] = { ( k - numComponents + 1 ) % numComponents,
251  ( k - numComponents + 2 ) % numComponents };
252  forAll< parallelHostPolicy >( dofIndex.size(), [=]( localIndex const i )
253  {
254  localIndex const localDof = LvArray::integerConversion< localIndex >( dofIndex[i] - dofOffset );
255  if( 0 <= localDof && localDof < numLocalDof )
256  {
257  values[localDof + ind[0]] = -nodePosition( i, ind[1] );
258  values[localDof + ind[1]] = +nodePosition( i, ind[0] );
259  }
260  } );
261  rigidBodyModes[k].close();
262  for( localIndex j = 0; j < k; ++j )
263  {
264  rigidBodyModes[k].axpy( -rigidBodyModes[k].dot( rigidBodyModes[j] ), rigidBodyModes[j] );
265  }
266  rigidBodyModes[k].scale( 1.0 / rigidBodyModes[k].norm2() );
267  }
268 
269  return rigidBodyModes;
270 }
271 
272 } // LAIHelperFunctions namespace
273 
274 } // geos namespace
275 
276 #endif /*GEOS_LINEARALGEBRA_UTILITIES_LAIHELPERFUNCTIONS_HPP_*/
MATRIX permuteMatrix(MATRIX const &matrix, MATRIX const &permutationMatrix)
Permute rows and columns of a square matrix.
void createPermutationMatrix(NodeManager const &nodeManager, int const nDofPerNode, string const &dofKey, MATRIX &permutationMatrix)
Create a permutation matrix for a given nodal variable.
void makeIdentity(localIndex const n, MPI_Comm const &comm, MATRIX &mat)
Create an identity matrix.
VECTOR permuteVector(VECTOR const &vector, MATRIX const &permutationMatrix)
Permute a vector.
array1d< VECTOR > computeRigidBodyModes(arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const &nodePosition, arrayView1d< globalIndex const > const &dofIndex, globalIndex const dofOffset, localIndex const numLocalDof)
Computes rigid body modes.
#define GEOS_ASSERT_EQ(lhs, rhs)
Assert that two values compare equal in debug builds.
Definition: Logger.hpp:410
The ElementRegionManager class provides an interface to ObjectManagerBase in order to manage ElementR...
void forElementSubRegions(LAMBDA &&lambda)
This function is used to launch kernel function over the element subregions of all the subregion type...
The NodeManager class provides an interface to ObjectManagerBase in order to manage node data.
Definition: NodeManager.hpp:46
arrayView1d< globalIndex > localToGlobalMap()
Get local to global map.
localIndex getNumberOfLocalIndices() const
Get the number of locally owned objects.
GEOS_DECLTYPE_AUTO_RETURN getReference(LOOKUP_TYPE const &lookup) const
Look up a wrapper and get reference to wrapped object.
Definition: Group.hpp:1275
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Definition: Group.hpp:1317
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:179
int MPI_COMM_GEOS
Global MPI communicator used by GEOSX.
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:87
array1d< globalIndex > globalIndex_array
A 1-dimensional array of geos::globalIndex types.
Definition: DataTypes.hpp:370
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:84
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:195
int integer
Signed integer type.
Definition: DataTypes.hpp:81
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:175