GEOS
MeshMapUtilities.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 Total, S.A
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 
19 #ifndef GEOS_MESH_UTILITIES_MESHMAPUTILITIES_HPP
20 #define GEOS_MESH_UTILITIES_MESHMAPUTILITIES_HPP
21 
22 #include "common/DataTypes.hpp"
24 
25 
26 namespace geos
27 {
28 
34 namespace meshMapUtilities
35 {
36 
38 
45 template< typename T, int USD >
48 {
49  return map.size( 0 );
50 }
51 
57 template< typename T >
60 {
61  return map.size();
62 }
63 
69 template< typename T >
72 {
73  return map.size();
74 }
75 
77 
87 template< typename POLICY, typename VIEW_TYPE >
89 transposeIndexMap( VIEW_TYPE const & srcMap,
90  localIndex const dstSize,
91  localIndex const overAlloc = 0 )
92 {
93  // Count the number of elements in each set
94  array1d< localIndex > counts( dstSize );
95  counts.setValues< POLICY >( overAlloc );
96  forAll< POLICY >( size0( srcMap ), [srcMap, counts = counts.toView()] ( localIndex const srcIndex )
97  {
98  for( localIndex const dstIndex : srcMap[ srcIndex ] )
99  {
100  RAJA::atomicInc< AtomicPolicy< POLICY > >( &counts[ dstIndex ] );
101  }
102  } );
103 
104  // Allocate storage for the transpose map
106  dstMap.resizeFromCapacities< parallelHostPolicy >( dstSize, counts.data() );
107 
108  // Fill the sub-arrays with unsorted entries
109  forAll< POLICY >( size0( srcMap ), [srcMap, dstMap = dstMap.toView()] ( localIndex const srcIndex )
110  {
111  for( localIndex const dstIndex : srcMap[ srcIndex ] )
112  {
113  dstMap.emplaceBackAtomic< AtomicPolicy< POLICY > >( dstIndex, srcIndex );
114  }
115  } );
116 
117  return dstMap;
118 }
119 
127 template< typename POLICY >
131 {
132  GEOS_ASSERT_EQ( blockToSubRegion.size( 1 ), 2 );
133  localIndex const numObjects = srcMap.toCellIndex.size();
134 
135  localIndex const * offsets = srcMap.toCellIndex.toViewConst().getOffsets();
136  dstMap.m_toElementRegion.resizeFromOffsets( numObjects, offsets );
137  dstMap.m_toElementSubRegion.resizeFromOffsets( numObjects, offsets );
138  dstMap.m_toElementIndex.resizeFromOffsets( numObjects, offsets );
139 
140  forAll< POLICY >( numObjects, [toCell = srcMap.toCellIndex.toViewConst(),
141  toBlock = srcMap.toBlockIndex.toViewConst(),
142  toRegion = dstMap.m_toElementRegion.toView(),
143  toSubRegion = dstMap.m_toElementSubRegion.toView(),
144  toElement = dstMap.m_toElementIndex.toView(),
145  blockToSubRegion]( localIndex const objIndex )
146  {
147  arraySlice1d< localIndex const > const cells = toCell[objIndex];
148  for( localIndex i = 0; i < cells.size(); ++i )
149  {
150  localIndex const blockIndex = toBlock( objIndex, i );
151  localIndex const er = blockToSubRegion( blockIndex, 0 );
152  localIndex const esr = blockToSubRegion( blockIndex, 1 );
153 
154  // Check needed because some blocks may remain unused
155  if( er >= 0 && esr >= 0 )
156  {
157  toRegion.emplaceBack( objIndex, er );
158  toSubRegion.emplaceBack( objIndex, esr );
159  toElement.emplaceBack( objIndex, cells[i] );
160  }
161  }
162  } );
163 }
164 
172 template< typename POLICY, typename PERM1, typename PERM2 >
176 {
177  GEOS_ASSERT_EQ( blockToSubRegion.size( 1 ), 2 );
178  localIndex const numObjects = srcMap.toCellIndex.size( 0 );
179  localIndex const maxCellsPerObject = srcMap.toCellIndex.size( 1 );
180 
181  dstMap.m_toElementRegion.resize( numObjects, maxCellsPerObject );
182  dstMap.m_toElementSubRegion.resize( numObjects, maxCellsPerObject );
183  dstMap.m_toElementIndex.resize( numObjects, maxCellsPerObject );
184 
185  forAll< POLICY >( numObjects, [toCell = srcMap.toCellIndex.toViewConst(),
186  toBlock = srcMap.toBlockIndex.toViewConst(),
187  toRegion = dstMap.m_toElementRegion.toView(),
188  toSubRegion = dstMap.m_toElementSubRegion.toView(),
189  toElement = dstMap.m_toElementIndex.toView(),
190  blockToSubRegion,
191  maxCellsPerObject]( localIndex const objIndex )
192  {
193  arraySlice1d< localIndex const > const cells = toCell[objIndex];
194  localIndex cellCount = 0;
195  for( localIndex i = 0; i < maxCellsPerObject && cells[i] >= 0; ++i )
196  {
197  localIndex const blockIndex = toBlock( objIndex, i );
198  localIndex const er = blockToSubRegion( blockIndex, 0 );
199  localIndex const esr = blockToSubRegion( blockIndex, 1 );
200 
201  // Check needed because some blocks may remain unused
202  if( er >= 0 && esr >= 0 )
203  {
204  toRegion( objIndex, cellCount ) = er;
205  toSubRegion( objIndex, cellCount ) = esr;
206  toElement( objIndex, cellCount ) = cells[i];
207  ++cellCount;
208  }
209  }
210  } );
211 }
212 
213 } // namespace meshMapUtilities
214 
219 template< typename T >
221 {
226  std::size_t operator()( const std::array< T, 6 > & arr ) const
227  {
228  std::size_t hash = 0;
229  // use a boost-style hash function
230  for( auto v : arr )
231  {
232  hash ^= std::hash< T >{} ( v ) + 0x9e3779b9 + ( hash << 6 ) + ( hash >> 2 );
233  }
234  return hash;
235  }
236 };
237 
243 template< typename T >
244 static std::array< T, 6 > createNodeKey( T v )
245 {
246  return std::array< T, 6 > { v, -1, -1, -1, -1, -1 };
247 }
248 
257 template< typename T >
258 static std::array< T, 6 > createNodeKey( T v1, T v2, int a, int order )
259 {
260  if( a == 0 )
261  return createNodeKey( v1 );
262  if( a == order )
263  return createNodeKey( v2 );
264  if( v1 < v2 )
265  {
266  return std::array< T, 6 > { v1, v2, -1, -1, a, -1 };
267  }
268  else
269  {
270  return std::array< T, 6 > { v2, v1, -1, -1, order - a, -1 };
271  }
272 }
273 
285 template< typename T >
286 static std::array< T, 6 > createNodeKey( T v1, T v2, T v3, T v4, int a, int b, int order )
287 {
288  if( a == 0 )
289  return createNodeKey( v1, v3, b, order );
290  if( a == order )
291  return createNodeKey( v2, v4, b, order );
292  if( b == 0 )
293  return createNodeKey( v1, v2, a, order );
294  if( b == order )
295  return createNodeKey( v3, v4, a, order );
296  // arrange the vertices of the face such that v1 is the lowest value, and v2 is lower than v3
297  // this ensures a coherent orientation of all face nodes
298  while( v1 > v2 || v1 > v3 || v1 > v4 || v2 > v3 )
299  {
300  if( v1 > v2 )
301  {
302  std::swap( v1, v2 );
303  std::swap( v3, v4 );
304  a = order - a;
305  }
306  if( v1 > v3 )
307  {
308  std::swap( v1, v3 );
309  std::swap( v2, v4 );
310  b = order - b;
311  }
312  if( v1 > v4 )
313  {
314  std::swap( v1, v4 );
315  std::swap( a, b );
316  a = order - a;
317  b = order - b;
318  }
319  if( v2 > v3 )
320  {
321  std::swap( v2, v3 );
322  std::swap( a, b );
323  }
324  }
325  return std::array< T, 6 > { v1, v2, v3, v4, a, b };
326 }
327 
337 template< typename T >
338 static std::array< T, 6 > createNodeKey( T const (&elemNodes)[ 8 ], int q1, int q2, int q3, int order )
339 {
340  bool extremal1 = q1 == 0 || q1 == order;
341  bool extremal2 = q2 == 0 || q2 == order;
342  bool extremal3 = q3 == 0 || q3 == order;
343  int v1 = q1/order;
344  int v2 = q2/order;
345  int v3 = q3/order;
346  if( extremal1 && extremal2 && extremal3 )
347  {
348  // vertex node
349  return createNodeKey( elemNodes[ v1 + 2*v2 + 4*v3 ] );
350  }
351  else if( extremal1 && extremal2 )
352  {
353  // edge node on v1, v2
354  return createNodeKey( elemNodes[ v1 + 2*v2 ], elemNodes[ v1 + 2*v2 + 4 ], q3, order );
355  }
356  else if( extremal1 && extremal3 )
357  {
358  // edge node on v1, v3
359  return createNodeKey( elemNodes[ v1 + 4*v3 ], elemNodes[ v1 + 2 + 4*v3 ], q2, order );
360  }
361  else if( extremal2 && extremal3 )
362  {
363  // edge node on v2, v3
364  return createNodeKey( elemNodes[ 2*v2 + 4*v3 ], elemNodes[ 1 + 2*v2 + 4*v3 ], q1, order );
365  }
366  else if( extremal1 )
367  {
368  // face node on the face of type 1
369  return createNodeKey( elemNodes[ v1 ], elemNodes[ v1 + 2 ], elemNodes[ v1 + 4 ], elemNodes[ v1 + 2 + 4 ], q2, q3, order );
370  }
371  else if( extremal2 )
372  {
373  // face node on the face of type 2
374  return createNodeKey( elemNodes[ 2*v2 ], elemNodes[ 1 + 2*v2 ], elemNodes[ 2*v2 + 4 ], elemNodes[ 1 + 2*v2 + 4 ], q1, q3, order );
375  }
376  else if( extremal3 )
377  {
378  // face node on the face of type 3
379  return createNodeKey( elemNodes[ 4*v3 ], elemNodes[ 1 + 4*v3 ], elemNodes[ 2 + 4*v3 ], elemNodes[ 1 + 2 + 4*v3 ], q1, q2, order );
380  }
381  else
382  {
383  // node internal to the cell -- no need for key, it will be created
384  return createNodeKey( -1 );
385  }
386 }
387 
388 } // namespace geos
389 
390 #endif //GEOS_MESH_UTILITIES_MESHMAPUTILITIES_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
#define GEOS_ASSERT_EQ(lhs, rhs)
Assert that two values compare equal in debug builds.
Definition: Logger.hpp:410
A relationship to an element.
Base template for ordered and unordered maps.
Definition: DataTypes.hpp:329
ArrayOfArrays< std::remove_const_t< typename VIEW_TYPE::ValueType > > transposeIndexMap(VIEW_TYPE const &srcMap, localIndex const dstSize, localIndex const overAlloc=0)
Transposes an input map (array2d, ArrayOfArrays or ArrayOfSets)
void transformCellBlockToRegionMap(arrayView2d< localIndex const > const &blockToSubRegion, ToCellRelation< array2d< localIndex, PERM1 > > const &srcMap, ToElementRelation< array2d< localIndex, PERM2 > > &dstMap)
Convert ToCellRelation into ToElementRelation.
GEOS_HOST_DEVICE localIndex size0(arrayView2d< T, USD > const &map)
Array< T, 2, PERMUTATION > array2d
Alias for 2D array.
Definition: DataTypes.hpp:192
LvArray::ArrayOfSetsView< T, INDEX_TYPE const, LvArray::ChaiBuffer > ArrayOfSetsView
View of array of variable-sized sets. See LvArray::ArrayOfSetsView for details.
Definition: DataTypes.hpp:294
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
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:85
std::size_t size_t
Unsigned size type.
Definition: DataTypes.hpp:79
static std::array< T, 6 > createNodeKey(T const (&elemNodes)[8], int q1, int q2, int q3, int order)
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:176
LvArray::ArrayOfArrays< T, INDEX_TYPE, LvArray::ChaiBuffer > ArrayOfArrays
Array of variable-sized arrays. See LvArray::ArrayOfArrays for details.
Definition: DataTypes.hpp:282
Strucure used to hash interpolation arrays representing high-order nodes.
std::size_t operator()(const std::array< T, 6 > &arr) const
Container for maps from a mesh object (node, edge or face) to cells.