GEOS
StatisticsAggregatorBaseHelpers.hpp
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 
16 #include "mesh/MeshBody.hpp"
18 
19 #include "LvArray/src/math.hpp"
20 #include "common/DataTypes.hpp"
21 #include "common/format/Format.hpp"
23 #include "common/logger/Logger.hpp"
25 #include "dataRepository/Group.hpp"
27 #include "mesh/CellElementSubRegion.hpp"
29 #include "mesh/MeshLevel.hpp"
30 
31 namespace geos
32 {
33 
34 inline RegionStatisticsBase::RegionStatisticsBase( string const & targetName,
35  dataRepository::Group * const parent,
36  string_view setName,
37  bool const dataOutputEnabled ):
38  dataRepository::Group( targetName, parent ),
39  m_time( std::numeric_limits< double >::lowest() ),
40  m_setName( setName )
41 {
42  Group::setRestartFlags( dataOutputEnabled ?
45 
46  // TODO : registerWrappers to store results in HDF5 (but need repairing of 1D HDF5 outputs)
47 }
48 
49 template< typename Impl >
51  dataRepository::Group & meshBodies,
52  bool const dataOutputEnabled ):
53  m_ownerDataContext( ownerDataContext ),
54  m_dataOutputEnabled( dataOutputEnabled ),
55  m_meshBodies( meshBodies ),
56  m_isAnySetsIntersecting( false )
57 {}
58 
59 template< typename Impl >
60 std::set< string >
62  string_array const & regionNames )
63 {
64  std::set< string > foundSetNames;
65 
66  mesh.getElemManager().forElementRegions< CellElementRegion >( regionNames,
67  [&] ( localIndex &,
68  CellElementRegion const & region )
69  {
70  region.forElementSubRegions< CellElementSubRegion >( [&] ( CellElementSubRegion const & subRegion ) {
71  dataRepository::Group const & sets = subRegion.sets();
72  sets.forWrappers< SetType >( [&] ( dataRepository::Wrapper< SetType > const & set )
73  {
74  foundSetNames.emplace( set.getName() );
75  } );
76  } );
77  } );
78 
79  return foundSetNames;
80 }
81 
82 template< typename Impl >
83 void
85 {
86  solver.forDiscretizationOnMeshTargets( m_meshBodies, [&] ( string const & meshBodyName,
87  MeshLevel & mesh,
88  string_array const & regionNames )
89  {
90  // getting the container of all requesters statistics groups (can be already initialized)
91  dataRepository::Group * meshStatsGroup = mesh.getGroupPointer( string( ViewKeys::statisticsString()) );
92  if( meshStatsGroup == nullptr )
93  meshStatsGroup = &mesh.registerGroup( string( ViewKeys::statisticsString() ) );
94 
95  // registering the container of instance statistics groups (must be unique for this instance)
96  string const & ownerName = getOwnerName();
97  GEOS_ERROR_IF_NE_MSG( meshStatsGroup->hasGroup( ownerName ), false,
98  GEOS_FMT( "A statistics aggregator have already been requested for '{}'.",
99  ownerName ),
100  m_ownerDataContext );
101  meshStatsGroup->registerGroup( ownerName );
102 
103  MeshBody const & body = m_meshBodies.getGroup< MeshBody >( meshBodyName );
104 
106  std::set< string > foundSetNames = getMeshLevelPartialSetNames( mesh, regionNames );
107 
108  { // remembering the path of this discretization
109  DiscretizationSetPath const path {
110  /* .m_meshBody = */ body.getIndexInParent(),
111  /* .m_meshLevel = */ mesh.getIndexInParent(),
112  /* .m_setNames = */ string_array( foundSetNames.begin(), foundSetNames.end()),
113  /* .m_regionNames = */ regionNames,
114  /* .m_setsCompound = */ {},
115  };
116  m_discretizationsPaths.emplace_back( path );
117  }
118  } );
119 }
120 
121 template< typename Impl >
122 void
124  string_array const & setNames )
125 {
126  m_setNames.insert( setNames.begin(), setNames.end() );
127  if( m_setNames.empty())
128  m_setNames.emplace( "all" );
129 
130  bool regionFound = false;
131  bool subRegionFound = false;
132  std::set< string > confirmedSets;
133 
134  for( auto & path : m_discretizationsPaths )
135  {
136  MeshLevel & mesh = getMeshLevel( path );
137  ElementRegionManager & elemManager = mesh.getElemManager();
138  dataRepository::Group & statisticsGroup = getInstanceStatisticsGroup( mesh );
139  StatsGroupType & meshStats = registerStatsFunc( statisticsGroup, string( ViewKeys::setsStatisticsString() ),
140  "", m_dataOutputEnabled );
141  SetsCompound meshSetsCompounds;
142  bool isAnySetIntersects = false;
143 
144  // registering all stats Group in the dataRepository for each set
145  for( string const & setName : m_setNames )
146  {
147  StatsGroupType & meshSetStats = registerStatsFunc( meshStats, setName,
148  setName, m_dataOutputEnabled );
149 
150  for( size_t regionId = 0; regionId < path.m_regionNames.size(); ++regionId )
151  {
152  ElementRegionBase & region = elemManager.getRegion< ElementRegionBase >( path.m_regionNames[regionId] );
153  if( dynamic_cast< CellElementRegion * >(&region) != nullptr )
154  { // we only process cell regions
155  StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, region.getName(),
156  setName, m_dataOutputEnabled );
157  stdMap< string, SetType > & regionSetsCompounds = meshSetsCompounds.get_inserted( region.getName() );
158  regionFound = true;
159 
160  region.forElementSubRegions< CellElementSubRegion >( [&] ( CellElementSubRegion & subRegion )
161  {
162  registerStatsFunc( setRegionStats, subRegion.getName(),
163  setName, false );
164  subRegionFound = true;
165 
166  auto const * const subRegionSetWrapper = subRegion.sets().getWrapperPointer< SetType >( setName );
167  if( subRegionSetWrapper != nullptr )
168  {
169  if( !subRegionSetWrapper->reference().empty() )
170  confirmedSets.emplace( setName );
171 
172  // Insert the set elements ids in the mesh-level compound. If doubles are found, sets intersect.
173  SetViewType const & subRegionSet = subRegionSetWrapper->reference();
174  arrayView1d< integer const > const elemGhostRank = subRegion.ghostRank();
175  SetType & subRegionSetsCompound = regionSetsCompounds.get_inserted( subRegion.getName() );
176  for( localIndex setIter = 0; setIter < subRegionSet.size(); ++setIter )
177  {
178  localIndex elemId = subRegionSet[setIter];
179  if( elemGhostRank[elemId] < 0 )
180  {
181  if( !subRegionSetsCompound.insert( elemId ) )
182  isAnySetIntersects = true;
183  }
184  }
185  }
186  } );
187  }
188  }
189  }
190 
191  // if needed, registering stats Group in the dataRepository for the compound set
192  isAnySetIntersects = (bool)( MpiWrapper::max( (unsigned char)( isAnySetIntersects ) ) );
193  if( isAnySetIntersects )
194  {
195  string_view setName = ViewKeys::compoundSetNameString();
196  StatsGroupType & meshSetStats = registerStatsFunc( meshStats, string( setName ),
197  setName, false );
198  for( size_t regionId = 0; regionId < path.m_regionNames.size(); ++regionId )
199  {
200  ElementRegionBase & region = elemManager.getRegion< ElementRegionBase >( path.m_regionNames[regionId] );
201  if( dynamic_cast< CellElementRegion * >(&region) != nullptr )
202  { // we only process cell regions
203  StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, region.getName(),
204  setName, false );
205 
206  region.forElementSubRegions< CellElementSubRegion >( [&] ( CellElementSubRegion & subRegion )
207  {
208  registerStatsFunc( setRegionStats, subRegion.getName(),
209  setName, false );
210 
211  path.m_setsCompound
212  .get_inserted( region.getName())
213  .insert( meshSetsCompounds
214  .at( region.getName() )
215  .extract( subRegion.getName() ) );
216  } );
217  }
218  }
219  }
220  }
221 
222  m_regionStatsState.m_isEnabled = true;
223  m_regionStatsState.m_isDirty = true;
224 
225  GEOS_ERROR_IF( regionFound == 0 || subRegionFound == 0,
226  GEOS_FMT( "{}: Missing region for computing statistics:\n- {} regions,\n- {} sub-regions.",
227  getOwnerName(),
228  regionFound ? "found" : "no",
229  subRegionFound ? "found" : "no" ),
230  m_ownerDataContext );
231 
232  // at this point, m_setNames content is element sets user *requests*: they are the same on every ranks,
233  // but we don't know yet if any of these set is missing or empty (=> confirmedSets).
234  std::set< string > notFoundSets;
235  for( string const & requestedSetName : m_setNames )
236  {
237  if( MpiWrapper::max( confirmedSets.count( requestedSetName ) ) == 0 )
238  notFoundSets.emplace( requestedSetName );
239  }
240  if( MpiWrapper::commRank() == 0 )
241  GEOS_ERROR_IF( !notFoundSets.empty(),
242  GEOS_FMT( "During retrieval of statistics element sets, the following set(s) could not be "
243  "found or does not contain any element:\n- {}",
244  stringutilities::join( notFoundSets, "\n- " ) ),
245  m_ownerDataContext );
246 }
247 
248 template< typename Impl >
249 MeshLevel &
251 {
252  MeshBody & body = m_meshBodies.getGroup< MeshBody >( path.m_meshBody );
253  MeshLevel & mesh = body.getMeshLevel( path.m_meshLevel );
254  return mesh;
255 }
256 
257 template< typename Impl >
260 {
261  // considering everything is initialized, or else, crash gracefully
262  dataRepository::Group & meshStatsGroup = mesh.getGroup( string( ViewKeys::statisticsString() ) );
263  dataRepository::Group & instanceStatisticsGroup = meshStatsGroup.getGroup( getOwnerName() );
264  return instanceStatisticsGroup;
265 }
266 
267 template< typename Impl >
268 typename StatsAggregatorBase< Impl >::StatsGroupType &
270 getMeshLevelStatistics( MeshLevel & mesh ) const
271 {
272  // considering everything is initialized, or else, crash gracefully
273  dataRepository::Group & instanceStatisticsGroup = getInstanceStatisticsGroup( mesh );
274  return instanceStatisticsGroup.getGroup< StatsGroupType >( string( ViewKeys::setsStatisticsString()) );
275 }
276 
277 template< typename Impl >
278 typename StatsAggregatorBase< Impl >::StatsGroupType &
280  string_view requestedSetName ) const
281 {
282  // considering mesh-level stats structure is initialized, or else, crash gracefully
283  StatsGroupType & meshStats = getMeshLevelStatistics( mesh );
284  string const setName = string( requestedSetName.empty() ? "all" : requestedSetName );
285  StatsGroupType * const stats = meshStats.template getGroupPointer< StatsGroupType >( setName );
286  GEOS_THROW_IF( stats == nullptr,
287  GEOS_FMT( "Element set '{}' statistics data structure not found, has the set been requested?\nRequested element sets:\n- {}",
288  setName, stringutilities::join( m_setNames, "\n- " ) ),
289  InputError, m_ownerDataContext );
290  return *stats;
291 }
292 
293 template< typename Impl >
294 typename StatsAggregatorBase< Impl >::StatsGroupType &
296 {
297  // considering mesh-level stats structure is initialized, or else, crash gracefully
298  StatsGroupType & meshStats = getMeshLevelStatistics( mesh );
299  string const setName = string( ViewKeys::compoundSetNameString() );
300  StatsGroupType * const stats = meshStats.template getGroupPointer< StatsGroupType >( setName );
301  GEOS_THROW_IF( stats == nullptr,
302  GEOS_FMT( "Compound element set data structure not found ({}), is the aggregator initialized? Was the compound needed?\nRequested element sets:\n- {}",
303  setName, stringutilities::join( m_setNames, "\n- " ) ),
304  InputError, m_ownerDataContext );
305  return *stats;
306 }
307 
308 template< typename Impl >
309 bool
310 StatsAggregatorBase< Impl >::isCompoundSetStatistics( StatsGroupType const & setStats ) const
311 {
312  return setStats.getSetName() == ViewKeys::compoundSetNameString();
313 }
314 
315 template< typename Impl >
316 typename StatsAggregatorBase< Impl >::StatsGroupType &
318  string_view regionName,
319  string_view setName ) const
320 {
321  StatsGroupType & setStats = getSetStatistics( mesh, setName );
322  StatsGroupType * const stats = setStats.template getGroupPointer< StatsGroupType >( string( regionName ) );
323  GEOS_THROW_IF( stats == nullptr,
324  GEOS_FMT( "Region '{}' not found to get region statistics, is it a target of the reservoir solver?\n"
325  "Available target regions:\n- {}",
326  regionName, stringutilities::join( setStats.getSubGroupsNames(), "\n- " ) ),
327  InputError, m_ownerDataContext );
328  return *stats;
329 }
330 
331 template< typename Impl >
332 void
334 {
335  for( auto const & path : m_discretizationsPaths )
336  {
337  MeshLevel & mesh = getMeshLevel( path );
338  StatsGroupType & meshLevelStats = getMeshLevelStatistics( mesh );
339 
340  func( mesh, meshLevelStats );
341  }
342 }
343 
344 template< typename Impl >
345 void
347  StatsGroupType & meshLevelStats,
348  bool enableCompoundSet,
349  RegionStatsFunc< MeshLevelSet > const & func ) const
350 {
351  meshLevelStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & setStats )
352  {
353  if( enableCompoundSet || setStats.getSetName() != ViewKeys::compoundSetNameString() )
354  {
355  MeshLevelSet meshSet {
356  /* .mesh = */ mesh,
357  /* .setName = */ setStats.getTargetName(),
358  };
359 
360  func( meshSet, setStats );
361  }
362  } );
363 }
364 
365 template< typename Impl >
366 void
368  StatsGroupType & setStats,
369  RegionStatsFunc< CellElementRegion & > const & func ) const
370 {
371  ElementRegionManager & elemManager = meshSet.mesh.getElemManager();
372  setStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & setRegionStats )
373  {
374  string_view regionName = setRegionStats.getTargetName();
375  ElementRegionBase & region = elemManager.getRegion< ElementRegionBase >( string( regionName ) );
376  CellElementRegion * cellRegion = dynamic_cast< CellElementRegion * >(&region); // we only process cell regions
377 
378  if( cellRegion != nullptr )
379  func( *cellRegion, setRegionStats );
380  } );
381 }
382 
383 template< typename Impl >
384 void
386  StatsGroupType & setRegionStats,
387  RegionStatsFunc< CellElementSubRegion & > const & func ) const
388 {
389  setRegionStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & subRegionStatistics )
390  {
391  string_view subRegionName = subRegionStatistics.getTargetName();
392  CellElementSubRegion & subRegion = setRegion.getSubRegion< CellElementSubRegion >( string( subRegionName ) );
393 
394  func( subRegion, subRegionStatistics );
395  } );
396 }
397 
398 template< typename Impl >
399 bool
400 StatsAggregatorBase< Impl >::isComputed( real64 const timeRequest, StatsGroupType const & stats )
401 {
402  real64 const timePrecisionScale = LvArray::math::max( LvArray::math::abs( timeRequest ),
403  LvArray::math::abs( stats.m_time ) );
404  static constexpr real64 timeRelTol = 1.0e-12;
405 
406  return
407  !m_regionStatsState.m_isDirty &&
408  LvArray::math::abs( timeRequest - stats.m_time ) < timeRelTol * timePrecisionScale;
409 }
410 
411 template< typename Impl >
412 void
414 {
415  m_regionStatsState.m_isDirty = true;
416 }
417 
418 template< typename Impl >
419 bool
421 {
423 
424  m_warnings.clear();
425 
426  for( auto const & path : m_discretizationsPaths )
427  {
428  MeshLevel & mesh = getMeshLevel( path );
429  StatsGroupType & meshLevelStats = getMeshLevelStatistics( mesh );
430  bool const isSetsCompoundEnabled = !path.m_setsCompound.empty();
431 
432  // computation of sub region stats for each selected set
433  initStats( meshLevelStats, timeRequest );
434  forRegionStatistics( mesh, meshLevelStats, true,
435  [&, timeRequest] ( MeshLevelSet meshSet, StatsGroupType & setStats )
436  {
437  initStats( setStats, timeRequest );
438  forRegionStatistics( meshSet, setStats,
439  [&, timeRequest] ( CellElementRegion & region, StatsGroupType & regionStats )
440  {
441  initStats( regionStats, timeRequest );
442  forRegionStatistics( region, regionStats,
443  [&, timeRequest] ( CellElementSubRegion & subRegion, StatsGroupType & subRegionStats )
444  {
445  initStats( subRegionStats, timeRequest );
446 
447  SetType const & targetSet = meshSet.setName == ViewKeys::compoundSetNameString() ?
448  path.m_setsCompound.at( region.getName() ).at( subRegion.getName() ) :
449  subRegion.sets().getReference< SetType >( string( meshSet.setName ) );
450  computeSubRegionRankStats( subRegion, subRegionStats, targetSet );
451  } );
452  } );
453  } );
454 
455  // aggregation of computations from the sub regions
456  forRegionStatistics( mesh, meshLevelStats, true,
457  [&] ( MeshLevelSet meshSet, StatsGroupType & setStats )
458  {
459  forRegionStatistics( meshSet, setStats,
460  [&] ( CellElementRegion & region, StatsGroupType & regionStats )
461  {
462  forRegionStatistics( region, regionStats,
463  [&] ( CellElementSubRegion &, StatsGroupType & subRegionStats )
464  {
465  aggregateStats( regionStats, subRegionStats );
466  // sub-region stats finalization is disabled, it does not seem useful
467  // mpiAggregateStats( subRegionStats );
468  // postAggregateStats( subRegionStats );
469  } );
470 
471  aggregateStats( setStats, regionStats );
472 
473  mpiAggregateStats( regionStats );
474  postAggregateStats( regionStats );
475  } );
476 
477  // if there is no compound set, we can simply aggregate each set statistics to the mesh-level statistics.
478  // if there is one, we will only take into account the statistics of the compound set.
479  if( !isSetsCompoundEnabled || isCompoundSetStatistics( setStats ) )
480  {
481  aggregateStats( meshLevelStats, setStats );
482  }
483 
484  mpiAggregateStats( setStats );
485  postAggregateStats( setStats );
486  } );
487 
488  mpiAggregateStats( meshLevelStats );
489  postAggregateStats( meshLevelStats );
490  }
491 
492  m_regionStatsState.m_isDirty = false;
493 
494  return true;
495 }
496 
497 } /* namespace geos */
#define GEOS_ERROR_IF(COND,...)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:211
#define GEOS_ERROR_IF_NE_MSG(lhs, rhs,...)
Raise a hard error if two values are not equal.
Definition: Logger.hpp:442
#define GEOS_THROW_IF(COND, MSG,...)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:289
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
The ElementRegionBase is the base class to manage the data stored at the element level.
void forElementSubRegions(LAMBDA &&lambda) const
Apply a lambda to all subregions.
SUBREGIONTYPE const & getSubRegion(KEY_TYPE const &key) const
Get a reference to a subregion.
The ElementRegionManager class provides an interface to ObjectManagerBase in order to manage ElementR...
void forElementRegions(LAMBDA &&lambda)
This function is used to launch kernel function over all the element regions with region type = Eleme...
T const & getRegion(KEY_TYPE const &key) const
Get a element region.
The class is used to manage mesh body.
Definition: MeshBody.hpp:36
MeshLevel & getMeshLevel(T const &level) const
Get a reference to a MeshLevel.
Definition: MeshBody.hpp:100
Class facilitating the representation of a multi-level discretization of a MeshBody.
Definition: MeshLevel.hpp:42
ElementRegionManager const & getElemManager() const
Get the element region manager.
Definition: MeshLevel.hpp:207
Group & sets()
Get the group holding the object sets.
RegionStatisticsBase(string const &targetName, dataRepository::Group *const parent, string_view setName, bool dataOutputEnabled)
Construct a new Region Statistics Base object.
Reponsible of computing physical statistics over the grid, registering the result in the data reposit...
dataRepository::Group & getInstanceStatisticsGroup(MeshLevel &mesh) const
Get the Instance Statistics Group for the given mesh-level.
void initStatisticsAggregation(SolverType &solver)
Enable the computation of any statistics, explores the data structure to collect them.
StatsGroupType & getMeshLevelStatistics(MeshLevel &mesh) const
StatsAggregatorBase(dataRepository::DataContext const &ownerDataContext, dataRepository::Group &meshBodies, bool statsOutputEnabled)
Construct a new Stats Aggregator object.
void enableRegionStatisticsAggregation(RegionStatsRegisterFunc &&registerStatsFunc, string_array const &setNames)
Enable the computation of region statistics, initialize data structure to collect them....
StatsGroupType & getRegionStatistics(MeshLevel &mesh, string_view regionName, string_view setName="") const
std::function< void(OwnerType, StatsGroupType &) > RegionStatsFunc
Standard function signature for any functor that applies on statistics group instances (StatsGroupTyp...
MeshLevel & getMeshLevel(DiscretizationSetPath const &path) const
StatsGroupType & getSetStatistics(MeshLevel &mesh, string_view setName="") const
static std::set< string > getMeshLevelPartialSetNames(MeshLevel const &mesh, string_array const &regionNames)
TODO.
StatsGroupType & getCompoundSetStatistics(MeshLevel &mesh) const
bool isCompoundSetStatistics(StatsGroupType const &stats) const
std::function< StatsGroupType &(dataRepository::Group &, string const &, string_view, bool) > RegionStatsRegisterFunc
A functor that can be used to register a statistics Group instance. Parameters:
void forRegionStatistics(RegionStatsFunc< MeshLevel & > const &functor) const
Execute the given functor on each mesh-level (discretization) available for this instance.
T * getGroupPointer(KEY const &key)
Return a pointer to a sub-group of the current Group.
Definition: Group.hpp:299
localIndex getIndexInParent() const
Get the group's index within its parent group.
Definition: Group.hpp:1391
T & registerGroup(string const &name, std::unique_ptr< T > newObject)
Register a new Group as a sub-group of current Group.
Definition: Group.hpp:200
void setRestartFlags(RestartFlags flags)
Set flags that control restart output of this group.
Definition: Group.hpp:1428
string const & getName() const
Get group name.
Definition: Group.hpp:1329
GEOS_DECLTYPE_AUTO_RETURN getReference(LOOKUP_TYPE const &lookup) const
Look up a wrapper and get reference to wrapped object.
Definition: Group.hpp:1273
T & getGroup(KEY const &key)
Return a reference to a sub-group of the current Group.
Definition: Group.hpp:318
bool hasGroup(string const &name) const
Check whether a sub-group exists.
Definition: Group.hpp:405
void forWrappers(LAMBDA &&lambda)
Apply the given functor to wrappers.
Definition: Group.hpp:637
@ WRITE_AND_READ
Write and read from restart.
@ NO_WRITE
Do not write into restart.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:179
stdVector< string > string_array
A 1-dimensional array of geos::string types.
Definition: DataTypes.hpp:361
std::string string
String type.
Definition: DataTypes.hpp:90
std::set< T > set
A set of local indices.
Definition: DataTypes.hpp:262
double real64
64-bit floating point type.
Definition: DataTypes.hpp:98
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:84
internal::StdMapWrapper< std::map< Key, T, Compare, Allocator >, USE_STD_CONTAINER_BOUNDS_CHECKING > stdMap
std::string_view string_view
String type.
Definition: DataTypes.hpp:93
Exception class used to report errors in user input.
static T max(T const &value, MPI_Comm comm=MPI_COMM_GEOS)
Convenience function for a MPI_Allreduce using a MPI_MAX operation.
localIndex m_meshLevel
The id of the mesh level in the mesh body.
localIndex m_meshBody
The id of the mesh body in the "meshBodies" Group.
Allow to reference a set in a given MeshLevel structure.