19 #include "LvArray/src/math.hpp"
21 #include "common/format/Format.hpp"
27 #include "mesh/CellElementSubRegion.hpp"
29 #include "mesh/MeshLevel.hpp"
37 bool const dataOutputEnabled ):
38 dataRepository::
Group( targetName, parent ),
39 m_time( std::numeric_limits< double >::lowest() ),
49 template<
typename Impl >
52 bool const dataOutputEnabled ):
53 m_ownerDataContext( ownerDataContext ),
54 m_dataOutputEnabled( dataOutputEnabled ),
55 m_meshBodies( meshBodies ),
56 m_isAnySetsIntersecting( false )
59 template<
typename Impl >
64 std::set< string > foundSetNames;
74 foundSetNames.emplace(
set.getName() );
82 template<
typename Impl >
86 solver.forDiscretizationOnMeshTargets( m_meshBodies, [&] (
string const & meshBodyName,
92 if( meshStatsGroup ==
nullptr )
93 meshStatsGroup = &mesh.
registerGroup(
string( ViewKeys::statisticsString() ) );
96 string const & ownerName = getOwnerName();
98 GEOS_FMT(
"A statistics aggregator have already been requested for '{}'.",
100 m_ownerDataContext );
106 std::set< string > foundSetNames = getMeshLevelPartialSetNames( mesh, regionNames );
112 string_array( foundSetNames.begin(), foundSetNames.end()),
116 m_discretizationsPaths.emplace_back( path );
121 template<
typename Impl >
126 m_setNames.insert( setNames.begin(), setNames.end() );
127 if( m_setNames.empty())
128 m_setNames.emplace(
"all" );
130 bool regionFound =
false;
131 bool subRegionFound =
false;
132 std::set< string > confirmedSets;
134 for(
auto & path : m_discretizationsPaths )
139 StatsGroupType & meshStats = registerStatsFunc( statisticsGroup,
string( ViewKeys::setsStatisticsString() ),
140 "", m_dataOutputEnabled );
141 SetsCompound meshSetsCompounds;
142 bool isAnySetIntersects =
false;
145 for(
string const & setName : m_setNames )
147 StatsGroupType & meshSetStats = registerStatsFunc( meshStats, setName,
148 setName, m_dataOutputEnabled );
150 for(
size_t regionId = 0; regionId < path.m_regionNames.size(); ++regionId )
155 StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, region.
getName(),
156 setName, m_dataOutputEnabled );
162 registerStatsFunc( setRegionStats, subRegion.getName(),
164 subRegionFound =
true;
166 auto const *
const subRegionSetWrapper = subRegion.sets().getWrapperPointer< SetType >( setName );
167 if( subRegionSetWrapper !=
nullptr )
169 if( !subRegionSetWrapper->reference().empty() )
170 confirmedSets.emplace( setName );
173 SetViewType
const & subRegionSet = subRegionSetWrapper->reference();
175 SetType & subRegionSetsCompound = regionSetsCompounds.get_inserted( subRegion.getName() );
176 for(
localIndex setIter = 0; setIter < subRegionSet.size(); ++setIter )
179 if( elemGhostRank[elemId] < 0 )
181 if( !subRegionSetsCompound.insert( elemId ) )
182 isAnySetIntersects =
true;
192 isAnySetIntersects = (bool)(
MpiWrapper::max( (
unsigned char)( isAnySetIntersects ) ) );
193 if( isAnySetIntersects )
195 string_view setName = ViewKeys::compoundSetNameString();
196 StatsGroupType & meshSetStats = registerStatsFunc( meshStats,
string( setName ),
198 for(
size_t regionId = 0; regionId < path.m_regionNames.size(); ++regionId )
203 StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, region.
getName(),
208 registerStatsFunc( setRegionStats, subRegion.getName(),
212 .get_inserted( region.
getName())
213 .insert( meshSetsCompounds
215 .extract( subRegion.getName() ) );
222 m_regionStatsState.m_isEnabled =
true;
223 m_regionStatsState.m_isDirty =
true;
226 GEOS_FMT(
"{}: Missing region for computing statistics:\n- {} regions,\n- {} sub-regions.",
228 regionFound ?
"found" :
"no",
229 subRegionFound ?
"found" :
"no" ),
230 m_ownerDataContext );
234 std::set< string > notFoundSets;
235 for(
string const & requestedSetName : m_setNames )
238 notFoundSets.emplace( requestedSetName );
240 if( MpiWrapper::commRank() == 0 )
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 );
248 template<
typename Impl >
257 template<
typename Impl >
264 return instanceStatisticsGroup;
267 template<
typename Impl >
268 typename StatsAggregatorBase< Impl >::StatsGroupType &
274 return instanceStatisticsGroup.
getGroup< StatsGroupType >(
string( ViewKeys::setsStatisticsString()) );
277 template<
typename Impl >
278 typename StatsAggregatorBase< Impl >::StatsGroupType &
283 StatsGroupType & meshStats = getMeshLevelStatistics( mesh );
284 string const setName =
string( requestedSetName.empty() ?
"all" : requestedSetName );
285 StatsGroupType *
const stats = meshStats.template getGroupPointer< StatsGroupType >( setName );
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- " ) ),
293 template<
typename Impl >
294 typename StatsAggregatorBase< Impl >::StatsGroupType &
298 StatsGroupType & meshStats = getMeshLevelStatistics( mesh );
299 string const setName =
string( ViewKeys::compoundSetNameString() );
300 StatsGroupType *
const stats = meshStats.template getGroupPointer< StatsGroupType >( setName );
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- " ) ),
308 template<
typename Impl >
312 return setStats.getSetName() == ViewKeys::compoundSetNameString();
315 template<
typename Impl >
316 typename StatsAggregatorBase< Impl >::StatsGroupType &
321 StatsGroupType & setStats = getSetStatistics( mesh, setName );
322 StatsGroupType *
const stats = setStats.template getGroupPointer< StatsGroupType >(
string( regionName ) );
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- " ) ),
331 template<
typename Impl >
335 for(
auto const & path : m_discretizationsPaths )
338 StatsGroupType & meshLevelStats = getMeshLevelStatistics( mesh );
340 func( mesh, meshLevelStats );
344 template<
typename Impl >
347 StatsGroupType & meshLevelStats,
348 bool enableCompoundSet,
351 meshLevelStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & setStats )
353 if( enableCompoundSet || setStats.getSetName() != ViewKeys::compoundSetNameString() )
355 MeshLevelSet meshSet {
357 setStats.getTargetName(),
360 func( meshSet, setStats );
365 template<
typename Impl >
368 StatsGroupType & setStats,
372 setStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & setRegionStats )
374 string_view regionName = setRegionStats.getTargetName();
378 if( cellRegion !=
nullptr )
379 func( *cellRegion, setRegionStats );
383 template<
typename Impl >
386 StatsGroupType & setRegionStats,
389 setRegionStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & subRegionStatistics )
391 string_view subRegionName = subRegionStatistics.getTargetName();
394 func( subRegion, subRegionStatistics );
398 template<
typename Impl >
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;
407 !m_regionStatsState.m_isDirty &&
408 LvArray::math::abs( timeRequest - stats.m_time ) < timeRelTol * timePrecisionScale;
411 template<
typename Impl >
415 m_regionStatsState.m_isDirty =
true;
418 template<
typename Impl >
426 for(
auto const & path : m_discretizationsPaths )
429 StatsGroupType & meshLevelStats = getMeshLevelStatistics( mesh );
430 bool const isSetsCompoundEnabled = !path.m_setsCompound.empty();
433 initStats( meshLevelStats, timeRequest );
434 forRegionStatistics( mesh, meshLevelStats,
true,
435 [&, timeRequest] (
MeshLevelSet meshSet, StatsGroupType & setStats )
437 initStats( setStats, timeRequest );
438 forRegionStatistics( meshSet, setStats,
441 initStats( regionStats, timeRequest );
442 forRegionStatistics( region, regionStats,
445 initStats( subRegionStats, timeRequest );
447 SetType
const & targetSet = meshSet.setName == ViewKeys::compoundSetNameString() ?
448 path.m_setsCompound.at( region.
getName() ).at( subRegion.
getName() ) :
450 computeSubRegionRankStats( subRegion, subRegionStats, targetSet );
456 forRegionStatistics( mesh, meshLevelStats,
true,
459 forRegionStatistics( meshSet, setStats,
462 forRegionStatistics( region, regionStats,
465 aggregateStats( regionStats, subRegionStats );
471 aggregateStats( setStats, regionStats );
473 mpiAggregateStats( regionStats );
474 postAggregateStats( regionStats );
479 if( !isSetsCompoundEnabled || isCompoundSetStatistics( setStats ) )
481 aggregateStats( meshLevelStats, setStats );
484 mpiAggregateStats( setStats );
485 postAggregateStats( setStats );
488 mpiAggregateStats( meshLevelStats );
489 postAggregateStats( meshLevelStats );
492 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.