GEOS
DofManagerHelpers.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_DOFMANAGERHELPERS_HPP
21 #define GEOS_LINEARALGEBRA_DOFMANAGERHELPERS_HPP
22 
24 
25 namespace geos
26 {
27 
28 // unnamed namespace to avoid needless external linkage
29 namespace
30 {
31 
36 template< FieldLocation LOC >
37 struct MeshHelper;
38 
39 template<>
40 struct MeshHelper< FieldLocation::Node >
41 {
42  using ManagerType = NodeManager;
43  using LocalIndexType = localIndex;
44 
45  static LocalIndexType constexpr invalid_local_index{ -1 };
46 
47  static constexpr char const * managerGroupName() { return MeshLevel::groupStructKeys::nodeManagerString(); }
48  static constexpr char const * mapViewKey() { return ElementSubRegionBase::viewKeyStruct::nodeListString(); }
49  static constexpr char const * syncObjName = "node";
50 
51  template< typename MANAGER >
52  using MapType = typename MANAGER::NodeMapType;
53 };
54 
55 template<>
56 struct MeshHelper< FieldLocation::Edge >
57 {
58  using ManagerType = EdgeManager;
59  using LocalIndexType = localIndex;
60 
61  static LocalIndexType constexpr invalid_local_index{ -1 };
62 
63  static constexpr char const * managerGroupName() { return MeshLevel::groupStructKeys::edgeManagerString(); }
64  static constexpr char const * mapViewKey() { return ElementSubRegionBase::viewKeyStruct::edgeListString(); }
65  static constexpr char const * syncObjName = "edge";
66 
67  template< typename MANAGER >
68  using MapType = typename MANAGER::EdgeMapType;
69 };
70 
71 template<>
72 struct MeshHelper< FieldLocation::Face >
73 {
74  using ManagerType = FaceManager;
75  using LocalIndexType = localIndex;
76 
77  static LocalIndexType constexpr invalid_local_index{ -1 };
78 
79  static constexpr char const * managerGroupName() { return MeshLevel::groupStructKeys::faceManagerString(); }
80  static constexpr char const * mapViewKey() { return ElementSubRegionBase::viewKeyStruct::faceListString(); }
81  static constexpr char const * syncObjName = "face";
82 
83  template< typename MANAGER >
84  using MapType = typename MANAGER::FaceMapType;
85 };
86 
87 template<>
88 struct MeshHelper< FieldLocation::Elem >
89 {
90  using ManagerType = ElementSubRegionBase;
91  using LocalIndexType = std::array< localIndex, 3 >;
92 
93  static LocalIndexType constexpr invalid_local_index{ -1, -1, -1 };
94 
95  static constexpr auto managerGroupName() { return MeshLevel::groupStructKeys::elemManagerString(); }
96  static constexpr auto syncObjName = "elems";
97 
98  template< typename MANAGER >
99  using MapType = typename MANAGER::ElemMapType;
100 };
101 
113 template< FieldLocation LOC, FieldLocation LOC_ADJ >
114 struct MeshIncidence {};
115 
117 template< FieldLocation LOC >
118 struct MeshIncidence< LOC, LOC >
119 {
120  static localIndex constexpr max = 1;
121 };
122 
124 #define SET_MAX_MESH_INCIDENCE( LOC, LOC_ADJ, MAX ) \
125  template<> \
126  struct MeshIncidence< FieldLocation::LOC, FieldLocation::LOC_ADJ > \
127  { \
128  static localIndex constexpr max = MAX; \
129  }
130 
131 SET_MAX_MESH_INCIDENCE( Node, Edge, 10 );
132 SET_MAX_MESH_INCIDENCE( Node, Face, 10 );
133 SET_MAX_MESH_INCIDENCE( Node, Elem, 12 );
134 
135 SET_MAX_MESH_INCIDENCE( Edge, Node, 2 );
136 SET_MAX_MESH_INCIDENCE( Edge, Face, 8 );
137 SET_MAX_MESH_INCIDENCE( Edge, Elem, 8 );
138 
139 SET_MAX_MESH_INCIDENCE( Face, Node, 8 );
140 SET_MAX_MESH_INCIDENCE( Face, Edge, 4 );
141 SET_MAX_MESH_INCIDENCE( Face, Elem, 2 );
142 
143 SET_MAX_MESH_INCIDENCE( Elem, Node, 8 );
144 SET_MAX_MESH_INCIDENCE( Elem, Edge, 12 );
145 SET_MAX_MESH_INCIDENCE( Elem, Face, 6 );
146 
147 #undef SET_MAX_MESH_INCIDENCE
148 
155 template< typename LAMBDA >
156 bool LocationSwitch( FieldLocation const loc,
157  LAMBDA lambda )
158 {
159  switch( loc )
160  {
161  case FieldLocation::Node:
162  {
163  lambda( std::integral_constant< FieldLocation, FieldLocation::Node >() );
164  return true;
165  }
166  case FieldLocation::Edge:
167  {
168  lambda( std::integral_constant< FieldLocation, FieldLocation::Edge >() );
169  return true;
170  }
171  case FieldLocation::Face:
172  {
173  lambda( std::integral_constant< FieldLocation, FieldLocation::Face >() );
174  return true;
175  }
176  case FieldLocation::Elem:
177  {
178  lambda( std::integral_constant< FieldLocation, FieldLocation::Elem >() );
179  return true;
180  }
181  default:
182  return false;
183  }
184 }
185 
186 template< typename LAMBDA >
187 bool LocationSwitch( FieldLocation const loc1,
188  FieldLocation const loc2,
189  LAMBDA lambda )
190 {
191  bool ret2;
192  bool const ret1 =
193  LocationSwitch( loc1, [&]( auto const loc_type1 )
194  {
195  ret2 =
196  LocationSwitch( loc2, [&]( auto const loc_type2 )
197  {
198  lambda( loc_type1, loc_type2 );
199  } );
200  } );
201  return ret1 && ret2;
202 }
203 
204 template< FieldLocation LOC >
205 typename MeshHelper< LOC >::ManagerType const & getObjectManager( MeshLevel const & mesh )
206 {
207  using ObjectManager = typename MeshHelper< LOC >::ManagerType;
208  return mesh.getGroup< ObjectManager >( MeshHelper< LOC >::managerGroupName() );
209 }
210 
211 template< FieldLocation LOC >
212 typename MeshHelper< LOC >::ManagerType & getObjectManager( MeshLevel & mesh )
213 {
214  using ObjectManager = typename MeshHelper< LOC >::ManagerType;
215  return mesh.getGroup< ObjectManager >( MeshHelper< LOC >::managerGroupName() );
216 }
217 
218 ObjectManagerBase const & getObjectManager( FieldLocation const loc,
219  MeshLevel const & mesh )
220 {
221  ObjectManagerBase const * manager = nullptr;
222  LocationSwitch( loc, [&]( auto const LOC )
223  {
224  manager = &getObjectManager< decltype(LOC)::value >( mesh );
225  } );
226  GEOS_ASSERT( manager != nullptr );
227  return *manager;
228 }
229 
230 ObjectManagerBase & getObjectManager( FieldLocation const loc,
231  MeshLevel & mesh )
232 {
233  return const_cast< ObjectManagerBase & >( getObjectManager( loc, const_cast< MeshLevel const & >( mesh ) ) );
234 }
235 
241 template< FieldLocation LOC, typename MANAGER >
242 using MapType = typename MeshHelper< LOC >::template MapType< MANAGER >;
243 
251 template< FieldLocation LOC, FieldLocation CONN_LOC, bool VISIT_GHOSTS >
252 struct MeshVisitor;
253 
262 template< FieldLocation LOC, bool VISIT_GHOSTS >
263 struct MeshVisitor< LOC, LOC, VISIT_GHOSTS >
264 {
265  template< typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
266  static void visit( MeshLevel const & meshLevel,
267  REGIONS_CONTAINER const & regions,
268  LAMBDA && lambda )
269  {
270  // derive some useful type aliases
271  using ObjectManagerLoc = typename MeshHelper< LOC >::ManagerType;
272 
273  // get access to location ghost rank (we don't want to visit ghosted locations
274  ObjectManagerLoc const & objectManager = getObjectManager< LOC >( meshLevel );
275  arrayView1d< integer const > const & ghostRank = objectManager.ghostRank();
276 
277  // create an array to track previously visited locations (to avoid multiple visits)
278  array1d< integer > visited( objectManager.size() );
279 
280  meshLevel.getElemManager().
281  forElementSubRegions< SUBREGIONTYPES... >( regions, [&]( localIndex const, auto const & subRegion )
282  {
283  // derive some more useful, subregion-dependent type aliases
284  using ElemToLocMapType = MapType< LOC, TYPEOFREF( subRegion ) >;
285 
286  // get access to element-to-location map
287  auto const & elemToLocMap =
288  subRegion.template getReference< ElemToLocMapType >( MeshHelper< LOC >::mapViewKey() ).toViewConst();
289 
290  // loop over all elements (including ghosts, which may be necessary to access some locally owned locations)
291  forAll< parallelHostPolicy >( subRegion.size(), [=, visited = visited.toView()]( localIndex const ei )
292  {
293  // loop over all locations incident on an element and increment visitation counter
294  auto const locList = elemToLocMap[ei];
295  for( localIndex a = 0; a < locList.size(); ++a )
296  {
297  localIndex const locIdx = locList[a];
298  // Skip invalid indices
299  if( locIdx >= 0 && ( VISIT_GHOSTS || ghostRank[locIdx] < 0 ) )
300  {
301  RAJA::atomicInc< parallelHostAtomic >( &visited[locIdx] );
302  }
303  }
304  } );
305  } );
306 
307  // turn marker array into a list of indices to visit (this is inherently serial, but fast)
308  array1d< localIndex > locations;
309  locations.reserve( objectManager.size() );
310  for( localIndex i = 0; i < visited.size(); ++i )
311  {
312  if( visited[i] > 0 )
313  {
314  locations.emplace_back( i );
315  }
316  }
317 
318  // optimize for the common case (e.g. all nodes of the mesh) to avoid extra memory access
319  if( locations.size() == objectManager.size() )
320  {
321  forAll< POLICY >( objectManager.size(), [=]( localIndex const locIdx )
322  {
323  lambda( locIdx, locIdx, 0 );
324  } );
325  }
326  else
327  {
328  forAll< POLICY >( locations.size(), [=, locations = locations.toViewConst()]( localIndex const i )
329  {
330  localIndex const locIdx = locations[i];
331  lambda( locIdx, locIdx, 0 );
332  } );
333  }
334  }
335 };
336 
343 template< FieldLocation LOC, FieldLocation CONN_LOC, bool VISIT_GHOSTS >
344 struct MeshVisitor
345 {
346  template< typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
347  static void visit( MeshLevel const & meshLevel,
348  REGIONS_CONTAINER const & regions,
349  LAMBDA && lambda )
350  {
351  // derive some useful type aliases
352  using ObjectManagerLoc = typename MeshHelper< LOC >::ManagerType;
353  using LocToConnMapType = MapType< CONN_LOC, ObjectManagerLoc >;
354 
355  ObjectManagerLoc const & objectManager = getObjectManager< LOC >( meshLevel );
356 
357  // get access to location-to-connected map
358  auto const & locToConnMap =
359  objectManager.template getReference< LocToConnMapType >( MeshHelper< CONN_LOC >::mapViewKey() ).toViewConst();
360 
361  // call the specialized version first, then add an extra loop over connected objects
362  MeshVisitor< LOC, LOC, VISIT_GHOSTS >::
363  template visit< POLICY, SUBREGIONTYPES... >( meshLevel, regions,
364  [=]( localIndex const locIdx,
365  localIndex const,
366  localIndex const )
367  {
368  // loop over all connected locations
369  auto const connList = locToConnMap[locIdx];
370  for( localIndex b = 0; b < connList.size(); ++b )
371  {
372  lambda( locIdx, connList[b], b );
373  }
374  } );
375  }
376 };
377 
386 template< FieldLocation LOC, bool VISIT_GHOSTS >
387 struct MeshVisitor< LOC, FieldLocation::Elem, VISIT_GHOSTS >
388 {
389  template< typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
390  static void visit( MeshLevel const & meshLevel,
391  REGIONS_CONTAINER const & regions,
392  LAMBDA && lambda )
393  {
394  // derive some useful type aliases
395  using ObjectManagerLoc = typename MeshHelper< LOC >::ManagerType;
396  using ToElemMapType = typename MapType< FieldLocation::Elem, ObjectManagerLoc >::base_type;
397 
398  // get mesh object manager for LOC to access maps
399  ObjectManagerLoc const & objectManager = getObjectManager< LOC >( meshLevel );
400 
401  // access to location-to-element map
402  using keys = typename ObjectManagerLoc::viewKeyStruct;
403  auto const & elemRegionList =
404  objectManager.template getReference< ToElemMapType >( keys::elementRegionListString() ).toViewConst();
405  auto const & elemSubRegionList =
406  objectManager.template getReference< ToElemMapType >( keys::elementSubRegionListString() ).toViewConst();
407  auto const & elemIndexList =
408  objectManager.template getReference< ToElemMapType >( keys::elementListString() ).toViewConst();
409 
410  // call the specialized version first, then add an extra loop over connected elements
411  MeshVisitor< LOC, LOC, VISIT_GHOSTS >::
412  template visit< POLICY, SUBREGIONTYPES... >( meshLevel, regions,
413  [=]( localIndex const locIdx,
414  localIndex const,
415  localIndex const )
416  {
417  // loop over all connected locations
418  auto const elemRegions = elemRegionList[ locIdx ];
419  auto const elemSubRegions = elemSubRegionList[ locIdx ];
420  auto const elemIndices = elemIndexList[ locIdx ];
421  for( localIndex b = 0; b < elemIndices.size(); ++b )
422  {
423  MeshHelper< FieldLocation::Elem >::LocalIndexType const elemIdx =
424  { elemRegions[b], elemSubRegions[b], elemIndices[b] };
425 
426  if( elemIdx[0] >= 0 && elemIdx[1] >= 0 && elemIdx[2] >= 0 )
427  {
428  lambda( locIdx, elemIdx, b );
429  }
430  }
431  } );
432  }
433 };
434 
443 template< FieldLocation CONN_LOC, bool VISIT_GHOSTS >
444 struct MeshVisitor< FieldLocation::Elem, CONN_LOC, VISIT_GHOSTS >
445 {
446  template< typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
447  static void visit( MeshLevel const & meshLevel,
448  REGIONS_CONTAINER const & regions,
449  LAMBDA && lambda )
450  {
451  meshLevel.getElemManager().
452  forElementSubRegionsComplete< SUBREGIONTYPES... >( regions, [&]( localIndex const,
453  localIndex const er,
454  localIndex const esr,
455  ElementRegionBase const &,
456  auto const & subRegion )
457  {
458  // derive subregion-dependent map type
459  using ElemToConnMapType = MapType< CONN_LOC, TYPEOFREF( subRegion ) >;
460 
461  // get access to element-to-location map
462  auto const & elemToConnMap =
463  subRegion.template getReference< ElemToConnMapType >( MeshHelper< CONN_LOC >::mapViewKey() ).toViewConst();
464 
465  arrayView1d< integer const > const & ghostRank = subRegion.ghostRank();
466 
467  forAll< POLICY >( subRegion.size(), [=]( localIndex const ei )
468  {
469  if( VISIT_GHOSTS || ghostRank[ei] < 0 )
470  {
471  auto const elemIdx = MeshHelper< FieldLocation::Elem >::LocalIndexType{ er, esr, ei };
472  auto const connList = elemToConnMap[ei];
473 
474  for( localIndex a = 0; a < connList.size(); ++a )
475  {
476  lambda( elemIdx, connList[a], a );
477  }
478  }
479  } );
480  } );
481  }
482 };
483 
488 template< bool VISIT_GHOSTS >
489 struct MeshVisitor< FieldLocation::Elem, FieldLocation::Elem, VISIT_GHOSTS >
490 {
491  template< typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
492  static void visit( MeshLevel const & meshLevel,
493  REGIONS_CONTAINER const & regions,
494  LAMBDA && lambda )
495  {
496  meshLevel.getElemManager().
497  forElementSubRegionsComplete< SUBREGIONTYPES... >( regions, [&]( localIndex const,
498  localIndex const er,
499  localIndex const esr,
500  ElementRegionBase const &,
501  ElementSubRegionBase const & subRegion )
502  {
503  arrayView1d< integer const > const & ghostRank = subRegion.ghostRank();
504 
505  forAll< POLICY >( subRegion.size(), [=]( localIndex const ei )
506  {
507  if( VISIT_GHOSTS || ghostRank[ei] < 0 )
508  {
509  MeshHelper< FieldLocation::Elem >::LocalIndexType elemIdx{ er, esr, ei };
510  lambda( elemIdx, elemIdx, 0 );
511  }
512  } );
513  } );
514  }
515 };
516 
540 template< FieldLocation LOC, FieldLocation CONN_LOC, bool VISIT_GHOSTS,
541  typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
542 void forMeshLocation( MeshLevel const & mesh,
543  REGIONS_CONTAINER const & regions,
544  LAMBDA && lambda )
545 {
546  MeshVisitor< LOC, CONN_LOC, VISIT_GHOSTS >::
547  template visit< POLICY, SUBREGIONTYPES... >( mesh,
548  regions,
549  std::forward< LAMBDA >( lambda ) );
550 }
551 
555 template< FieldLocation LOC, bool VISIT_GHOSTS,
556  typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
557 void forMeshLocation( MeshLevel const & mesh,
558  REGIONS_CONTAINER const & regions,
559  LAMBDA && lambda )
560 {
561  forMeshLocation< LOC, LOC, VISIT_GHOSTS, POLICY, SUBREGIONTYPES... >( mesh,
562  regions,
563  [=]( auto const locIdx, auto, auto )
564  {
565  lambda( locIdx );
566  } );
567 }
568 
579 template< FieldLocation LOC, bool VISIT_GHOSTS, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
580 localIndex countMeshObjects( MeshLevel const & mesh,
581  REGIONS_CONTAINER const & regions )
582 {
583  using countPolicy = parallelHostPolicy;
584  RAJA::ReduceSum< ReducePolicy< countPolicy >, localIndex > count( 0 );
585  forMeshLocation< LOC, VISIT_GHOSTS, countPolicy, SUBREGIONTYPES... >( mesh, regions, [=]( auto )
586  {
587  count += 1;
588  } );
589  return count.get();
590 }
591 
602 template< bool VISIT_GHOSTS, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
603 localIndex countMeshObjects( FieldLocation const location,
604  MeshLevel const & mesh,
605  REGIONS_CONTAINER const & regions )
606 {
607  localIndex count = 0;
608  bool const success = LocationSwitch( location, [&]( auto const loc )
609  {
610  FieldLocation constexpr LOC = decltype(loc)::value;
611  count = countMeshObjects< LOC, VISIT_GHOSTS, SUBREGIONTYPES... >( mesh, regions );
612  } );
613  GEOS_ERROR_IF( !success, GEOS_FMT( "Invalid location type: {}", static_cast< int >( location ) ) );
614  return count;
615 }
616 
623 template< typename T, FieldLocation LOC >
624 struct ArrayHelper
625 {
626  using ArrayType = array1d< std::remove_const_t< T > >;
627  using ViewType = arrayView1d< T >;
628  using Accessor = ViewType;
629 
630  template< typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
631  static void
632  create( MeshLevel & mesh,
633  string const & key,
634  string const & description,
635  REGIONS_CONTAINER const & GEOS_UNUSED_PARAM( regions ) )
636  {
637  ObjectManagerBase & baseManager = getObjectManager< LOC >( mesh );
638  baseManager.registerWrapper< ArrayType >( key ).
639  setApplyDefaultValue( -1 ).
640  setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ).
641  setRestartFlags( dataRepository::RestartFlags::NO_WRITE ).
642  setDescription( description );
643  }
644 
645  static Accessor get( add_const_if_t< MeshLevel, std::is_const< T >::value > & mesh, string const & key )
646  {
647  return getObjectManager< LOC >( mesh ).template getReference< ArrayType >( key );
648  }
649 
650  static inline T value( Accessor const & indexArray, typename MeshHelper< LOC >::LocalIndexType const i )
651  {
652  return indexArray[i];
653  }
654 
655  static inline T & reference( Accessor const & indexArray, typename MeshHelper< LOC >::LocalIndexType const i )
656  {
657  return indexArray[i];
658  }
659 
660  template< typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
661  static void
662  remove( MeshLevel & mesh,
663  string const & key,
664  REGIONS_CONTAINER const & GEOS_UNUSED_PARAM( regions ) )
665  {
666  getObjectManager< LOC >( mesh ).deregisterWrapper( key );
667  }
668 };
669 
674 template< typename T >
675 struct ArrayHelper< T, FieldLocation::Elem >
676 {
677  using ArrayType = array1d< std::remove_const_t< T > >;
678  using ViewType = arrayView1d< T >;
679  using Accessor = ElementRegionManager::ElementViewAccessor< ViewType >;
680 
681  template< typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
682  static void
683  create( MeshLevel & mesh,
684  string const & key,
685  string const & description,
686  REGIONS_CONTAINER const & regions )
687  {
688  mesh.getElemManager().template forElementSubRegions< SUBREGIONTYPES... >( regions,
689  [&]( localIndex const, ElementSubRegionBase & subRegion )
690  {
691  subRegion.registerWrapper< ArrayType >( key ).
692  setApplyDefaultValue( -1 ).
693  setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ).
694  setRestartFlags( dataRepository::RestartFlags::NO_WRITE ).
695  setDescription( description );
696  } );
697  }
698 
699  static Accessor get( add_const_if_t< MeshLevel, std::is_const< T >::value > & mesh, string const & key )
700  {
701  return mesh.getElemManager().template constructViewAccessor< ArrayType, ViewType >( key );
702  }
703 
704  static inline T value( Accessor const & indexArray,
705  MeshHelper< FieldLocation::Elem >::LocalIndexType const & e )
706  {
707  if( indexArray[std::get< 0 >( e )].empty() || indexArray[std::get< 0 >( e )][std::get< 1 >( e )].empty() )
708  {
709  return -1;
710  }
711  return indexArray[std::get< 0 >( e )][std::get< 1 >( e )][std::get< 2 >( e )];
712  }
713 
714  static inline T & reference( Accessor const & indexArray,
715  MeshHelper< FieldLocation::Elem >::LocalIndexType const & e )
716  {
717  return indexArray[std::get< 0 >( e )][std::get< 1 >( e )][std::get< 2 >( e )];
718  }
719 
720  template< typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
721  static void
722  remove( MeshLevel & mesh,
723  string const & key,
724  REGIONS_CONTAINER const & regions )
725  {
726  mesh.getElemManager().template forElementSubRegions< SUBREGIONTYPES... >( regions,
727  [&]( localIndex const, ElementSubRegionBase & subRegion )
728  {
729  subRegion.deregisterWrapper( key );
730  } );
731  }
732 };
733 
734 } // namespace
735 
736 } // namespace geos
737 
738 #endif //GEOS_LINEARALGEBRA_DOFMANAGERHELPERS_HPP
#define SET_MAX_MESH_INCIDENCE(LOC, LOC_ADJ, MAX)
Shortcut macro for declaring adjacency.
#define GEOS_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
Definition: GeosxMacros.hpp:97
#define GEOS_ASSERT(COND)
Assert a condition in debug builds.
Definition: Logger.hpp:868
#define GEOS_ERROR_IF(COND,...)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:217
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:84
FieldLocation
Enum defining the possible location of a field on the mesh.
@ Node
location is node (like displacements in finite elements)
@ Face
location is face (like flux in mixed finite elements)
@ Elem
location is element (like pressure in finite volumes)
@ Edge
location is edge (like flux between fracture elements)
static constexpr char const * nodeListString()
static constexpr char const * edgeListString()
static constexpr char const * faceListString()