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  if( VISIT_GHOSTS || ghostRank[locIdx] < 0 )
299  {
300  RAJA::atomicInc< parallelHostAtomic >( &visited[locIdx] );
301  }
302  }
303  } );
304  } );
305 
306  // turn marker array into a list of indices to visit (this is inherently serial, but fast)
307  array1d< localIndex > locations;
308  locations.reserve( objectManager.size() );
309  for( localIndex i = 0; i < visited.size(); ++i )
310  {
311  if( visited[i] > 0 )
312  {
313  locations.emplace_back( i );
314  }
315  }
316 
317  // optimize for the common case (e.g. all nodes of the mesh) to avoid extra memory access
318  if( locations.size() == objectManager.size() )
319  {
320  forAll< POLICY >( objectManager.size(), [=]( localIndex const locIdx )
321  {
322  lambda( locIdx, locIdx, 0 );
323  } );
324  }
325  else
326  {
327  forAll< POLICY >( locations.size(), [=, locations = locations.toViewConst()]( localIndex const i )
328  {
329  localIndex const locIdx = locations[i];
330  lambda( locIdx, locIdx, 0 );
331  } );
332  }
333  }
334 };
335 
342 template< FieldLocation LOC, FieldLocation CONN_LOC, bool VISIT_GHOSTS >
343 struct MeshVisitor
344 {
345  template< typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
346  static void visit( MeshLevel const & meshLevel,
347  REGIONS_CONTAINER const & regions,
348  LAMBDA && lambda )
349  {
350  // derive some useful type aliases
351  using ObjectManagerLoc = typename MeshHelper< LOC >::ManagerType;
352  using LocToConnMapType = MapType< CONN_LOC, ObjectManagerLoc >;
353 
354  ObjectManagerLoc const & objectManager = getObjectManager< LOC >( meshLevel );
355 
356  // get access to location-to-connected map
357  auto const & locToConnMap =
358  objectManager.template getReference< LocToConnMapType >( MeshHelper< CONN_LOC >::mapViewKey() ).toViewConst();
359 
360  // call the specialized version first, then add an extra loop over connected objects
361  MeshVisitor< LOC, LOC, VISIT_GHOSTS >::
362  template visit< POLICY, SUBREGIONTYPES... >( meshLevel, regions,
363  [=]( localIndex const locIdx,
364  localIndex const,
365  localIndex const )
366  {
367  // loop over all connected locations
368  auto const connList = locToConnMap[locIdx];
369  for( localIndex b = 0; b < connList.size(); ++b )
370  {
371  lambda( locIdx, connList[b], b );
372  }
373  } );
374  }
375 };
376 
385 template< FieldLocation LOC, bool VISIT_GHOSTS >
386 struct MeshVisitor< LOC, FieldLocation::Elem, VISIT_GHOSTS >
387 {
388  template< typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
389  static void visit( MeshLevel const & meshLevel,
390  REGIONS_CONTAINER const & regions,
391  LAMBDA && lambda )
392  {
393  // derive some useful type aliases
394  using ObjectManagerLoc = typename MeshHelper< LOC >::ManagerType;
395  using ToElemMapType = typename MapType< FieldLocation::Elem, ObjectManagerLoc >::base_type;
396 
397  // get mesh object manager for LOC to access maps
398  ObjectManagerLoc const & objectManager = getObjectManager< LOC >( meshLevel );
399 
400  // access to location-to-element map
401  using keys = typename ObjectManagerLoc::viewKeyStruct;
402  auto const & elemRegionList =
403  objectManager.template getReference< ToElemMapType >( keys::elementRegionListString() ).toViewConst();
404  auto const & elemSubRegionList =
405  objectManager.template getReference< ToElemMapType >( keys::elementSubRegionListString() ).toViewConst();
406  auto const & elemIndexList =
407  objectManager.template getReference< ToElemMapType >( keys::elementListString() ).toViewConst();
408 
409  // call the specialized version first, then add an extra loop over connected elements
410  MeshVisitor< LOC, LOC, VISIT_GHOSTS >::
411  template visit< POLICY, SUBREGIONTYPES... >( meshLevel, regions,
412  [=]( localIndex const locIdx,
413  localIndex const,
414  localIndex const )
415  {
416  // loop over all connected locations
417  auto const elemRegions = elemRegionList[ locIdx ];
418  auto const elemSubRegions = elemSubRegionList[ locIdx ];
419  auto const elemIndices = elemIndexList[ locIdx ];
420  for( localIndex b = 0; b < elemIndices.size(); ++b )
421  {
422  MeshHelper< FieldLocation::Elem >::LocalIndexType const elemIdx =
423  { elemRegions[b], elemSubRegions[b], elemIndices[b] };
424 
425  if( elemIdx[0] >= 0 && elemIdx[1] >= 0 && elemIdx[2] >= 0 )
426  {
427  lambda( locIdx, elemIdx, b );
428  }
429  }
430  } );
431  }
432 };
433 
442 template< FieldLocation CONN_LOC, bool VISIT_GHOSTS >
443 struct MeshVisitor< FieldLocation::Elem, CONN_LOC, VISIT_GHOSTS >
444 {
445  template< typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
446  static void visit( MeshLevel const & meshLevel,
447  REGIONS_CONTAINER const & regions,
448  LAMBDA && lambda )
449  {
450  meshLevel.getElemManager().
451  forElementSubRegionsComplete< SUBREGIONTYPES... >( regions, [&]( localIndex const,
452  localIndex const er,
453  localIndex const esr,
454  ElementRegionBase const &,
455  auto const & subRegion )
456  {
457  // derive subregion-dependent map type
458  using ElemToConnMapType = MapType< CONN_LOC, TYPEOFREF( subRegion ) >;
459 
460  // get access to element-to-location map
461  auto const & elemToConnMap =
462  subRegion.template getReference< ElemToConnMapType >( MeshHelper< CONN_LOC >::mapViewKey() ).toViewConst();
463 
464  arrayView1d< integer const > const & ghostRank = subRegion.ghostRank();
465 
466  forAll< POLICY >( subRegion.size(), [=]( localIndex const ei )
467  {
468  if( VISIT_GHOSTS || ghostRank[ei] < 0 )
469  {
470  auto const elemIdx = MeshHelper< FieldLocation::Elem >::LocalIndexType{ er, esr, ei };
471  auto const connList = elemToConnMap[ei];
472 
473  for( localIndex a = 0; a < connList.size(); ++a )
474  {
475  lambda( elemIdx, connList[a], a );
476  }
477  }
478  } );
479  } );
480  }
481 };
482 
487 template< bool VISIT_GHOSTS >
488 struct MeshVisitor< FieldLocation::Elem, FieldLocation::Elem, VISIT_GHOSTS >
489 {
490  template< typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
491  static void visit( MeshLevel const & meshLevel,
492  REGIONS_CONTAINER const & regions,
493  LAMBDA && lambda )
494  {
495  meshLevel.getElemManager().
496  forElementSubRegionsComplete< SUBREGIONTYPES... >( regions, [&]( localIndex const,
497  localIndex const er,
498  localIndex const esr,
499  ElementRegionBase const &,
500  ElementSubRegionBase const & subRegion )
501  {
502  arrayView1d< integer const > const & ghostRank = subRegion.ghostRank();
503 
504  forAll< POLICY >( subRegion.size(), [=]( localIndex const ei )
505  {
506  if( VISIT_GHOSTS || ghostRank[ei] < 0 )
507  {
508  MeshHelper< FieldLocation::Elem >::LocalIndexType elemIdx{ er, esr, ei };
509  lambda( elemIdx, elemIdx, 0 );
510  }
511  } );
512  } );
513  }
514 };
515 
539 template< FieldLocation LOC, FieldLocation CONN_LOC, bool VISIT_GHOSTS,
540  typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
541 void forMeshLocation( MeshLevel const & mesh,
542  REGIONS_CONTAINER const & regions,
543  LAMBDA && lambda )
544 {
545  MeshVisitor< LOC, CONN_LOC, VISIT_GHOSTS >::
546  template visit< POLICY, SUBREGIONTYPES... >( mesh,
547  regions,
548  std::forward< LAMBDA >( lambda ) );
549 }
550 
554 template< FieldLocation LOC, bool VISIT_GHOSTS,
555  typename POLICY, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER, typename LAMBDA >
556 void forMeshLocation( MeshLevel const & mesh,
557  REGIONS_CONTAINER const & regions,
558  LAMBDA && lambda )
559 {
560  forMeshLocation< LOC, LOC, VISIT_GHOSTS, POLICY, SUBREGIONTYPES... >( mesh,
561  regions,
562  [=]( auto const locIdx, auto, auto )
563  {
564  lambda( locIdx );
565  } );
566 }
567 
578 template< FieldLocation LOC, bool VISIT_GHOSTS, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
579 localIndex countMeshObjects( MeshLevel const & mesh,
580  REGIONS_CONTAINER const & regions )
581 {
582  using countPolicy = parallelHostPolicy;
583  RAJA::ReduceSum< ReducePolicy< countPolicy >, localIndex > count( 0 );
584  forMeshLocation< LOC, VISIT_GHOSTS, countPolicy, SUBREGIONTYPES... >( mesh, regions, [=]( auto )
585  {
586  count += 1;
587  } );
588  return count.get();
589 }
590 
601 template< bool VISIT_GHOSTS, typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
602 localIndex countMeshObjects( FieldLocation const location,
603  MeshLevel const & mesh,
604  REGIONS_CONTAINER const & regions )
605 {
606  localIndex count = 0;
607  bool const success = LocationSwitch( location, [&]( auto const loc )
608  {
609  FieldLocation constexpr LOC = decltype(loc)::value;
610  count = countMeshObjects< LOC, VISIT_GHOSTS, SUBREGIONTYPES... >( mesh, regions );
611  } );
612  GEOS_ERROR_IF( !success, "Invalid location type: " << static_cast< int >( location ) );
613  return count;
614 }
615 
622 template< typename T, FieldLocation LOC >
623 struct ArrayHelper
624 {
625  using ArrayType = array1d< std::remove_const_t< T > >;
626  using ViewType = arrayView1d< T >;
627  using Accessor = ViewType;
628 
629  template< typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
630  static void
631  create( MeshLevel & mesh,
632  string const & key,
633  string const & description,
634  REGIONS_CONTAINER const & GEOS_UNUSED_PARAM( regions ) )
635  {
636  ObjectManagerBase & baseManager = getObjectManager< LOC >( mesh );
637  baseManager.registerWrapper< ArrayType >( key ).
638  setApplyDefaultValue( -1 ).
639  setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ).
640  setRestartFlags( dataRepository::RestartFlags::NO_WRITE ).
641  setDescription( description );
642  }
643 
644  static Accessor get( add_const_if_t< MeshLevel, std::is_const< T >::value > & mesh, string const & key )
645  {
646  return getObjectManager< LOC >( mesh ).template getReference< ArrayType >( key );
647  }
648 
649  static inline T value( Accessor const & indexArray, typename MeshHelper< LOC >::LocalIndexType const i )
650  {
651  return indexArray[i];
652  }
653 
654  static inline T & reference( Accessor const & indexArray, typename MeshHelper< LOC >::LocalIndexType const i )
655  {
656  return indexArray[i];
657  }
658 
659  template< typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
660  static void
661  remove( MeshLevel & mesh,
662  string const & key,
663  REGIONS_CONTAINER const & GEOS_UNUSED_PARAM( regions ) )
664  {
665  getObjectManager< LOC >( mesh ).deregisterWrapper( key );
666  }
667 };
668 
673 template< typename T >
674 struct ArrayHelper< T, FieldLocation::Elem >
675 {
676  using ArrayType = array1d< std::remove_const_t< T > >;
677  using ViewType = arrayView1d< T >;
678  using Accessor = ElementRegionManager::ElementViewAccessor< ViewType >;
679 
680  template< typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
681  static void
682  create( MeshLevel & mesh,
683  string const & key,
684  string const & description,
685  REGIONS_CONTAINER const & regions )
686  {
687  mesh.getElemManager().template forElementSubRegions< SUBREGIONTYPES... >( regions,
688  [&]( localIndex const, ElementSubRegionBase & subRegion )
689  {
690  subRegion.registerWrapper< ArrayType >( key ).
691  setApplyDefaultValue( -1 ).
692  setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ).
693  setRestartFlags( dataRepository::RestartFlags::NO_WRITE ).
694  setDescription( description );
695  } );
696  }
697 
698  static Accessor get( add_const_if_t< MeshLevel, std::is_const< T >::value > & mesh, string const & key )
699  {
700  return mesh.getElemManager().template constructViewAccessor< ArrayType, ViewType >( key );
701  }
702 
703  static inline T value( Accessor const & indexArray,
704  MeshHelper< FieldLocation::Elem >::LocalIndexType const & e )
705  {
706  if( indexArray[std::get< 0 >( e )].empty() || indexArray[std::get< 0 >( e )][std::get< 1 >( e )].empty() )
707  {
708  return -1;
709  }
710  return indexArray[std::get< 0 >( e )][std::get< 1 >( e )][std::get< 2 >( e )];
711  }
712 
713  static inline T & reference( Accessor const & indexArray,
714  MeshHelper< FieldLocation::Elem >::LocalIndexType const & e )
715  {
716  return indexArray[std::get< 0 >( e )][std::get< 1 >( e )][std::get< 2 >( e )];
717  }
718 
719  template< typename ... SUBREGIONTYPES, typename REGIONS_CONTAINER >
720  static void
721  remove( MeshLevel & mesh,
722  string const & key,
723  REGIONS_CONTAINER const & regions )
724  {
725  mesh.getElemManager().template forElementSubRegions< SUBREGIONTYPES... >( regions,
726  [&]( localIndex const, ElementSubRegionBase & subRegion )
727  {
728  subRegion.deregisterWrapper( key );
729  } );
730  }
731 };
732 
733 } // namespace
734 
735 } // namespace geos
736 
737 #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:72
#define GEOS_ASSERT(EXP)
Assert a condition in debug builds.
Definition: Logger.hpp:177
#define GEOS_ERROR_IF(EXP, msg)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:142
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:85
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()