GEOSX
MeshMapUtilities.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2019 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2019 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2019 TotalEnergies
8  * Copyright (c) 2019- GEOSX Contributors
9  * All right reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 
18 #ifndef GEOS_MESH_UTILITIES_MESHMAPUTILITIES_HPP
19 #define GEOS_MESH_UTILITIES_MESHMAPUTILITIES_HPP
20 
21 #include "common/DataTypes.hpp"
23 
24 
25 namespace geos
26 {
27 
33 namespace meshMapUtilities
34 {
35 
37 
44 template< typename T, int USD >
47 {
48  return map.size( 0 );
49 }
50 
56 template< typename T >
59 {
60  return map.size();
61 }
62 
68 template< typename T >
71 {
72  return map.size();
73 }
74 
76 
86 template< typename POLICY, typename VIEW_TYPE >
88 transposeIndexMap( VIEW_TYPE const & srcMap,
89  localIndex const dstSize,
90  localIndex const overAlloc = 0 )
91 {
92  // Count the number of elements in each set
93  array1d< localIndex > counts( dstSize );
94  counts.setValues< POLICY >( overAlloc );
95  forAll< POLICY >( size0( srcMap ), [srcMap, counts = counts.toView()] ( localIndex const srcIndex )
96  {
97  for( localIndex const dstIndex : srcMap[ srcIndex ] )
98  {
99  RAJA::atomicInc< AtomicPolicy< POLICY > >( &counts[ dstIndex ] );
100  }
101  } );
102 
103  // Allocate storage for the transpose map
105  dstMap.resizeFromCapacities< parallelHostPolicy >( dstSize, counts.data() );
106 
107  // Fill the sub-arrays with unsorted entries
108  forAll< POLICY >( size0( srcMap ), [srcMap, dstMap = dstMap.toView()] ( localIndex const srcIndex )
109  {
110  for( localIndex const dstIndex : srcMap[ srcIndex ] )
111  {
112  dstMap.emplaceBackAtomic< AtomicPolicy< POLICY > >( dstIndex, srcIndex );
113  }
114  } );
115 
116  return dstMap;
117 }
118 
126 template< typename POLICY >
130 {
131  GEOS_ASSERT_EQ( blockToSubRegion.size( 1 ), 2 );
132  localIndex const numObjects = srcMap.toCellIndex.size();
133 
134  localIndex const * offsets = srcMap.toCellIndex.toViewConst().getOffsets();
135  dstMap.m_toElementRegion.resizeFromOffsets( numObjects, offsets );
136  dstMap.m_toElementSubRegion.resizeFromOffsets( numObjects, offsets );
137  dstMap.m_toElementIndex.resizeFromOffsets( numObjects, offsets );
138 
139  forAll< POLICY >( numObjects, [toCell = srcMap.toCellIndex.toViewConst(),
140  toBlock = srcMap.toBlockIndex.toViewConst(),
141  toRegion = dstMap.m_toElementRegion.toView(),
142  toSubRegion = dstMap.m_toElementSubRegion.toView(),
143  toElement = dstMap.m_toElementIndex.toView(),
144  blockToSubRegion]( localIndex const objIndex )
145  {
146  arraySlice1d< localIndex const > const cells = toCell[objIndex];
147  for( localIndex i = 0; i < cells.size(); ++i )
148  {
149  localIndex const blockIndex = toBlock( objIndex, i );
150  localIndex const er = blockToSubRegion( blockIndex, 0 );
151  localIndex const esr = blockToSubRegion( blockIndex, 1 );
152 
153  // Check needed because some blocks may remain unused
154  if( er >= 0 && esr >= 0 )
155  {
156  toRegion.emplaceBack( objIndex, er );
157  toSubRegion.emplaceBack( objIndex, esr );
158  toElement.emplaceBack( objIndex, cells[i] );
159  }
160  }
161  } );
162 }
163 
171 template< typename POLICY, typename PERM1, typename PERM2 >
175 {
176  GEOS_ASSERT_EQ( blockToSubRegion.size( 1 ), 2 );
177  localIndex const numObjects = srcMap.toCellIndex.size( 0 );
178  localIndex const maxCellsPerObject = srcMap.toCellIndex.size( 1 );
179 
180  dstMap.m_toElementRegion.resize( numObjects, maxCellsPerObject );
181  dstMap.m_toElementSubRegion.resize( numObjects, maxCellsPerObject );
182  dstMap.m_toElementIndex.resize( numObjects, maxCellsPerObject );
183 
184  forAll< POLICY >( numObjects, [toCell = srcMap.toCellIndex.toViewConst(),
185  toBlock = srcMap.toBlockIndex.toViewConst(),
186  toRegion = dstMap.m_toElementRegion.toView(),
187  toSubRegion = dstMap.m_toElementSubRegion.toView(),
188  toElement = dstMap.m_toElementIndex.toView(),
189  blockToSubRegion,
190  maxCellsPerObject]( localIndex const objIndex )
191  {
192  arraySlice1d< localIndex const > const cells = toCell[objIndex];
193  localIndex cellCount = 0;
194  for( localIndex i = 0; i < maxCellsPerObject && cells[i] >= 0; ++i )
195  {
196  localIndex const blockIndex = toBlock( objIndex, i );
197  localIndex const er = blockToSubRegion( blockIndex, 0 );
198  localIndex const esr = blockToSubRegion( blockIndex, 1 );
199 
200  // Check needed because some blocks may remain unused
201  if( er >= 0 && esr >= 0 )
202  {
203  toRegion( objIndex, cellCount ) = er;
204  toSubRegion( objIndex, cellCount ) = esr;
205  toElement( objIndex, cellCount ) = cells[i];
206  ++cellCount;
207  }
208  }
209  } );
210 }
211 
212 } // namespace meshMapUtilities
213 
218 template< typename T >
220 {
225  std::size_t operator()( const std::array< T, 6 > & arr ) const
226  {
227  std::size_t hash = 0;
228  // use a boost-style hash function
229  for( auto v : arr )
230  {
231  hash ^= std::hash< T >{} ( v ) + 0x9e3779b9 + ( hash << 6 ) + ( hash >> 2 );
232  }
233  return hash;
234  }
235 };
236 
242 template< typename T >
243 static std::array< T, 6 > createNodeKey( T v )
244 {
245  return std::array< T, 6 > { v, -1, -1, -1, -1, -1 };
246 }
247 
256 template< typename T >
257 static std::array< T, 6 > createNodeKey( T v1, T v2, int a, int order )
258 {
259  if( a == 0 )
260  return createNodeKey( v1 );
261  if( a == order )
262  return createNodeKey( v2 );
263  if( v1 < v2 )
264  {
265  return std::array< T, 6 > { v1, v2, -1, -1, a, -1 };
266  }
267  else
268  {
269  return std::array< T, 6 > { v2, v1, -1, -1, order - a, -1 };
270  }
271 }
272 
284 template< typename T >
285 static std::array< T, 6 > createNodeKey( T v1, T v2, T v3, T v4, int a, int b, int order )
286 {
287  if( a == 0 )
288  return createNodeKey( v1, v3, b, order );
289  if( a == order )
290  return createNodeKey( v2, v4, b, order );
291  if( b == 0 )
292  return createNodeKey( v1, v2, a, order );
293  if( b == order )
294  return createNodeKey( v3, v4, a, order );
295  // arrange the vertices of the face such that v1 is the lowest value, and v2 is lower than v3
296  // this ensures a coherent orientation of all face nodes
297  while( v1 > v2 || v1 > v3 || v1 > v4 || v2 > v3 )
298  {
299  if( v1 > v2 )
300  {
301  std::swap( v1, v2 );
302  std::swap( v3, v4 );
303  a = order - a;
304  }
305  if( v1 > v3 )
306  {
307  std::swap( v1, v3 );
308  std::swap( v2, v4 );
309  b = order - b;
310  }
311  if( v1 > v4 )
312  {
313  std::swap( v1, v4 );
314  std::swap( a, b );
315  a = order - a;
316  b = order - b;
317  }
318  if( v2 > v3 )
319  {
320  std::swap( v2, v3 );
321  std::swap( a, b );
322  }
323  }
324  return std::array< T, 6 > { v1, v2, v3, v4, a, b };
325 }
326 
336 template< typename T >
337 static std::array< T, 6 > createNodeKey( T const (&elemNodes)[ 8 ], int q1, int q2, int q3, int order )
338 {
339  bool extremal1 = q1 == 0 || q1 == order;
340  bool extremal2 = q2 == 0 || q2 == order;
341  bool extremal3 = q3 == 0 || q3 == order;
342  int v1 = q1/order;
343  int v2 = q2/order;
344  int v3 = q3/order;
345  if( extremal1 && extremal2 && extremal3 )
346  {
347  // vertex node
348  return createNodeKey( elemNodes[ v1 + 2*v2 + 4*v3 ] );
349  }
350  else if( extremal1 && extremal2 )
351  {
352  // edge node on v1, v2
353  return createNodeKey( elemNodes[ v1 + 2*v2 ], elemNodes[ v1 + 2*v2 + 4 ], q3, order );
354  }
355  else if( extremal1 && extremal3 )
356  {
357  // edge node on v1, v3
358  return createNodeKey( elemNodes[ v1 + 4*v3 ], elemNodes[ v1 + 2 + 4*v3 ], q2, order );
359  }
360  else if( extremal2 && extremal3 )
361  {
362  // edge node on v2, v3
363  return createNodeKey( elemNodes[ 2*v2 + 4*v3 ], elemNodes[ 1 + 2*v2 + 4*v3 ], q1, order );
364  }
365  else if( extremal1 )
366  {
367  // face node on the face of type 1
368  return createNodeKey( elemNodes[ v1 ], elemNodes[ v1 + 2 ], elemNodes[ v1 + 4 ], elemNodes[ v1 + 2 + 4 ], q2, q3, order );
369  }
370  else if( extremal2 )
371  {
372  // face node on the face of type 2
373  return createNodeKey( elemNodes[ 2*v2 ], elemNodes[ 1 + 2*v2 ], elemNodes[ 2*v2 + 4 ], elemNodes[ 1 + 2*v2 + 4 ], q1, q3, order );
374  }
375  else if( extremal3 )
376  {
377  // face node on the face of type 3
378  return createNodeKey( elemNodes[ 4*v3 ], elemNodes[ 1 + 4*v3 ], elemNodes[ 2 + 4*v3 ], elemNodes[ 1 + 2 + 4*v3 ], q1, q2, order );
379  }
380  else
381  {
382  // node internal to the cell -- no need for key, it will be created
383  return createNodeKey( -1 );
384  }
385 }
386 
387 } // namespace geos
388 
389 #endif //GEOS_MESH_UTILITIES_MESHMAPUTILITIES_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:48
#define GEOS_ASSERT_EQ(lhs, rhs)
Assert that two values compare equal in debug builds.
Definition: Logger.hpp:375
A relationship to an element.
Base template for ordered and unordered maps.
Definition: DataTypes.hpp:369
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:232
LvArray::ArrayOfSetsView< T, INDEX_TYPE const, LvArray::ChaiBuffer > ArrayOfSetsView
View of array of variable-sized sets. See LvArray::ArrayOfSetsView for details.
Definition: DataTypes.hpp:334
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:326
std::size_t size_t
Unsigned size type.
Definition: DataTypes.hpp:119
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:236
GEOSX_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:216
LvArray::ArrayOfArrays< T, INDEX_TYPE, LvArray::ChaiBuffer > ArrayOfArrays
Array of variable-sized arrays. See LvArray::ArrayOfArrays for details.
Definition: DataTypes.hpp:322
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.