19 #include "LvArray/src/math.hpp"
21 #include "common/format/Format.hpp"
27 #include "mesh/ElementRegionBase.hpp"
30 #include "mesh/MeshLevel.hpp"
43 inline bool isStatisticsRegion( ElementRegionBase
const & region )
46 return dynamic_cast< CellElementRegion
const *
>( ®ion ) !=
nullptr ||
47 dynamic_cast< SurfaceElementRegion
const *
>( ®ion ) !=
nullptr;
55 bool const dataOutputEnabled ):
56 dataRepository::
Group( targetName, parent ),
57 m_time( std::numeric_limits< double >::lowest() ),
67 template<
typename Impl >
70 bool const dataOutputEnabled ):
71 m_ownerDataContext( ownerDataContext ),
72 m_dataOutputEnabled( dataOutputEnabled ),
73 m_meshBodies( meshBodies ),
74 m_isAnySetsIntersecting( false )
77 template<
typename Impl >
82 std::set< string > foundSetNames;
88 if( !internal::isStatisticsRegion( region ) )
95 foundSetNames.emplace(
set.getName() );
100 return foundSetNames;
103 template<
typename Impl >
107 solver.forDiscretizationOnMeshTargets( m_meshBodies, [&] (
string const & meshBodyName,
113 if( meshStatsGroup ==
nullptr )
114 meshStatsGroup = &mesh.
registerGroup(
string( ViewKeys::statisticsString() ) );
117 string const & ownerName = getOwnerName();
119 GEOS_FMT(
"A statistics aggregator have already been requested for '{}'.",
121 m_ownerDataContext );
127 std::set< string > foundSetNames = getMeshLevelPartialSetNames( mesh, regionNames );
133 string_array( foundSetNames.begin(), foundSetNames.end()),
137 m_discretizationsPaths.emplace_back( path );
142 template<
typename Impl >
147 m_setNames.insert( setNames.begin(), setNames.end() );
148 if( m_setNames.empty())
149 m_setNames.emplace(
"all" );
151 bool regionFound =
false;
152 bool subRegionFound =
false;
153 std::set< string > confirmedSets;
155 for(
auto & path : m_discretizationsPaths )
160 StatsGroupType & meshStats = registerStatsFunc( statisticsGroup,
string( ViewKeys::setsStatisticsString() ),
161 "", m_dataOutputEnabled );
162 SetsCompound meshSetsCompounds;
163 bool isAnySetIntersects =
false;
166 for(
string const & setName : m_setNames )
168 StatsGroupType & meshSetStats = registerStatsFunc( meshStats, setName,
169 setName, m_dataOutputEnabled );
171 for(
size_t regionId = 0; regionId < path.m_regionNames.size(); ++regionId )
174 if( internal::isStatisticsRegion( region ) )
176 StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, region.
getName(),
177 setName, m_dataOutputEnabled );
183 registerStatsFunc( setRegionStats, subRegion.getName(),
185 subRegionFound =
true;
187 auto const *
const subRegionSetWrapper = subRegion.sets().getWrapperPointer< SetType >( setName );
188 if( subRegionSetWrapper !=
nullptr )
190 if( !subRegionSetWrapper->reference().empty() )
191 confirmedSets.emplace( setName );
194 SetViewType
const & subRegionSet = subRegionSetWrapper->reference();
196 SetType & subRegionSetsCompound = regionSetsCompounds.get_inserted( subRegion.getName() );
197 for(
localIndex setIter = 0; setIter < subRegionSet.size(); ++setIter )
200 if( elemGhostRank[elemId] < 0 )
202 if( !subRegionSetsCompound.insert( elemId ) )
203 isAnySetIntersects =
true;
213 isAnySetIntersects = (bool)(
MpiWrapper::max( (
unsigned char)( isAnySetIntersects ) ) );
214 if( isAnySetIntersects )
216 string_view setName = ViewKeys::compoundSetNameString();
217 StatsGroupType & meshSetStats = registerStatsFunc( meshStats,
string( setName ),
219 for(
size_t regionId = 0; regionId < path.m_regionNames.size(); ++regionId )
222 if( internal::isStatisticsRegion( region ) )
224 StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, region.
getName(),
229 registerStatsFunc( setRegionStats, subRegion.getName(),
233 .get_inserted( region.
getName())
234 .insert( meshSetsCompounds
236 .extract( subRegion.getName() ) );
243 m_regionStatsState.m_isEnabled =
true;
244 m_regionStatsState.m_isDirty =
true;
247 GEOS_FMT(
"{}: Missing region for computing statistics:\n- {} regions,\n- {} sub-regions.",
249 regionFound ?
"found" :
"no",
250 subRegionFound ?
"found" :
"no" ),
251 m_ownerDataContext );
255 std::set< string > notFoundSets;
256 for(
string const & requestedSetName : m_setNames )
259 notFoundSets.emplace( requestedSetName );
261 if( MpiWrapper::commRank() == 0 )
263 GEOS_FMT(
"During retrieval of statistics element sets, the following set(s) could not be "
264 "found or does not contain any element:\n- {}",
265 stringutilities::join( notFoundSets,
"\n- " ) ),
266 m_ownerDataContext );
269 template<
typename Impl >
278 template<
typename Impl >
285 return instanceStatisticsGroup;
288 template<
typename Impl >
289 typename StatsAggregatorBase< Impl >::StatsGroupType &
295 return instanceStatisticsGroup.
getGroup< StatsGroupType >(
string( ViewKeys::setsStatisticsString()) );
298 template<
typename Impl >
299 typename StatsAggregatorBase< Impl >::StatsGroupType &
304 StatsGroupType & meshStats = getMeshLevelStatistics( mesh );
305 string const setName =
string( requestedSetName.empty() ?
"all" : requestedSetName );
306 StatsGroupType *
const stats = meshStats.template getGroupPointer< StatsGroupType >( setName );
308 GEOS_FMT(
"Element set '{}' statistics data structure not found, has the set been requested?\nRequested element sets:\n- {}",
309 setName, stringutilities::join( m_setNames,
"\n- " ) ),
314 template<
typename Impl >
315 typename StatsAggregatorBase< Impl >::StatsGroupType &
319 StatsGroupType & meshStats = getMeshLevelStatistics( mesh );
320 string const setName =
string( ViewKeys::compoundSetNameString() );
321 StatsGroupType *
const stats = meshStats.template getGroupPointer< StatsGroupType >( setName );
323 GEOS_FMT(
"Compound element set data structure not found ({}), is the aggregator initialized? Was the compound needed?\nRequested element sets:\n- {}",
324 setName, stringutilities::join( m_setNames,
"\n- " ) ),
329 template<
typename Impl >
333 return setStats.getSetName() == ViewKeys::compoundSetNameString();
336 template<
typename Impl >
337 typename StatsAggregatorBase< Impl >::StatsGroupType &
342 StatsGroupType & setStats = getSetStatistics( mesh, setName );
343 StatsGroupType *
const stats = setStats.template getGroupPointer< StatsGroupType >(
string( regionName ) );
345 GEOS_FMT(
"Region '{}' not found to get region statistics, is it a target of the reservoir solver?\n"
346 "Available target regions:\n- {}",
347 regionName, stringutilities::join( setStats.getSubGroupsNames(),
"\n- " ) ),
352 template<
typename Impl >
356 for(
auto const & path : m_discretizationsPaths )
359 StatsGroupType & meshLevelStats = getMeshLevelStatistics( mesh );
361 func( mesh, meshLevelStats );
365 template<
typename Impl >
368 StatsGroupType & meshLevelStats,
369 bool enableCompoundSet,
372 meshLevelStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & setStats )
374 if( enableCompoundSet || setStats.getSetName() != ViewKeys::compoundSetNameString() )
376 MeshLevelSet meshSet {
378 setStats.getTargetName(),
381 func( meshSet, setStats );
386 template<
typename Impl >
389 StatsGroupType & setStats,
393 setStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & setRegionStats )
395 string_view regionName = setRegionStats.getTargetName();
397 if( internal::isStatisticsRegion( region ) )
398 func( region, setRegionStats );
402 template<
typename Impl >
405 StatsGroupType & setRegionStats,
408 setRegionStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & subRegionStatistics )
410 string_view subRegionName = subRegionStatistics.getTargetName();
413 func( subRegion, subRegionStatistics );
417 template<
typename Impl >
421 real64 const timePrecisionScale = LvArray::math::max( LvArray::math::abs( timeRequest ),
422 LvArray::math::abs( stats.m_time ) );
423 static constexpr
real64 timeRelTol = 1.0e-12;
426 !m_regionStatsState.m_isDirty &&
427 LvArray::math::abs( timeRequest - stats.m_time ) < timeRelTol * timePrecisionScale;
430 template<
typename Impl >
434 m_regionStatsState.m_isDirty =
true;
437 template<
typename Impl >
445 for(
auto const & path : m_discretizationsPaths )
448 StatsGroupType & meshLevelStats = getMeshLevelStatistics( mesh );
449 bool const isSetsCompoundEnabled = !path.m_setsCompound.empty();
452 initStats( meshLevelStats, timeRequest );
453 forRegionStatistics( mesh, meshLevelStats,
true,
454 [&, timeRequest] (
MeshLevelSet meshSet, StatsGroupType & setStats )
456 initStats( setStats, timeRequest );
457 forRegionStatistics( meshSet, setStats,
460 initStats( regionStats, timeRequest );
461 forRegionStatistics( region, regionStats,
464 initStats( subRegionStats, timeRequest );
466 SetType
const & targetSet = meshSet.setName == ViewKeys::compoundSetNameString() ?
467 path.m_setsCompound.at( region.
getName() ).at( subRegion.
getName() ) :
469 computeSubRegionRankStats( subRegion, subRegionStats, targetSet );
475 forRegionStatistics( mesh, meshLevelStats,
true,
478 forRegionStatistics( meshSet, setStats,
481 forRegionStatistics( region, regionStats,
484 aggregateStats( regionStats, subRegionStats );
490 aggregateStats( setStats, regionStats );
492 mpiAggregateStats( regionStats );
493 postAggregateStats( regionStats );
498 if( !isSetsCompoundEnabled || isCompoundSetStatistics( setStats ) )
500 aggregateStats( meshLevelStats, setStats );
503 mpiAggregateStats( setStats );
504 postAggregateStats( setStats );
507 mpiAggregateStats( meshLevelStats );
508 postAggregateStats( meshLevelStats );
511 m_regionStatsState.m_isDirty =
false;
#define GEOS_ERROR_IF(COND,...)
Conditionally raise a hard error and terminate the program.
#define GEOS_ERROR_IF_NE_MSG(lhs, rhs,...)
Raise a hard error if two values are not equal.
#define GEOS_THROW_IF(COND, MSG,...)
Conditionally raise a hard error and terminate the program.
#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.
MeshLevel & getMeshLevel(T const &level) const
Get a reference to a MeshLevel.
Class facilitating the representation of a multi-level discretization of a MeshBody.
ElementRegionManager const & getElemManager() const
Get the element region manager.
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 &®isterStatsFunc, 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 ®ionNames)
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.
localIndex getIndexInParent() const
Get the group's index within its parent group.
T & registerGroup(string const &name, std::unique_ptr< T > newObject)
Register a new Group as a sub-group of current Group.
void setRestartFlags(RestartFlags flags)
Set flags that control restart output of this group.
string const & getName() const
Get group name.
GEOS_DECLTYPE_AUTO_RETURN getReference(LOOKUP_TYPE const &lookup) const
Look up a wrapper and get reference to wrapped object.
T & getGroup(KEY const &key)
Return a reference to a sub-group of the current Group.
bool hasGroup(string const &name) const
Check whether a sub-group exists.
void forWrappers(LAMBDA &&lambda)
Apply the given functor to wrappers.
@ WRITE_AND_READ
Write and read from restart.
@ NO_WRITE
Do not write into restart.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
stdVector< string > string_array
A 1-dimensional array of geos::string types.
std::string string
String type.
std::set< T > set
A set of local indices.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
internal::StdMapWrapper< std::map< Key, T, Compare, Allocator >, USE_STD_CONTAINER_BOUNDS_CHECKING > stdMap
std::string_view string_view
String type.
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.