From 222631901c59138356bff7fb62c77a321f94c47b Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Thu, 12 Mar 2026 17:10:13 +0100 Subject: [PATCH 01/25] =?UTF-8?q?=F0=9F=9A=A7=20added=20user=20inputs=20to?= =?UTF-8?q?=20define=20the=20general=20concept?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CompositionalMultiphaseStatisticsTask.cpp | 7 +++++++ .../CompositionalMultiphaseStatisticsTask.hpp | 5 +++++ .../fluidFlow/SinglePhaseStatisticsTask.cpp | 7 +++++++ .../fluidFlow/SinglePhaseStatisticsTask.hpp | 12 ++++++++++++ 4 files changed, 31 insertions(+) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp index 448de457f77..122a5144886 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp @@ -39,6 +39,13 @@ StatsTask::StatsTask( string const & name, Group * const parent ): m_computeCFLNumbers( 0 ), m_computeRegionStatistics( 1 ) { + registerWrapper( viewKeyStruct::setNamesString(), &m_setNames ). + setApplyDefaultValue( "{}" ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Optional targeted mesh element set(s) for which the statistics will be restricted." + "If empty, all mesh regions will be processed." + "Be aware that only the regions that are computed by the solver will be taken into account." ); + registerWrapper( viewKeyStruct::computeCFLNumbersString(), &m_computeCFLNumbers ). setApplyDefaultValue( 0 ). setInputFlag( InputFlags::OPTIONAL ). diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.hpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.hpp index 6f29bbe844f..5e019236245 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.hpp @@ -84,6 +84,8 @@ class StatsTask : public FieldStatisticsBase< CompositionalMultiphaseBase > */ struct viewKeyStruct { + /// String for optionnal targeted element set(s) + constexpr static char const * setNamesString() { return "setNames"; } /// String for the flag deciding the computation of the CFL numbers constexpr static char const * computeCFLNumbersString() { return "computeCFLNumbers"; } /// String for the flag deciding the computation of the region statistics @@ -121,6 +123,9 @@ class StatsTask : public FieldStatisticsBase< CompositionalMultiphaseBase > // mesh statistics aggregator std::unique_ptr< StatsAggregator > m_aggregator; + /// Optionnal targeted element set(s) + string_array m_setNames; + /// Flag to decide whether CFL numbers are computed or not integer m_computeCFLNumbers; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp index 69fdfc9a5c7..f4523fa2440 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp @@ -33,6 +33,13 @@ namespace singlePhaseStatistics StatsTask::StatsTask( const string & name, Group * const parent ): Base( name, parent ) { + registerWrapper( viewKeyStruct::setNamesString(), &m_setNames ). + setApplyDefaultValue( "{}" ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Optional targeted mesh element set(s) for which the statistics will be restricted." + "If empty, all mesh regions will be processed." + "Be aware that only the regions that are computed by the solver will be taken into account." ); + addLogLevel< logInfo::Statistics >(); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.hpp index 2d83a6b5a3f..498333248aa 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.hpp @@ -76,6 +76,15 @@ class StatsTask : public FieldStatisticsBase< SinglePhaseBase > using Base = FieldStatisticsBase< SinglePhaseBase >; + /** + * @struct viewKeyStruct holds char strings and viewKeys for fast lookup + */ + struct viewKeyStruct + { + /// String for optionnal targeted element set(s) + constexpr static char const * setNamesString() { return "setNames"; } + }; + void postInputInitialization() override; void registerDataOnMesh( Group & meshBodies ) override; @@ -103,6 +112,9 @@ class StatsTask : public FieldStatisticsBase< SinglePhaseBase > // mesh statistics aggregator std::unique_ptr< StatsAggregator > m_aggregator; + /// Optionnal targeted element set(s) + string_array m_setNames; + }; } /* namespace singlePhaseStatistics */ From d362afaa881cde70aa26ef7cd152c44fa5d856a9 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Fri, 13 Mar 2026 14:42:56 +0100 Subject: [PATCH 02/25] =?UTF-8?q?=F0=9F=90=9B=20wrapper=20params=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fluidFlow/CompositionalMultiphaseStatisticsTask.cpp | 8 +++++--- .../fluidFlow/SinglePhaseStatisticsTask.cpp | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp index 122a5144886..35d74f9036b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp @@ -40,10 +40,12 @@ StatsTask::StatsTask( string const & name, Group * const parent ): m_computeRegionStatistics( 1 ) { registerWrapper( viewKeyStruct::setNamesString(), &m_setNames ). - setApplyDefaultValue( "{}" ). + setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ). setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Optional targeted mesh element set(s) for which the statistics will be restricted." - "If empty, all mesh regions will be processed." + setSizedFromParent( 0 ). + setDescription( "Optional targeted mesh element set(s) for which the statistics will be restricted. " + "A set can be be defined by a 'Geometry' component, or correspond to imported sets in case of an external mesh. " + "If empty, all mesh regions will be processed. " "Be aware that only the regions that are computed by the solver will be taken into account." ); registerWrapper( viewKeyStruct::computeCFLNumbersString(), &m_computeCFLNumbers ). diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp index f4523fa2440..690af1779fe 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp @@ -34,10 +34,12 @@ StatsTask::StatsTask( const string & name, Group * const parent ): Base( name, parent ) { registerWrapper( viewKeyStruct::setNamesString(), &m_setNames ). - setApplyDefaultValue( "{}" ). + setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ). setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Optional targeted mesh element set(s) for which the statistics will be restricted." - "If empty, all mesh regions will be processed." + setSizedFromParent( 0 ). + setDescription( "Optional targeted mesh element set(s) for which the statistics will be restricted. " + "A set can be be defined by a 'Geometry' component, or correspond to imported sets in case of an external mesh. " + "If empty, all mesh regions will be processed. " "Be aware that only the regions that are computed by the solver will be taken into account." ); addLogLevel< logInfo::Statistics >(); From 2ab71be279cc59728eac60a1740a191298c33c81 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Fri, 13 Mar 2026 15:07:44 +0100 Subject: [PATCH 03/25] =?UTF-8?q?=F0=9F=93=9D=20missing=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../physicsSolvers/StatisticsAggregatorBase.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index bcfb06de296..bce93f192ee 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -220,6 +220,10 @@ class StatsAggregatorBase /// The current state of the region statistics StatsState m_regionStatsState; + /** + * @param path the path of the discretization group in the data-repository. + * @return MeshLevel& the MeshLevel Group for the given discretisation + */ MeshLevel & getMeshLevel( DiscretizationGroupPath const & path ) const; /** From 876b54ba51cabf8a0e580c9b94221fe9fbdb1459 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Fri, 13 Mar 2026 15:08:56 +0100 Subject: [PATCH 04/25] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20method=20should=20be?= =?UTF-8?q?=20private?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../physicsSolvers/StatisticsAggregatorBase.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index bce93f192ee..f7992a68d72 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -127,14 +127,6 @@ class StatsAggregatorBase void initStatisticsAggregation( dataRepository::Group & meshBodies, SolverType & solver ); - /** - * @brief Enable the computation of region statistics, initialize data structure to collect them. - * Register the resulting data wrappers so they will be targeted by TimeHistory output - * @note Must be called in or after the "registerDataOnMesh" initialization phase - * @param registerStatsFunc The functor which register each statistics group whithin the regions hierarchy - */ - void enableRegionStatisticsAggregation( RegionStatsRegisterFunc && registerStatsFunc ); - void forRegionStatistics( RegionStatsFunc< MeshLevel > const & functor ) const; void forRegionStatistics( MeshLevel & mesh, @@ -220,6 +212,14 @@ class StatsAggregatorBase /// The current state of the region statistics StatsState m_regionStatsState; + /** + * @brief Enable the computation of region statistics, initialize data structure to collect them. + * Register the resulting data wrappers so they will be targeted by TimeHistory output + * @note Must be called in or after the "registerDataOnMesh" initialization phase + * @param registerStatsFunc The functor which register each statistics group whithin the regions hierarchy + */ + void enableRegionStatisticsAggregation( RegionStatsRegisterFunc && registerStatsFunc ); + /** * @param path the path of the discretization group in the data-repository. * @return MeshLevel& the MeshLevel Group for the given discretisation From db605771e9f7c0126a64b6e1a49544fe89764010 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Fri, 13 Mar 2026 17:31:57 +0100 Subject: [PATCH 05/25] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20follow=20conventions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../physicsSolvers/StatisticsAggregatorBase.hpp | 7 ++++--- .../StatisticsAggregatorBaseHelpers.hpp | 14 +++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index f7992a68d72..da40d4d9cde 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -192,9 +192,10 @@ class StatsAggregatorBase struct DiscretizationGroupPath { - localIndex meshBody; - localIndex meshLevel; - string_array regionNames; + localIndex m_meshBody; + localIndex m_meshLevel; + string_array m_regionNames; + }; }; /// @see getOwnerName() diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp index 2d5f52ea284..aaf2165111e 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp @@ -78,9 +78,9 @@ StatsAggregatorBase< Impl >::initStatisticsAggregation( dataRepository::Group & // remembering the path of this discretization MeshBody const & body = m_meshBodies->getGroup< MeshBody >( meshBodyName ); DiscretizationGroupPath const path { - body.getIndexInParent(), - mesh.getIndexInParent(), - regionNames, + /* .m_meshBody = */ body.getIndexInParent(), + /* .m_meshLevel = */ mesh.getIndexInParent(), + /* .m_regionNames = */ regionNames, }; m_discretizationsPaths.push_back( path ); } ); @@ -104,9 +104,9 @@ StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegis StatsGroupType & meshRegionsStats = registerStatsFunc( statisticsGroup, ViewKeys::regionsStatisticsString() ); - for( size_t i = 0; i < path.regionNames.size(); ++i ) + for( size_t i = 0; i < path.m_regionNames.size(); ++i ) { - CellElementRegion & region = elemManager.getRegion< CellElementRegion >( path.regionNames[i] ); + CellElementRegion & region = elemManager.getRegion< CellElementRegion >( path.m_regionNames[i] ); StatsGroupType & regionStats = registerStatsFunc( meshRegionsStats, region.getName() ); @@ -257,8 +257,8 @@ template< typename Impl > MeshLevel & StatsAggregatorBase< Impl >::getMeshLevel( DiscretizationGroupPath const & path ) const { - MeshBody & body = m_meshBodies->getGroup< MeshBody >( path.meshBody ); - MeshLevel & mesh = body.getMeshLevel( path.meshLevel ); + MeshBody & body = m_meshBodies->getGroup< MeshBody >( path.m_meshBody ); + MeshLevel & mesh = body.getMeshLevel( path.m_meshLevel ); return mesh; } From db9049bbabe75ae1c70628262b02cec420dc3c8d Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Fri, 13 Mar 2026 17:32:12 +0100 Subject: [PATCH 06/25] =?UTF-8?q?=F0=9F=9A=A7=20add=20set=20selection=20to?= =?UTF-8?q?=20stat=20aggregators?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StatisticsAggregatorBase.hpp | 12 +++++++++++ .../StatisticsAggregatorBaseHelpers.hpp | 21 ++++++++++++++++++- .../CompositionalMultiphaseStatisticsTask.cpp | 3 +++ .../fluidFlow/SinglePhaseStatisticsTask.cpp | 3 +++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index da40d4d9cde..6f76b44c56b 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -127,6 +127,8 @@ class StatsAggregatorBase void initStatisticsAggregation( dataRepository::Group & meshBodies, SolverType & solver ); + void restrictToSets( string_array const & setNames ); + void forRegionStatistics( RegionStatsFunc< MeshLevel > const & functor ) const; void forRegionStatistics( MeshLevel & mesh, @@ -196,6 +198,10 @@ class StatsAggregatorBase localIndex m_meshLevel; string_array m_regionNames; }; + + struct SelectedSet { + SortedArrayView< localIndex const > m_set; + string m_name; }; /// @see getOwnerName() @@ -203,6 +209,12 @@ class StatsAggregatorBase bool const m_statsOutputEnabled; + /// if true, the statistics are computed for given sets of elements (see restrictToSets()). + bool m_isRestrictedToSets; + + /// optional list of sets + array1d< SelectedSet > m_sets; + dataRepository::Group * m_meshBodies = nullptr; std::vector< DiscretizationGroupPath > m_discretizationsPaths; diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp index aaf2165111e..deb42849478 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp @@ -48,7 +48,8 @@ template< typename Impl > StatsAggregatorBase< Impl >::StatsAggregatorBase( dataRepository::DataContext const & ownerDataContext, bool const statsOutputEnabled ): m_ownerDataContext( ownerDataContext ), - m_statsOutputEnabled( statsOutputEnabled ) + m_statsOutputEnabled( statsOutputEnabled ), + m_isRestrictedToSets( false ) {} template< typename Impl > @@ -129,6 +130,24 @@ StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegis m_regionStatsState.m_isDirty = true; } +template< typename Impl > +void +StatsAggregatorBase< Impl >::restrictToSets( string_array const & /*setNames*/ ) +{ + for( auto const & path : m_discretizationsPaths ) + { + if( MpiWrapper::commRank()==0 ) + { + GEOS_LOG( "=======================================" ); + MeshLevel const & mesh = getMeshLevel( path ); + mesh.printDataHierarchy( 2 ); + GEOS_LOG( "=======================================" ); + } + } + + m_isRestrictedToSets = MpiWrapper::max( m_sets.size()) > 0; +} + template< typename Impl > void StatsAggregatorBase< Impl >::forRegionStatistics( RegionStatsFunc< MeshLevel > const & func ) const diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp index 35d74f9036b..3abde88b0ff 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp @@ -118,6 +118,9 @@ void StatsTask::registerDataOnMesh( Group & meshBodies ) if( m_computeCFLNumbers ) m_aggregator->enableCFLStatistics(); + if( m_setNames.size() > 0 ) + m_aggregator->restrictToSets( m_setNames ); + m_aggregator->forRegionStatistics( [&] ( MeshLevel & mesh, RegionStatistics & ) { prepareLogTableLayouts( mesh.getName() ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp index 690af1779fe..b18b8cd0796 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp @@ -84,6 +84,9 @@ void StatsTask::registerDataOnMesh( Group & meshBodies ) m_aggregator->enableRegionStatisticsAggregation(); + if( m_setNames.size() > 0 ) + m_aggregator->restrictToSets( m_setNames ); + m_aggregator->forRegionStatistics( [&] ( MeshLevel & mesh, RegionStatistics & ) { prepareLogTableLayouts( mesh.getName() ); From 5271c271d6d5c8cec56df620321bac37e072c350 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Fri, 13 Mar 2026 17:32:54 +0100 Subject: [PATCH 07/25] =?UTF-8?q?=E2=9C=85=20add=20a=20test=20case?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../simpleCo2InjTutorial_base.xml | 13 ++++++++++ .../simpleCo2InjTutorial_smoke.xml | 25 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml b/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml index 705b4934fb9..2dd5fda291d 100644 --- a/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml +++ b/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml @@ -198,6 +198,19 @@ objectPath="ElementRegions/wellRegion/wellRegionUniqueSubRegion" fieldName="pressure" /> + + + + diff --git a/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_smoke.xml b/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_smoke.xml index 5e2f4c93169..907a348217e 100644 --- a/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_smoke.xml +++ b/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_smoke.xml @@ -26,7 +26,8 @@ { 525.0, 525.0, 6600.00 } }" polylineSegmentConn="{ { 0, 1 } }" radius="0.1" - numElementsPerSegment="2"> + numElementsPerSegment="2" + logLevel="1"> @@ -34,6 +35,18 @@ + + + + + + + + + + + + + From 0f6fb9cadb289433888e32241d3f031b4f349a91 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Fri, 13 Mar 2026 17:33:13 +0100 Subject: [PATCH 08/25] =?UTF-8?q?=F0=9F=93=A6=20schema=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/coreComponents/schema/schema.xsd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreComponents/schema/schema.xsd b/src/coreComponents/schema/schema.xsd index 728d7ec8eff..8f3fed44503 100644 --- a/src/coreComponents/schema/schema.xsd +++ b/src/coreComponents/schema/schema.xsd @@ -6324,6 +6324,8 @@ Information output from lower logLevels is added with the desired log level + + @@ -6542,6 +6544,8 @@ Information output from lower logLevels is added with the desired log level 1 - Print statistics--> + + From 605e02fba6bc105b32533cf90bdc2d196dc01bd5 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Fri, 13 Mar 2026 17:55:55 +0100 Subject: [PATCH 09/25] =?UTF-8?q?=F0=9F=90=9B=20fix=20merge=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../physicsSolvers/StatisticsAggregatorBase.hpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index 4a6bfe979d9..6f76b44c56b 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -233,18 +233,6 @@ class StatsAggregatorBase */ void enableRegionStatisticsAggregation( RegionStatsRegisterFunc && registerStatsFunc ); - /** - * @param path the path of the discretization group in the data-repository. - * @return MeshLevel& the MeshLevel Group for the given discretisation - */ - /** - * @brief Enable the computation of region statistics, initialize data structure to collect them. - * Register the resulting data wrappers so they will be targeted by TimeHistory output - * @note Must be called in or after the "registerDataOnMesh" initialization phase - * @param registerStatsFunc The functor which register each statistics group whithin the regions hierarchy - */ - void enableRegionStatisticsAggregation( RegionStatsRegisterFunc && registerStatsFunc ); - /** * @param path the path of the discretization group in the data-repository. * @return MeshLevel& the MeshLevel Group for the given discretisation From aa42af473c2de19a13ee867fed88531c4a45870d Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Fri, 13 Mar 2026 19:07:54 +0100 Subject: [PATCH 10/25] =?UTF-8?q?=F0=9F=93=9Dmore=20precise=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SinglePhaseStatisticsAggregator.hpp | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp index baa4202cd44..38df8a6360f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp @@ -23,31 +23,43 @@ * |-> cartesianMesh : MeshBody * |-> meshLevels : Group * |-> Level0 : MeshLevel + * | |-> ElementRegions : ElementRegionManager + * | | |-> elementRegionsGroup : Group + * | | |-> Channel : CellElementRegion + * | | | |-> elementSubRegions : Group + * | | | |-> cb-0_0_0 : CellElementSubRegion + * | | | | | * pressure : Wrapper< real64 array > + * | | | | | * temperature : Wrapper< real64 array > + * | | | | |-> sets : Group + * | | | | | | * all : Wrapper< index array > + * | | | | | | * myBox : Wrapper< index array > + * | | | | | [...] (other element sets) + * | | | | | + * | | | | [...] (other fields) + * | | | | + * | | | |-> cb-0_0_1 : CellElementSubRegion + * | | | | | * pressure : Wrapper< real64 array > + * | | | | | * temperature : Wrapper< real64 array > + * | | | | |-> sets : Group + * | | | | | | * all : Wrapper< index array > + * | | | | | | * myBox : Wrapper< index array > + * | | | | | [...] (other element sets) + * | | | | | + * | | | | [...] (other fields) + * | | | | + * | | | [...] (other sub-regions) + * | | | + * | | |-> Barrier : CellElementRegion + * | | |-> cb-1_0_0 : CellElementSubRegion + * | | |-> cb-1_0_1 : CellElementSubRegion + * | | [...] (other sub-regions) + * | | * | |-> nodeManager : NodeManager * | | |-> sets : Group * | | | * all : Wrapper< index array > - * | | | * xneg : Wrapper< index array > + * | | | * myBox : Wrapper< index array > * | | [...] (other element sets) * | | - * | |-> ElementRegions : ElementRegionManager - * | | |-> Channel : CellElementRegion - * | | | |-> cb-0_0_0 : CellElementSubRegion - * | | | | | * pressure : Wrapper< real64 array > - * | | | | | * temperature : Wrapper< real64 array > - * | | | | [...] (other fields) - * | | | | - * | | | |-> cb-0_0_1 : CellElementSubRegion - * | | | | | * pressure : Wrapper< real64 array > - * | | | | | * temperature : Wrapper< real64 array > - * | | | | [...] (other fields) - * | | | | - * | | | [...] (other sub-regions) - * | | | - * | | |-> Barrier : CellElementRegion - * | | |-> cb-1_0_0 : CellElementSubRegion - * | | |-> cb-1_0_1 : CellElementSubRegion - * | | [...] (other sub-regions) - * | | * | [...] (other element managers) * ____ | | * | | |-> statistics : Group (storage for all stats) From 39f9fb086dd47e87d320f27c3f2a2d0d552ed913 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Fri, 13 Mar 2026 19:08:57 +0100 Subject: [PATCH 11/25] =?UTF-8?q?=E2=9C=85=20test=20fix=20(5x5=20selection?= =?UTF-8?q?=20verified)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../simpleCo2InjTutorial_smoke.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_smoke.xml b/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_smoke.xml index 907a348217e..bb94303c5d6 100644 --- a/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_smoke.xml +++ b/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_smoke.xml @@ -40,10 +40,11 @@ + + xMin="{ 470.0, 400.0, 6584.0 }" + xMax="{ 590.0, 600.0, 6632.0 }" /> From 86499b828cf715bdd1252a1654e8edfa9633912d Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Mon, 16 Mar 2026 15:59:34 +0100 Subject: [PATCH 12/25] =?UTF-8?q?=F0=9F=93=9D=20added=20sets=20data=20stru?= =?UTF-8?q?cture=20docs=20+=20show=20which=20name=20is=20dynamic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...sitionalMultiphaseStatisticsAggregator.hpp | 49 ++++++++++--------- .../SinglePhaseStatisticsAggregator.hpp | 39 ++++++++------- 2 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp index a4969470188..8aed90874f1 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp @@ -20,49 +20,52 @@ * Problem : ProblemManager * |-> domain : DomainPartition * |-> MeshBodies : Group - * |-> cartesianMesh : MeshBody + * |-> "cartesianMesh" : MeshBody * |-> meshLevels : Group * |-> Level0 : MeshLevel - * | |-> nodeManager : NodeManager - * | | |-> sets : Group - * | | | * all : Wrapper< index array > - * | | | * xneg : Wrapper< index array > - * | | [...] (other element sets) - * | | * | |-> ElementRegions : ElementRegionManager - * | | |-> Channel : CellElementRegion - * | | | |-> cb-0_0_0 : CellElementSubRegion + * | | |-> "Channel" : CellElementRegion + * | | | |-> "cb-0_0_0" : CellElementSubRegion * | | | | | * pressure : Wrapper< real64 array > * | | | | | * temperature : Wrapper< real64 array > * | | | | [...] (other fields) * | | | | - * | | | |-> cb-0_0_1 : CellElementSubRegion + * | | | |-> "cb-0_0_1" : CellElementSubRegion * | | | | | * pressure : Wrapper< real64 array > * | | | | | * temperature : Wrapper< real64 array > * | | | | [...] (other fields) * | | | | * | | | [...] (other sub-regions) * | | | - * | | |-> Barrier : CellElementRegion - * | | |-> cb-1_0_0 : CellElementSubRegion - * | | |-> cb-1_0_1 : CellElementSubRegion + * | | |-> "Barrier" : CellElementRegion + * | | |-> "cb-1_0_0" : CellElementSubRegion + * | | |-> "cb-1_0_1" : CellElementSubRegion * | | [...] (other sub-regions) * | | + * | |-> nodeManager : NodeManager + * | | |-> sets : Group + * | | | * all : Wrapper< index array > + * | | | * "myBox" : Wrapper< index array > + * | | [...] (other element sets) + * | | * | [...] (other element managers) * ____ | | * | | |-> statistics : Group (storage for all stats) - * | | |-> compFlowStats : Group (storage for this instance stats) + * | | |-> "compFlowStats" : Group (storage for this instance stats) * | | | |-> cflStatistics : CFLStatistics - * | | | |-> regionsStatistics : RegionStatistics (aggregate) - * | | | |-> Channel : RegionStatistics (aggregate, mpi reduced) - * | | | | |-> cb-0_0_0 : RegionStatistics (compute read-back) - * stats | | | | |-> cb-0_0_1 : RegionStatistics (compute read-back) - * data -> | | | | [...] (other sub-regions stats) + * | | | |-> regionsStatistics : RegionStatistics (mesh-level aggregate) + * | | | |-> all / "myBox" : RegionStatistics (selected set aggregate) + * | | | | |-> "Channel" : RegionStatistics (region aggregate, mpi reduced) + * | | | | | |-> "cb-0_0_0" : RegionStatistics (sub-region compute read-back) + * stats | | | | | |-> "cb-0_0_1" : RegionStatistics (sub-region compute read-back) + * data -> | | | | | [...] (other sub-regions stats) + * | | | | | + * | | | | |-> "Barrier" : RegionStatistics (region aggregate, mpi reduced) + * | | | | |-> cb-1_0_0 : RegionStatistics (sub-region compute read-back) + * | | | | |-> cb-1_0_1 : RegionStatistics (sub-region compute read-back) + * | | | | [...] (other sub-regions stats) * | | | | - * | | | |-> Barrier : RegionStatistics (aggregate, mpi reduced) - * | | | |-> cb-1_0_0 : RegionStatistics (compute read-back) - * | | | |-> cb-1_0_1 : RegionStatistics (compute read-back) - * | | | [...] (other sub-regions stats) + * | | | [...] (other set aggregates) * | | | * |___ | [...] (other stats storages) * | diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp index 38df8a6360f..432fc947b22 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp @@ -20,14 +20,14 @@ * Problem : ProblemManager * |-> domain : DomainPartition * |-> MeshBodies : Group - * |-> cartesianMesh : MeshBody + * |-> "cartesianMesh" : MeshBody * |-> meshLevels : Group * |-> Level0 : MeshLevel * | |-> ElementRegions : ElementRegionManager * | | |-> elementRegionsGroup : Group - * | | |-> Channel : CellElementRegion + * | | |-> "Channel" : CellElementRegion * | | | |-> elementSubRegions : Group - * | | | |-> cb-0_0_0 : CellElementSubRegion + * | | | |-> "cb-0_0_0" : CellElementSubRegion * | | | | | * pressure : Wrapper< real64 array > * | | | | | * temperature : Wrapper< real64 array > * | | | | |-> sets : Group @@ -37,7 +37,7 @@ * | | | | | * | | | | [...] (other fields) * | | | | - * | | | |-> cb-0_0_1 : CellElementSubRegion + * | | | |-> "cb-0_0_1" : CellElementSubRegion * | | | | | * pressure : Wrapper< real64 array > * | | | | | * temperature : Wrapper< real64 array > * | | | | |-> sets : Group @@ -49,31 +49,34 @@ * | | | | * | | | [...] (other sub-regions) * | | | - * | | |-> Barrier : CellElementRegion - * | | |-> cb-1_0_0 : CellElementSubRegion - * | | |-> cb-1_0_1 : CellElementSubRegion + * | | |-> "Barrier" : CellElementRegion + * | | |-> "cb-1_0_0" : CellElementSubRegion + * | | |-> "cb-1_0_1" : CellElementSubRegion * | | [...] (other sub-regions) * | | * | |-> nodeManager : NodeManager * | | |-> sets : Group * | | | * all : Wrapper< index array > - * | | | * myBox : Wrapper< index array > + * | | | * "myBox" : Wrapper< index array > * | | [...] (other element sets) * | | * | [...] (other element managers) * ____ | | * | | |-> statistics : Group (storage for all stats) - * | | |-> flowStats : Group (storage for this instance stats) - * | | | |-> regionsStatistics : RegionStatistics (aggregate) - * | | | |-> Channel : RegionStatistics (aggregate, mpi reduced) - * | | | | |-> cb-0_0_0 : RegionStatistics (compute read-back) - * stats | | | | |-> cb-0_0_1 : RegionStatistics (compute read-back) - * data -> | | | | [...] (other sub-regions stats) + * | | |-> "flowStats" : Group (storage for this instance stats) + * | | | |-> regionsStatistics : RegionStatistics (mesh-level aggregate) + * | | | |-> all / "myBox" : RegionStatistics (selected set aggregate) + * | | | | |-> "Channel" : RegionStatistics (region aggregate, mpi reduced) + * | | | | | |-> "cb-0_0_0" : RegionStatistics (sub-region compute read-back) + * stats | | | | | |-> "cb-0_0_1" : RegionStatistics (sub-region compute read-back) + * data -> | | | | | [...] (other sub-regions stats) + * | | | | | + * | | | | |-> "Barrier" : RegionStatistics (region aggregate, mpi reduced) + * | | | | |-> cb-1_0_0 : RegionStatistics (sub-region compute read-back) + * | | | | |-> cb-1_0_1 : RegionStatistics (sub-region compute read-back) + * | | | | [...] (other sub-regions stats) * | | | | - * | | | |-> Barrier : RegionStatistics (aggregate, mpi reduced) - * | | | |-> cb-1_0_0 : RegionStatistics (compute read-back) - * | | | |-> cb-1_0_1 : RegionStatistics (compute read-back) - * | | | [...] (other sub-regions stats) + * | | | [...] (other set aggregates) * | | | * |___ | [...] (other stats storages) * | From dda3ac69c0fd99011608bdc39b96fd8936957d9c Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Mon, 23 Mar 2026 16:23:43 +0100 Subject: [PATCH 13/25] =?UTF-8?q?=F0=9F=9A=A7=20infrastructure=20to=20supp?= =?UTF-8?q?ort=20statistics=20processing=20on=20element=20sets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StatisticsAggregatorBase.hpp | 216 ++++++++--- .../StatisticsAggregatorBaseHelpers.hpp | 356 ++++++++++++------ ...sitionalMultiphaseStatisticsAggregator.cpp | 29 +- ...sitionalMultiphaseStatisticsAggregator.hpp | 12 +- .../CompositionalMultiphaseStatisticsTask.cpp | 71 +++- .../CompositionalMultiphaseStatisticsTask.hpp | 4 +- .../SinglePhaseStatisticsAggregator.cpp | 20 +- .../SinglePhaseStatisticsAggregator.hpp | 10 +- .../fluidFlow/SinglePhaseStatisticsTask.cpp | 76 ++-- .../fluidFlow/SinglePhaseStatisticsTask.hpp | 4 +- .../unitTests/testFlowStatistics.cpp | 2 +- 11 files changed, 548 insertions(+), 252 deletions(-) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index 6f76b44c56b..3b024c44ed6 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -39,7 +39,7 @@ class RegionStatisticsBase : public dataRepository::Group { public: - /// Time of statistics computation + /// Time of statistics computation (std::numeric_limits< double >::lowest() if not initialized) real64 m_time; /** @@ -47,10 +47,15 @@ class RegionStatisticsBase : public dataRepository::Group * @param targetName name of the data-repository object that is targeted by the statistics * (mesh level / region / sub-region). * @param parent the instance parent in data-repository + * @param setName Optional name of a set, restricting the statistics on given mesh element. + * If none is specified (empty), "all" elements set is targeted. + * @param dataOutputEnabled If true, the stats are saved in the output HDF5 (dataRepository::RestartFlags, not functional for this output + * for now). */ RegionStatisticsBase( string const & targetName, dataRepository::Group * const parent, - bool statsOutputEnabled ); + string_view setName, + bool dataOutputEnabled ); /** * @return the name of the data-repository object that is targeted by the statistics @@ -59,6 +64,16 @@ class RegionStatisticsBase : public dataRepository::Group string_view getTargetName() const { return getName(); } + /** + * @return Optional name of a set, restricting the statistics on given mesh element. + * If none is specified (empty), "all" elements set is targeted. + */ + string_view getSetName() const + { return m_setName; } + +private: + /// @see getSetName() + string const m_setName; }; template< typename T > @@ -80,6 +95,8 @@ class StatsAggregatorBase using StatsGroupType = typename StatsAggregatorTraits< Impl >::StatsGroupType; + using SetType = SortedArray< localIndex >; + /** * @brief Standard function signature for any functor that applies on statistics group instances (StatsGroupType) * - param 0: OwnerType &, the group instance containing the data for which we want to aggregate the statistics (MeshLevel, @@ -88,26 +105,43 @@ class StatsAggregatorBase * @tparam OwnerType the concrete type of the OwnerType param */ template< typename OwnerType > - using RegionStatsFunc = std::function< void ( OwnerType &, + using RegionStatsFunc = std::function< void ( OwnerType, StatsGroupType & ) >; /** * @brief TODO Document + * - dataRepository::Group & targetName: the parent Group, + * - string const & parent: name of the statistics target (i.e. region name). + * - string_view setName: name of the target element set. If none is specified (empty), "all" elements set is targeted. + * - bool dataOutputEnabled: enable Group output features */ using RegionStatsRegisterFunc = std::function< StatsGroupType & ( dataRepository::Group &, - string const & ) >; + string const &, + string_view, + bool ) >; /** * @brief the associated view keys */ struct ViewKeys { - /// String for the discretization statistics group + /// String for the mesh-level statistics group constexpr static char const * statisticsString() { return "statistics"; } /// String for the region statistics group + constexpr static char const * setsStatisticsString() { return "setsStatistics"; } + /// String for the region statistics group constexpr static char const * regionsStatisticsString() { return "regionsStatistics"; } }; + /** + * @brief Allow to reference a set in a given MeshLevel structure. + */ + struct MeshLevelSet + { + MeshLevel & mesh; + string_view setName; + }; + /** * @brief Construct a new Stats Aggregator object * @param ownerName the unique name of the entity requesting the statistics. @@ -117,8 +151,7 @@ class StatsAggregatorBase bool statsOutputEnabled ); /** - * @brief Enable the computation of any statistics, initialize data structure to collect them. - * Register the resulting data wrappers so they will be targeted by TimeHistory output + * @brief Enable the computation of any statistics, explores the data structure to collect them. * @param solver flow solver object to retrieve: - the simulated regions, - fields for statistics computation. @@ -127,17 +160,95 @@ class StatsAggregatorBase void initStatisticsAggregation( dataRepository::Group & meshBodies, SolverType & solver ); - void restrictToSets( string_array const & setNames ); + /** + * @brief set the statistics as dirty, ensuring isComputed() will be false until the next computation. + */ + void setDirty(); - void forRegionStatistics( RegionStatsFunc< MeshLevel > const & functor ) const; + /** + * @brief Compute statistics on the mesh discretizations (average field pressure, etc) + * Results are reduced on rank 0, and broadcasted over all ranks. + * @param[in] timeRequest The time for which we want to compute the statistics. + * @return false if there was a problem that prevented the statistics to be computed correctly. + */ + bool computeRegionsStatistics( real64 const timeRequest ); + + /** + * @name Data Structure Traversal Strategy + */ + ///@{ + /** + * @brief Execute the given functor on each mesh-level (discretization) available for this instance. + * @param functor the function to execute. + */ + void forRegionStatistics( RegionStatsFunc< MeshLevel & > const & functor ) const; + + /** + * @brief Execute the given functor on each set present in the given mesh-level (discretization). + * @param mesh the target mesh-level. + * @param meshSetsStats the instance mesh-level statistics data structure. + * @param functor the function to execute. + */ void forRegionStatistics( MeshLevel & mesh, - StatsGroupType & meshRegionsStatistics, - RegionStatsFunc< CellElementRegion > const & functor ) const; + StatsGroupType & meshSetsStats, + RegionStatsFunc< MeshLevelSet > const & functor ) const; + /** + * @brief Execute the given functor on each region available in the given mesh-level for the given set. + * @param meshSet the target mesh-level set. + * @param setStats the mesh-level statistics data structure for the given set. + * @param functor the function to execute. + */ + void forRegionStatistics( MeshLevelSet meshSet, + StatsGroupType & setStats, + RegionStatsFunc< CellElementRegion & > const & functor ) const; + + /** + * @brief Execute the given functor on each sub-region available in the given region for the given set. + * @param meshSet the target region set. + * @param setRegionStats the region statistics data structure for the given set. + * @param functor the function to execute. + */ void forRegionStatistics( CellElementRegion & region, - StatsGroupType & regionStatistics, - RegionStatsFunc< CellElementSubRegion > const & functor ) const; + StatsGroupType & setRegionStats, + RegionStatsFunc< CellElementSubRegion & > const & functor ) const; + + /** + * @brief Get the Instance Statistics Group for the given mesh-level. + * @param mesh the mesh-level (discretization). + * @return A Group instance hierarchically holding all statistics data structures. + */ + dataRepository::Group & getInstanceStatisticsGroup( MeshLevel & mesh ) const; + + /** + * @return A statistics data structure (see StatsGroupType), aggregated from all targeted regions + * and sets in the given mesh-level. + * @param mesh the mesh-level (discretization). + */ + StatsGroupType & getMeshLevelStatistics( MeshLevel & mesh ) const; + + /** + * @return A statistics data structure (see StatsGroupType), aggregated from all targeted regions + * for the given set in the given mesh-level. + * @param mesh the mesh-level (discretization). + * @param setName the name of element set. If none is specified (empty), "all" elements set is targeted. + * @throw InputError if "all" is targeted, but the instance does not target "all" element set. + */ + StatsGroupType & getSetStatistics( MeshLevel & mesh, string_view setName = "" ) const; + + /** + * @return A statistics data structure (see StatsGroupType), for the given set, in the given region, + * in the given mesh-level. + * @param mesh The mesh-level (discretization) + * @param setName the name of element set. If none is specified (empty), "all" elements set is targeted. + * @param regionName The name of the desired region + * @throw InputError - if no statistics data is found for the given region name. + * - if "all" is targeted, but the instance does not target "all" element set. + */ + StatsGroupType & getRegionStatistics( MeshLevel & mesh, string_view regionName, string_view setName = "" ) const; + + ///@} /** * @param[in] timeRequest The time for which we want to know if the statistics are computed. @@ -147,17 +258,11 @@ class StatsAggregatorBase bool isComputed( real64 const timeRequest, StatsGroupType const & stats ); /** - * @brief set the statistics as dirty, ensuring isComputed() will be false until the next computation. - */ - void setDirty(); - - /** - * @brief Compute statistics on the mesh discretizations (average field pressure, etc) - * Results are reduced on rank 0, and broadcasted over all ranks. - * @param[in] timeRequest The time for which we want to compute the statistics. - * @return false if there was a problem that prevented the statistics to be computed correctly. + * @return true if the region statistics target given sets. + * false if the statistics are targeted on only one mesh-level-wide set */ - bool computeRegionsStatistics( real64 const timeRequest ); + bool isRestrictedToSets() + {return m_setNames.empty() || ( m_setNames.size() == 1 && m_setNames.count( "all" ) > 0 ); } /** * @return the name of the entity that needs the statistics. @@ -171,19 +276,6 @@ class StatsAggregatorBase stdVector< string > const & getWarnings() const { return m_warnings; } - dataRepository::Group & getInstanceStatisticsGroup( MeshLevel & mesh ) const; - - StatsGroupType & getRegionsStatistics( MeshLevel & mesh ) const; - - /** - * @brief TODO - * @throw InputError if no statistics data is found for the given region name. - * @param mesh TODO - * @param regionNname TODO - * @return TODO - */ - StatsGroupType & getRegionStatistics( MeshLevel & mesh, string_view regionName ) const; - protected: struct StatsState @@ -192,32 +284,37 @@ class StatsAggregatorBase bool m_isDirty = false; }; - struct DiscretizationGroupPath + struct DiscretizationSetPath { + /// The id of the mesh body in the "meshBodies" Group localIndex m_meshBody; + /// The id of the mesh level in the mesh body. localIndex m_meshLevel; + /// The names of this mesh-level element sets. If none is specified (empty), "all" elements set is targeted. + string_array m_setNames; + /// the regions names in the mesh-level / mesh level string_array m_regionNames; - }; - - struct SelectedSet { - SortedArrayView< localIndex const > m_set; - string m_name; + /// TODO: if m_isAnySetsIntersecting is true, a compound set is needed to compute mesh-level statistics. + // SetType meshLevelSetsCompound; }; /// @see getOwnerName() dataRepository::DataContext const & m_ownerDataContext; - bool const m_statsOutputEnabled; + bool const m_dataOutputEnabled; - /// if true, the statistics are computed for given sets of elements (see restrictToSets()). - bool m_isRestrictedToSets; + dataRepository::Group * m_meshBodies = nullptr; - /// optional list of sets - array1d< SelectedSet > m_sets; + /// Data repository paths of the element sets per mesh levels + /// TODO: can it be generalized with the "all" set + std::vector< DiscretizationSetPath > m_discretizationsPaths; - dataRepository::Group * m_meshBodies = nullptr; + /// The list of mesh element sets to restrict the region statistics to. + /// Cannot be empty: if the whole mesh-level is to process, "all" must be targeted. + std::set< string > m_setNames; - std::vector< DiscretizationGroupPath > m_discretizationsPaths; + /// if true, at least ont set intersects with another, threfore we must compute mesh-level statistics with a coupound. + bool m_isAnySetsIntersecting; /// @see getWarnings() stdVector< string > m_warnings; @@ -230,14 +327,29 @@ class StatsAggregatorBase * Register the resulting data wrappers so they will be targeted by TimeHistory output * @note Must be called in or after the "registerDataOnMesh" initialization phase * @param registerStatsFunc The functor which register each statistics group whithin the regions hierarchy + * @param setNames The list of mesh element sets to restrict the statistics to. + * If empty, the whole mesh-level is processed. */ - void enableRegionStatisticsAggregation( RegionStatsRegisterFunc && registerStatsFunc ); + void enableRegionStatisticsAggregation( RegionStatsRegisterFunc && registerStatsFunc, + string_array const & setNames ); /** - * @param path the path of the discretization group in the data-repository. + * @param path the path of the mesh-level group in the data-repository. * @return MeshLevel& the MeshLevel Group for the given discretisation */ - MeshLevel & getMeshLevel( DiscretizationGroupPath const & path ) const; + MeshLevel & getMeshLevel( DiscretizationSetPath const & path ) const; + + /** + * @brief TODO + */ + static std::set< string > getMeshLevelPartialSetNames( MeshLevel const & mesh, + string_array const & regionNames ); + + /** + * @brief Set the statstics target sets to restrict the statistics to. + * @param setNames the list of target sets. If "all" is included, or none is present, all the discretisation is targeted. + */ + void setTargetSets( string_array const & setNames ); /** * @brief Initialize all statistics values to aggregable default values, diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp index deb42849478..d0f1cabad0b 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp @@ -33,11 +33,13 @@ namespace geos inline RegionStatisticsBase::RegionStatisticsBase( string const & targetName, dataRepository::Group * const parent, - bool const statsOutputEnabled ): + string_view setName, + bool const dataOutputEnabled ): dataRepository::Group( targetName, parent ), - m_time( std::numeric_limits< double >::lowest() ) + m_time( std::numeric_limits< double >::lowest() ), + m_setName( setName ) { - Group::setRestartFlags( statsOutputEnabled ? + Group::setRestartFlags( dataOutputEnabled ? dataRepository::RestartFlags::WRITE_AND_READ : dataRepository::RestartFlags::NO_WRITE ); @@ -46,12 +48,36 @@ inline RegionStatisticsBase::RegionStatisticsBase( string const & targetName, template< typename Impl > StatsAggregatorBase< Impl >::StatsAggregatorBase( dataRepository::DataContext const & ownerDataContext, - bool const statsOutputEnabled ): + bool const dataOutputEnabled ): m_ownerDataContext( ownerDataContext ), - m_statsOutputEnabled( statsOutputEnabled ), - m_isRestrictedToSets( false ) + m_dataOutputEnabled( dataOutputEnabled ), + m_isAnySetsIntersecting( false ) {} +template< typename Impl > +std::set< string > +StatsAggregatorBase< Impl >::getMeshLevelPartialSetNames( MeshLevel const & mesh, + string_array const & regionNames ) +{ + std::set< string > foundSetNames; + + mesh.getElemManager().forElementRegions< CellElementRegion >( regionNames, + [&] ( localIndex &, + CellElementRegion const & region ) + { + region.forElementSubRegions< CellElementSubRegion >( [&] ( CellElementSubRegion const & subRegion ) { + dataRepository::Group const & sets = subRegion.sets(); + sets.forWrappers< SetType >( [&] ( dataRepository::Wrapper< SetType > const & set ) + { + // if( set.getName() != "all" ) // TODO: is it useful? + foundSetNames.emplace( set.getName() ); + } ); + } ); + } ); + + return foundSetNames; +} + template< typename Impl > void StatsAggregatorBase< Impl >::initStatisticsAggregation( dataRepository::Group & meshBodies, @@ -76,48 +102,82 @@ StatsAggregatorBase< Impl >::initStatisticsAggregation( dataRepository::Group & m_ownerDataContext ); meshStatsGroup->registerGroup( ownerName ); - // remembering the path of this discretization MeshBody const & body = m_meshBodies->getGroup< MeshBody >( meshBodyName ); - DiscretizationGroupPath const path { - /* .m_meshBody = */ body.getIndexInParent(), - /* .m_meshLevel = */ mesh.getIndexInParent(), - /* .m_regionNames = */ regionNames, - }; - m_discretizationsPaths.push_back( path ); + + /// finding all sets in this mesh level + std::set< string > foundSetNames = getMeshLevelPartialSetNames( mesh, regionNames ); + + { // remembering the path of this discretization + DiscretizationSetPath const path { + /* .m_meshBody = */ body.getIndexInParent(), + /* .m_meshLevel = */ mesh.getIndexInParent(), + /* .m_setNames = */ string_array( foundSetNames.begin(), foundSetNames.end()), + /* .m_regionNames = */ regionNames, + }; + m_discretizationsPaths.emplace_back( path ); + } } ); } template< typename Impl > void -StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegisterFunc && registerStatsFunc ) +StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegisterFunc && registerStatsFunc, + string_array const & setNames ) { if( m_meshBodies == nullptr ) return; + m_setNames.insert( setNames.begin(), setNames.end() ); + if( m_setNames.empty()) + m_setNames.emplace( "all" ); + integer regionCount = 0; integer subRegionCount = 0; + std::set< string > confirmedSets; for( auto const & path : m_discretizationsPaths ) { MeshLevel & mesh = getMeshLevel( path ); ElementRegionManager & elemManager = mesh.getElemManager(); dataRepository::Group & statisticsGroup = getInstanceStatisticsGroup( mesh ); - StatsGroupType & meshRegionsStats = registerStatsFunc( statisticsGroup, - ViewKeys::regionsStatisticsString() ); + StatsGroupType & meshStats = registerStatsFunc( statisticsGroup, + ViewKeys::regionsStatisticsString(), + "", + m_dataOutputEnabled ); - for( size_t i = 0; i < path.m_regionNames.size(); ++i ) + for( string const & setName : m_setNames ) { - CellElementRegion & region = elemManager.getRegion< CellElementRegion >( path.m_regionNames[i] ); - StatsGroupType & regionStats = registerStatsFunc( meshRegionsStats, - region.getName() ); + StatsGroupType & meshSetStats = registerStatsFunc( meshStats, + setName, + setName, + m_dataOutputEnabled ); - region.forElementSubRegions< CellElementSubRegion >( [&] ( CellElementSubRegion & subRegion ) + for( size_t regionId = 0; regionId < path.m_regionNames.size(); ++regionId ) { - registerStatsFunc( regionStats, - subRegion.getName() ); - ++subRegionCount; - } ); - ++regionCount; + CellElementRegion & region = elemManager.getRegion< CellElementRegion >( path.m_regionNames[regionId] ); + StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, + region.getName(), + setName, + m_dataOutputEnabled ); + ++regionCount; + + region.forElementSubRegions< CellElementSubRegion >( [&] ( CellElementSubRegion & subRegion ) + { + registerStatsFunc( setRegionStats, + subRegion.getName(), + setName, + false ); + ++subRegionCount; + + dataRepository::Group const & subRegionSets = subRegion.sets(); + if( subRegionSets.hasWrapper( setName ) && + subRegionSets.getWrapperBase( setName ).size() > 0 ) + { + confirmedSets.emplace( setName ); + // meshLevelSetsCompound.insert() TODO + } + } ); + } } } @@ -128,65 +188,141 @@ StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegis m_regionStatsState.m_isEnabled = true; m_regionStatsState.m_isDirty = true; + + // at this point, m_setNames content is element sets user *requests*: they are the same on every ranks, + // but we don't know yet if any of these set is missing or empty (=> confirmedSets). + std::set< string > notFoundSets; + for( string const & requestedSetName : m_setNames ) + { + if( MpiWrapper::max( confirmedSets.count( requestedSetName ) ) == 0 ) + notFoundSets.emplace( requestedSetName ); + } + if( MpiWrapper::commRank() == 0 ) + GEOS_ERROR_IF( !notFoundSets.empty(), + GEOS_FMT( "During retrieval of statistics element sets, the following set(s) could not be " + "found or does not contain any element:\n- {}", + stringutilities::join( notFoundSets, "\n- " ) ), + m_ownerDataContext ); } template< typename Impl > -void -StatsAggregatorBase< Impl >::restrictToSets( string_array const & /*setNames*/ ) +MeshLevel & +StatsAggregatorBase< Impl >::getMeshLevel( DiscretizationSetPath const & path ) const { - for( auto const & path : m_discretizationsPaths ) - { - if( MpiWrapper::commRank()==0 ) - { - GEOS_LOG( "=======================================" ); - MeshLevel const & mesh = getMeshLevel( path ); - mesh.printDataHierarchy( 2 ); - GEOS_LOG( "=======================================" ); - } - } + MeshBody & body = m_meshBodies->getGroup< MeshBody >( path.m_meshBody ); + MeshLevel & mesh = body.getMeshLevel( path.m_meshLevel ); + return mesh; +} - m_isRestrictedToSets = MpiWrapper::max( m_sets.size()) > 0; +template< typename Impl > +dataRepository::Group & +StatsAggregatorBase< Impl >::getInstanceStatisticsGroup( MeshLevel & mesh ) const +{ + // considering everything is initialized, or else, crash gracefully + dataRepository::Group & meshStatsGroup = mesh.getGroup( ViewKeys::statisticsString() ); + dataRepository::Group & instanceStatisticsGroup = meshStatsGroup.getGroup( getOwnerName() ); + return instanceStatisticsGroup; +} + +template< typename Impl > +typename StatsAggregatorBase< Impl >::StatsGroupType & +StatsAggregatorBase< Impl >:: +getMeshLevelStatistics( MeshLevel & mesh ) const +{ + // considering everything is initialized, or else, crash gracefully + dataRepository::Group & instanceStatisticsGroup = getInstanceStatisticsGroup( mesh ); + return instanceStatisticsGroup.getGroup< StatsGroupType >( ViewKeys::regionsStatisticsString() ); +} + +template< typename Impl > +typename StatsAggregatorBase< Impl >::StatsGroupType & +StatsAggregatorBase< Impl >::getSetStatistics( MeshLevel & mesh, + string_view requestedSetName ) const +{ + // considering everything is initialized, or else, crash gracefully + StatsGroupType & meshStats = getMeshLevelStatistics( mesh ); + string const setName = string( requestedSetName.empty() ? "all" : requestedSetName ); + StatsGroupType * const stats = meshStats.template getGroupPointer< StatsGroupType >( setName ); + GEOS_THROW_IF( stats == nullptr, + GEOS_FMT( "Element set '{}' statistics data structure not found, has the set been requested?\nRequested element sets:\n- {}", + setName, stringutilities::join( m_setNames, "\n- " ) ), + InputError, m_ownerDataContext ); + return *stats; +} + +template< typename Impl > +typename StatsAggregatorBase< Impl >::StatsGroupType & +StatsAggregatorBase< Impl >::getRegionStatistics( MeshLevel & mesh, + string_view setName, + string_view regionName ) const +{ + StatsGroupType & setStats = getSetStatistics( mesh, setName ); + StatsGroupType * const stats = setStats.template getGroupPointer< StatsGroupType >( string( regionName ) ); + GEOS_THROW_IF( stats == nullptr, + GEOS_FMT( "Region '{}' not found to get region statistics, is it a target of the reservoir solver?\n" + "Available target regions:\n- {}", + regionName, stringutilities::join( setStats.getSubGroupsNames(), "\n- " ) ), + InputError, m_ownerDataContext ); + return *stats; } template< typename Impl > void -StatsAggregatorBase< Impl >::forRegionStatistics( RegionStatsFunc< MeshLevel > const & func ) const +StatsAggregatorBase< Impl >::forRegionStatistics( RegionStatsFunc< MeshLevel & > const & func ) const { for( auto const & path : m_discretizationsPaths ) { MeshLevel & mesh = getMeshLevel( path ); - StatsGroupType & meshRegionsStats = getRegionsStatistics( mesh ); + StatsGroupType & meshLevelStats = getMeshLevelStatistics( mesh ); - func( mesh, meshRegionsStats ); + func( mesh, meshLevelStats ); } } template< typename Impl > void StatsAggregatorBase< Impl >::forRegionStatistics( MeshLevel & mesh, - StatsGroupType & meshRegionsStatistics, - RegionStatsFunc< CellElementRegion > const & func ) const + StatsGroupType & meshLevelStats, + RegionStatsFunc< MeshLevelSet > const & func ) const +{ + meshLevelStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & setStats ) + { + MeshLevelSet meshSet { + /* .mesh = */ mesh, + /* .setName = */ setStats.getTargetName(), + }; + + func( meshSet, setStats ); + } ); +} + +template< typename Impl > +void +StatsAggregatorBase< Impl >::forRegionStatistics( MeshLevelSet const meshSet, + StatsGroupType & setStats, + RegionStatsFunc< CellElementRegion & > const & func ) const { - ElementRegionManager & elemManager = mesh.getElemManager(); - meshRegionsStatistics.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & regionStatistics ) + ElementRegionManager & elemManager = meshSet.mesh.getElemManager(); + setStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & setRegionStats ) { - string_view targetName = regionStatistics.getTargetName(); - CellElementRegion & region = elemManager.getRegion< CellElementRegion >( string( targetName ) ); + string_view regionName = setRegionStats.getTargetName(); + CellElementRegion & region = elemManager.getRegion< CellElementRegion >( string( regionName ) ); - func( region, regionStatistics ); + func( region, setRegionStats ); } ); } template< typename Impl > void -StatsAggregatorBase< Impl >::forRegionStatistics( CellElementRegion & region, - StatsGroupType & regionStatistics, - RegionStatsFunc< CellElementSubRegion > const & func ) const +StatsAggregatorBase< Impl >::forRegionStatistics( CellElementRegion & setRegion, + StatsGroupType & setRegionStats, + RegionStatsFunc< CellElementSubRegion & > const & func ) const { - regionStatistics.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & subRegionStatistics ) + setRegionStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & subRegionStatistics ) { - string_view targetName = subRegionStatistics.getTargetName(); - CellElementSubRegion & subRegion = region.getSubRegion< CellElementSubRegion >( string( targetName ) ); + string_view subRegionName = subRegionStatistics.getTargetName(); + CellElementSubRegion & subRegion = setRegion.getSubRegion< CellElementSubRegion >( string( subRegionName ) ); + func( subRegion, subRegionStatistics ); } ); } @@ -220,51 +356,69 @@ StatsAggregatorBase< Impl >::computeRegionsStatistics( real64 const timeRequest m_warnings.clear(); // computation of sub region stats - forRegionStatistics( [&, timeRequest] ( MeshLevel & mesh, StatsGroupType & meshRegionsStats ) + forRegionStatistics( [&, timeRequest] ( MeshLevel & mesh, StatsGroupType & meshLevelStats ) { forRegionStatistics( mesh, - meshRegionsStats, - [&, timeRequest] ( CellElementRegion & region, StatsGroupType & regionStats ) + meshLevelStats, + [&, timeRequest] ( MeshLevelSet meshSet, StatsGroupType & setStats ) { - forRegionStatistics( region, - regionStats, - [&, timeRequest] ( CellElementSubRegion & subRegion, StatsGroupType & subRegionStats ) + forRegionStatistics( meshSet, + setStats, + [&, timeRequest] ( CellElementRegion & region, StatsGroupType & regionStats ) { - initStats( subRegionStats, timeRequest ); - computeSubRegionRankStats( subRegion, subRegionStats ); + forRegionStatistics( region, + regionStats, + [&, timeRequest] ( CellElementSubRegion & subRegion, StatsGroupType & subRegionStats ) + { + initStats( subRegionStats, timeRequest ); + computeSubRegionRankStats( subRegion, subRegionStats ); + } ); } ); } ); } ); // aggregation of computations from the sub regions - forRegionStatistics( [&, timeRequest] ( MeshLevel & mesh, StatsGroupType & meshRegionsStats ) + forRegionStatistics( [&, timeRequest] ( MeshLevel & mesh, StatsGroupType & meshLevelStats ) { - initStats( meshRegionsStats, timeRequest ); + initStats( meshLevelStats, timeRequest ); forRegionStatistics( mesh, - meshRegionsStats, - [&, timeRequest] ( CellElementRegion & region, StatsGroupType & regionStats ) + meshLevelStats, + [&, timeRequest] ( MeshLevelSet meshSet, StatsGroupType & setStats ) { - initStats( regionStats, timeRequest ); + initStats( setStats, timeRequest ); - forRegionStatistics( region, - regionStats, - [&] ( CellElementSubRegion &, StatsGroupType & subRegionStats ) + forRegionStatistics( meshSet, + setStats, + [&, timeRequest] ( CellElementRegion & region, StatsGroupType & regionStats ) { - aggregateStats( regionStats, subRegionStats ); + initStats( regionStats, timeRequest ); + + forRegionStatistics( region, + regionStats, + [&] ( CellElementSubRegion &, StatsGroupType & subRegionStats ) + { + aggregateStats( regionStats, subRegionStats ); + } ); + + aggregateStats( setStats, regionStats ); - mpiAggregateStats( subRegionStats ); - postAggregateStats( subRegionStats ); + mpiAggregateStats( regionStats ); + postAggregateStats( regionStats ); } ); - aggregateStats( meshRegionsStats, regionStats ); + if( !m_isAnySetsIntersecting ) + aggregateStats( meshLevelStats, setStats ); - mpiAggregateStats( regionStats ); - postAggregateStats( regionStats ); + mpiAggregateStats( setStats ); + postAggregateStats( setStats ); } ); - mpiAggregateStats( meshRegionsStats ); - postAggregateStats( meshRegionsStats ); + if( !m_isAnySetsIntersecting ) + { + mpiAggregateStats( meshLevelStats ); + postAggregateStats( meshLevelStats ); + } } ); m_regionStatsState.m_isDirty = false; @@ -272,48 +426,4 @@ StatsAggregatorBase< Impl >::computeRegionsStatistics( real64 const timeRequest return true; } -template< typename Impl > -MeshLevel & -StatsAggregatorBase< Impl >::getMeshLevel( DiscretizationGroupPath const & path ) const -{ - MeshBody & body = m_meshBodies->getGroup< MeshBody >( path.m_meshBody ); - MeshLevel & mesh = body.getMeshLevel( path.m_meshLevel ); - return mesh; -} - -template< typename Impl > -dataRepository::Group & -StatsAggregatorBase< Impl >::getInstanceStatisticsGroup( MeshLevel & mesh ) const -{ - // considering everything is initialized, or else, crash gracefully - dataRepository::Group & meshStatsGroup = mesh.getGroup( ViewKeys::statisticsString() ); - dataRepository::Group & instanceStatisticsGroup = meshStatsGroup.getGroup( getOwnerName() ); - return instanceStatisticsGroup; -} - -template< typename Impl > -typename StatsAggregatorBase< Impl >::StatsGroupType & -StatsAggregatorBase< Impl >:: -getRegionsStatistics( MeshLevel & mesh ) const -{ - // considering everything is initialized, or else, crash gracefully - dataRepository::Group & instanceStatisticsGroup = getInstanceStatisticsGroup( mesh ); - return instanceStatisticsGroup.getGroup< StatsGroupType >( ViewKeys::regionsStatisticsString() ); -} - -template< typename Impl > -typename StatsAggregatorBase< Impl >::StatsGroupType & -StatsAggregatorBase< Impl >::getRegionStatistics( MeshLevel & mesh, - string_view regionName ) const -{ - StatsGroupType & meshRegionsStats = getRegionsStatistics( mesh ); - StatsGroupType * const stats = meshRegionsStats.template getGroupPointer< StatsGroupType >( string( regionName ) ); - GEOS_THROW_IF( stats == nullptr, - GEOS_FMT( "Region '{}' not found to get region statistics, is it a target of the reservoir solver?\n" - "Available target regions:\n- {}", - regionName, stringutilities::join( meshRegionsStats.getSubGroupsNames(), "\n- " ) ), - InputError, m_ownerDataContext ); - return *stats; -} - } /* namespace geos */ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp index 0e63b2d5b61..ae57c35387f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp @@ -88,10 +88,11 @@ namespace compositionalMultiphaseStatistics RegionStatistics::RegionStatistics( string const & name, dataRepository::Group * const parent, - bool statsOutputEnabled, + string_view setName, + bool dataOutputEnabled, integer const numPhases, integer const numComponents ): - RegionStatisticsBase( name, parent, statsOutputEnabled ), + RegionStatisticsBase( name, parent, setName, dataOutputEnabled ), m_phaseDynamicPoreVolume( numPhases ), m_phaseMass( numPhases ), m_trappedPhaseMass( numPhases ), @@ -105,15 +106,18 @@ RegionStatistics::RegionStatistics( string const & name, CFLStatistics::CFLStatistics( string const & name, dataRepository::Group * const parent, - bool const statsOutputEnabled ): - RegionStatisticsBase( name, parent, statsOutputEnabled ) + bool const dataOutputEnabled ): + RegionStatisticsBase( name, + parent, + "", // for now, CFL numbers are not for given sets + dataOutputEnabled ) { // TODO : registerWrappers to store results in HDF5 (but need repairing of 1D HDF5 outputs) } StatsAggregator::StatsAggregator( DataContext const & ownerDataContext, - bool const statsOutputEnabled ): - Base( ownerDataContext, statsOutputEnabled ), + bool const dataOutputEnabled ): + Base( ownerDataContext, dataOutputEnabled ), m_params() {} @@ -127,20 +131,23 @@ void StatsAggregator::initStatisticsAggregation( dataRepository::Group & meshBod Base::initStatisticsAggregation( meshBodies, solver ); } -void StatsAggregator::enableRegionStatisticsAggregation() +void StatsAggregator::enableRegionStatisticsAggregation( string_array const & setNames ) { auto const registerStats = [=] ( Group & parent, - string const & targetName ) -> RegionStatistics & + string const & targetName, + string_view setName, + bool const dataOutputEnabled ) -> RegionStatistics & { return parent.registerGroup( targetName, std::make_unique< RegionStatistics >( targetName, &parent, - m_statsOutputEnabled, + setName, + dataOutputEnabled, m_numPhases, m_numComponents ) ); }; - Base::enableRegionStatisticsAggregation( registerStats ); + Base::enableRegionStatisticsAggregation( registerStats, setNames ); } void StatsAggregator::enableCFLStatistics() @@ -157,7 +164,7 @@ void StatsAggregator::enableCFLStatistics() statisticsGroup.registerGroup< CFLStatistics >( cflStatsName, std::make_unique< CFLStatistics >( cflStatsName, &statisticsGroup, - m_statsOutputEnabled ) ); + m_dataOutputEnabled ) ); } m_cflStatsState.m_isEnabled = true; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp index 8aed90874f1..f29758dba7d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp @@ -53,8 +53,8 @@ * | | |-> statistics : Group (storage for all stats) * | | |-> "compFlowStats" : Group (storage for this instance stats) * | | | |-> cflStatistics : CFLStatistics - * | | | |-> regionsStatistics : RegionStatistics (mesh-level aggregate) - * | | | |-> all / "myBox" : RegionStatistics (selected set aggregate) + * | | | |-> regionsStatistics : RegionStatistics (selected sets aggregate, mpi reduced) + * | | | |-> "all" / "myBox" : RegionStatistics (set aggregate -> "all" if no set restriction, mpi reduced) * | | | | |-> "Channel" : RegionStatistics (region aggregate, mpi reduced) * | | | | | |-> "cb-0_0_0" : RegionStatistics (sub-region compute read-back) * stats | | | | | |-> "cb-0_0_1" : RegionStatistics (sub-region compute read-back) @@ -173,6 +173,7 @@ class RegionStatistics : public RegionStatisticsBase */ RegionStatistics( string const & targetName, dataRepository::Group * const parent, + string_view setName, bool statsOutputEnabled, integer numPhases, integer numComponents ); @@ -239,7 +240,6 @@ class StatsAggregator : public StatsAggregatorBase< StatsAggregator > * @param solver flow solver object to retrieve: - the simulated regions, - fields for statistics computation. - * @param meshBodies The Group containing the MeshBody objects */ void initStatisticsAggregation( dataRepository::Group & meshBodies, CompositionalMultiphaseBase & solver ); @@ -248,14 +248,14 @@ class StatsAggregator : public StatsAggregatorBase< StatsAggregator > * @brief Enable the computation of region statistics, initialize data structure to collect them. * Register the resulting data wrappers so they will be targeted by TimeHistory output * @note Must be called in or after the "registerDataOnMesh" initialization phase - * @param meshBodies The Group containing the MeshBody objects + * @param setNames The list of mesh element sets to restrict the statistics to. + * If empty, the whole discretization is processed. */ - void enableRegionStatisticsAggregation(); + void enableRegionStatisticsAggregation( string_array const & setNames = string_array() ); /** * @brief Register the results structs & wrappers so they will be targeted by TimeHistory output * @note Must be called in or after the "registerDataOnMesh" initialization phase - * @param meshBodies The Group containing the MeshBody objects */ void enableCFLStatistics(); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp index 3abde88b0ff..87742af13a0 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp @@ -112,15 +112,12 @@ void StatsTask::registerDataOnMesh( Group & meshBodies ) } if( m_computeRegionStatistics ) - m_aggregator->enableRegionStatisticsAggregation(); + m_aggregator->enableRegionStatisticsAggregation( m_setNames ); // if we have to compute CFL numbers later, we need to register additional variables if( m_computeCFLNumbers ) m_aggregator->enableCFLStatistics(); - if( m_setNames.size() > 0 ) - m_aggregator->restrictToSets( m_setNames ); - m_aggregator->forRegionStatistics( [&] ( MeshLevel & mesh, RegionStatistics & ) { prepareLogTableLayouts( mesh.getName() ); @@ -235,12 +232,12 @@ bool StatsTask::execute( real64 const time_n, m_aggregator->computeRegionsStatistics( statsTime ); - m_aggregator->forRegionStatistics( [&] ( MeshLevel & mesh, RegionStatistics & meshRegionsStatistics ) + m_aggregator->forRegionStatistics( [&] ( MeshLevel & mesh, RegionStatistics & meshLevelStats ) { if( m_computeRegionStatistics ) { - outputLogStats( statsTime, mesh, meshRegionsStatistics ); - outputCsvStats( statsTime, mesh, meshRegionsStatistics ); + outputLogStats( statsTime, mesh, meshLevelStats ); + outputCsvStats( statsTime, mesh, meshLevelStats ); } } ); @@ -252,7 +249,7 @@ bool StatsTask::execute( real64 const time_n, void StatsTask::outputLogStats( real64 const statsTime, MeshLevel & mesh, - RegionStatistics & meshRegionsStatistics ) + RegionStatistics & meshLevelStats ) { if( MpiWrapper::commRank() > 0 || !isLogLevelActive< logInfo::Statistics >( this->getLogLevel() ) ) return; @@ -275,11 +272,13 @@ void StatsTask::outputLogStats( real64 const statsTime, tableData.addRow( "Statistics time", merge, merge, statsTime ); // lamda to apply for each region statistics - auto const outputRegionStats = [&] ( string_view targetName, RegionStatistics & stats ) + auto const outputRegionStats = [&] ( string_view targetName, + string_view setName, + RegionStatistics & stats ) { tableData.addSeparator(); tableData.addRow( merge, merge, merge, "" ); - tableData.addRow( merge, merge, merge, targetName ); + tableData.addRow( merge, merge, merge, GEOS_FMT( "{} / {}", setName, targetName ) ); tableData.addSeparator(); tableData.addRow( "statistics", "min", "average", "max" ); @@ -341,12 +340,28 @@ void StatsTask::outputLogStats( real64 const statsTime, }; // apply the lambda for each region and, finally, the mesh summary - outputRegionStats( GEOS_FMT( "Discretization '{}'", mesh.getName() ), meshRegionsStatistics ); + string const meshTitle = GEOS_FMT( "Discretization: '{}'", mesh.getName() ); + string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; + + outputRegionStats( meshTitle, allSetsTitle, meshLevelStats ); - m_aggregator->forRegionStatistics( mesh, meshRegionsStatistics, - [&] ( CellElementRegion & region, RegionStatistics & stats ) + m_aggregator->forRegionStatistics( mesh, meshLevelStats, + [&] ( StatsAggregator::MeshLevelSet meshSet, + RegionStatistics & meshSetStats ) { - outputRegionStats( GEOS_FMT( "Region '{}'", region.getName() ), stats ); + string const setTitle = GEOS_FMT( "Element set: '{}'", meshSet.setName ); + + if( m_aggregator->isRestrictedToSets() ) + outputRegionStats( meshTitle, setTitle, meshLevelStats ); + + m_aggregator->forRegionStatistics( meshSet, meshSetStats, + [&] ( CellElementRegion & region, + RegionStatistics & setRegionStats ) + { + string const regionTitle = GEOS_FMT( "Region: '{}'", region.getName() ); + + outputRegionStats( regionTitle, setTitle, setRegionStats ); + } ); } ); // output to log @@ -355,7 +370,7 @@ void StatsTask::outputLogStats( real64 const statsTime, void StatsTask::outputCsvStats( real64 statsTime, MeshLevel & mesh, - RegionStatistics & meshRegionsStatistics ) + RegionStatistics & meshLevelStats ) { if( MpiWrapper::commRank() > 0 || m_writeCSV == 0 ) return; @@ -371,7 +386,9 @@ void StatsTask::outputCsvStats( real64 statsTime, row.reserve( formatter.getLayout().getTotalLowermostColumnCount() ); // lamda to apply for each region statistics - auto const outputRegionStats = [&] ( string_view targetName, RegionStatistics & stats ) + auto const outputRegionStats = [&] ( string_view targetName, + string_view setName, + RegionStatistics & stats ) { auto addPhaseValues = []( auto & list, auto const & values ) @@ -383,6 +400,7 @@ void StatsTask::outputCsvStats( real64 statsTime, row.clear(); row.insert( row.begin(), { std::to_string( statsTime ), + string( setName ), string( targetName ), std::to_string( stats.m_minPressure ), std::to_string( stats.m_averagePressure ), @@ -406,12 +424,25 @@ void StatsTask::outputCsvStats( real64 statsTime, }; // apply the lambda for each region and, finally, the mesh summary - m_aggregator->forRegionStatistics( mesh, meshRegionsStatistics, - [&] ( CellElementRegion & region, RegionStatistics & stats ) + string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; + + if( !m_aggregator->isRestrictedToSets()) + outputRegionStats( mesh.getName(), allSetsTitle, meshLevelStats ); + + m_aggregator->forRegionStatistics( mesh, meshLevelStats, + [&] ( StatsAggregator::MeshLevelSet meshSet, + RegionStatistics & meshSetStats ) { - outputRegionStats( region.getName(), stats ); + if( m_aggregator->isRestrictedToSets()) + outputRegionStats( meshSet.mesh.getName(), meshSet.setName, meshSetStats ); + + m_aggregator->forRegionStatistics( meshSet, meshSetStats, + [&] ( CellElementRegion & region, + RegionStatistics & setRegionStats ) + { + outputRegionStats( region.getName(), setRegionStats.getSetName(), setRegionStats ); + } ); } ); - outputRegionStats( mesh.getName(), meshRegionsStatistics ); // append to csv file std::ofstream outputFile( getCsvFileName( mesh.getName() ), std::ios_base::app ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.hpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.hpp index 5e019236245..87a4cf32161 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.hpp @@ -108,11 +108,11 @@ class StatsTask : public FieldStatisticsBase< CompositionalMultiphaseBase > void outputLogStats( real64 statsTime, MeshLevel & mesh, - RegionStatistics & meshRegionsStatistics ); + RegionStatistics & meshSetsStatistics ); void outputCsvStats( real64 statsTime, MeshLevel & mesh, - RegionStatistics & meshRegionsStatistics ); + RegionStatistics & meshSetsStatistics ); /// For each discretization (MeshLevel name), table formatter for log output. stdMap< string, std::unique_ptr< TableTextFormatter > > m_logFormatters; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp index ae8582daebe..f06c33268e9 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp @@ -41,27 +41,31 @@ using namespace dataRepository; RegionStatistics::RegionStatistics( string const & name, dataRepository::Group * const parent, - bool const statsOutputEnabled ): - RegionStatisticsBase( name, parent, statsOutputEnabled ) + string_view setName, + bool const dataOutputEnabled ): + RegionStatisticsBase( name, parent, setName, dataOutputEnabled ) {} StatsAggregator::StatsAggregator( DataContext const & ownerDataContext, - bool const statsOutputEnabled ): - Base( ownerDataContext, statsOutputEnabled ) + bool const dataOutputEnabled ): + Base( ownerDataContext, dataOutputEnabled ) {} -void StatsAggregator::enableRegionStatisticsAggregation() +void StatsAggregator::enableRegionStatisticsAggregation( string_array const & setNames ) { auto const registerStats = [=] ( Group & parent, - string const & targetName ) -> RegionStatistics & + string const & targetName, + string_view setName, + bool const dataOutputEnabled ) -> RegionStatistics & { return parent.registerGroup( targetName, std::make_unique< RegionStatistics >( targetName, &parent, - m_statsOutputEnabled ) ); + setName, + dataOutputEnabled ) ); }; - Base::enableRegionStatisticsAggregation( registerStats ); + Base::enableRegionStatisticsAggregation( registerStats, setNames ); } void StatsAggregator::initStats( RegionStatistics & stats, real64 const time ) const diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp index 432fc947b22..6ccd40cff48 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp @@ -64,8 +64,8 @@ * ____ | | * | | |-> statistics : Group (storage for all stats) * | | |-> "flowStats" : Group (storage for this instance stats) - * | | | |-> regionsStatistics : RegionStatistics (mesh-level aggregate) - * | | | |-> all / "myBox" : RegionStatistics (selected set aggregate) + * | | | |-> regionsStatistics : RegionStatistics (selected sets aggregate, mpi reduced) + * | | | |-> "all" / "myBox" : RegionStatistics (set aggregate, "all" if no set restriction, mpi reduced) * | | | | |-> "Channel" : RegionStatistics (region aggregate, mpi reduced) * | | | | | |-> "cb-0_0_0" : RegionStatistics (sub-region compute read-back) * stats | | | | | |-> "cb-0_0_1" : RegionStatistics (sub-region compute read-back) @@ -161,6 +161,7 @@ class RegionStatistics : public RegionStatisticsBase */ RegionStatistics( string const & targetName, dataRepository::Group * const parent, + string_view setName, bool statsOutputEnabled ); RegionStatistics( RegionStatistics && ) = default; @@ -191,9 +192,10 @@ class StatsAggregator : public StatsAggregatorBase< StatsAggregator > * @brief Enable the computation of region statistics, initialize data structure to collect them. * Register the resulting data wrappers so they will be targeted by TimeHistory output * @note Must be called in or after the "registerDataOnMesh" initialization phase - * @param meshBodies The Group containing the MeshBody objects + * @param setNames The list of mesh element sets to restrict the statistics to. + * If empty, the whole discretization is processed. */ - void enableRegionStatisticsAggregation(); + void enableRegionStatisticsAggregation( string_array const & setNames = string_array() ); // template implementations /// @cond DO_NOT_DOCUMENT diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp index b18b8cd0796..afc3215dc57 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp @@ -82,10 +82,7 @@ void StatsTask::registerDataOnMesh( Group & meshBodies ) catalogName(), getDataContext() ) ); } - m_aggregator->enableRegionStatisticsAggregation(); - - if( m_setNames.size() > 0 ) - m_aggregator->restrictToSets( m_setNames ); + m_aggregator->enableRegionStatisticsAggregation( m_setNames ); m_aggregator->forRegionStatistics( [&] ( MeshLevel & mesh, RegionStatistics & ) { @@ -116,6 +113,7 @@ void StatsTask::prepareCsvTableLayouts( string_view meshName ) TableLayout tableLayout( { TableLayout::Column( GEOS_FMT( "Time [{}]", units::getSymbol( units::Unit::Time ))), + TableLayout::Column( "Set" ), // TODO : mention this change in PR description TableLayout::Column( "Region" ), // TODO : mention this change in PR description TableLayout::Column( GEOS_FMT( "Min pressure [{}]", units::getSymbol( units::Unit::Pressure ))), TableLayout::Column( GEOS_FMT( "Average pressure [{}]", units::getSymbol( units::Unit::Pressure )) ), @@ -135,7 +133,6 @@ void StatsTask::prepareCsvTableLayouts( string_view meshName ) // output CSV header std::ofstream outputFile( getCsvFileName( meshName ) ); outputFile << csvFormatter->headerToString(); - GEOS_LOG( GEOS_FMT( "table {} : {}", meshName, csvFormatter->headerToString() ) ); // TODO : remove this log } string StatsTask::getCsvFileName( string_view meshName ) const @@ -156,10 +153,10 @@ bool StatsTask::execute( real64 const time_n, m_aggregator->computeRegionsStatistics( statsTime ); - m_aggregator->forRegionStatistics( [&] ( MeshLevel & mesh, RegionStatistics & meshRegionsStatistics ) + m_aggregator->forRegionStatistics( [&] ( MeshLevel & mesh, RegionStatistics & meshLevelStats ) { - outputLogStats( statsTime, mesh, meshRegionsStatistics ); - outputCsvStats( statsTime, mesh, meshRegionsStatistics ); + outputLogStats( statsTime, mesh, meshLevelStats ); + outputCsvStats( statsTime, mesh, meshLevelStats ); } ); return false; @@ -167,7 +164,7 @@ bool StatsTask::execute( real64 const time_n, void StatsTask::outputLogStats( real64 const statsTime, MeshLevel & mesh, - RegionStatistics & meshRegionsStatistics ) + RegionStatistics & meshLevelStats ) { if( MpiWrapper::commRank() > 0 || !isLogLevelActive< logInfo::Statistics >( this->getLogLevel() ) ) return; @@ -190,11 +187,13 @@ void StatsTask::outputLogStats( real64 const statsTime, tableData.addRow( "Statistics time", merge, merge, statsTime ); // lamda to apply for each region statistics - auto const outputRegionStats = [&] ( string_view targetName, RegionStatistics & stats ) + auto const outputRegionStats = [&] ( string_view targetName, + string_view setName, + RegionStatistics & stats ) { tableData.addSeparator(); tableData.addRow( merge, merge, merge, "" ); - tableData.addRow( merge, merge, merge, targetName ); + tableData.addRow( merge, merge, merge, GEOS_FMT( "{} / {}", setName, targetName ) ); tableData.addSeparator(); tableData.addRow( "statistics", "min", "average", "max" ); @@ -216,13 +215,29 @@ void StatsTask::outputLogStats( real64 const statsTime, "all", CellType::MergeNext, stats.m_totalMass ); }; - // apply the output lambda for the mesh then each regions - outputRegionStats( GEOS_FMT( "Discretization '{}'", mesh.getName() ), meshRegionsStatistics ); + // apply the output lambda for the mesh sets and regions + string const meshTitle = GEOS_FMT( "Discretization: '{}'", mesh.getName() ); + string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; + + outputRegionStats( meshTitle, allSetsTitle, meshLevelStats ); - m_aggregator->forRegionStatistics( mesh, meshRegionsStatistics, - [&] ( CellElementRegion & region, RegionStatistics & stats ) + m_aggregator->forRegionStatistics( mesh, meshLevelStats, + [&] ( StatsAggregator::MeshLevelSet meshSet, + RegionStatistics & meshSetStats ) { - outputRegionStats( GEOS_FMT( "Region '{}'", region.getName() ), stats ); + string const setTitle = GEOS_FMT( "Element set: '{}'", meshSet.setName ); + + if( m_aggregator->isRestrictedToSets() ) + outputRegionStats( meshTitle, setTitle, meshLevelStats ); + + m_aggregator->forRegionStatistics( meshSet, meshSetStats, + [&] ( CellElementRegion & region, + RegionStatistics & setRegionStats ) + { + string const regionTitle = GEOS_FMT( "Region: '{}'", region.getName() ); + + outputRegionStats( regionTitle, setTitle, setRegionStats ); + } ); } ); // output to log @@ -231,7 +246,7 @@ void StatsTask::outputLogStats( real64 const statsTime, void StatsTask::outputCsvStats( real64 statsTime, MeshLevel & mesh, - RegionStatistics & meshRegionsStatistics ) + RegionStatistics & meshLevelStats ) { if( MpiWrapper::commRank() > 0 || m_writeCSV == 0 ) return; @@ -247,11 +262,14 @@ void StatsTask::outputCsvStats( real64 statsTime, row.reserve( formatter.getLayout().getTotalLowermostColumnCount() ); // lamda to apply for each region statistics - auto const outputRegionStats = [&] ( string_view targetName, RegionStatistics & stats ) + auto const outputRegionStats = [&] ( string_view targetName, + string_view setName, + RegionStatistics & stats ) { row.clear(); row.insert( row.begin(), { std::to_string( statsTime ), + string( setName ), string( targetName ), std::to_string( stats.m_minPressure ), std::to_string( stats.m_averagePressure ), @@ -268,13 +286,25 @@ void StatsTask::outputCsvStats( real64 statsTime, tableData.addRow( row ); }; - // apply the output lambda for the mesh then each regions - outputRegionStats( mesh.getName(), meshRegionsStatistics ); + // apply the output lambda for the mesh sets and regions + string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; + + if( !m_aggregator->isRestrictedToSets()) + outputRegionStats( mesh.getName(), allSetsTitle, meshLevelStats ); - m_aggregator->forRegionStatistics( mesh, meshRegionsStatistics, - [&] ( CellElementRegion & region, RegionStatistics & stats ) + m_aggregator->forRegionStatistics( mesh, meshLevelStats, + [&] ( StatsAggregator::MeshLevelSet meshSet, + RegionStatistics & meshSetStats ) { - outputRegionStats( region.getName(), stats ); + if( m_aggregator->isRestrictedToSets()) + outputRegionStats( meshSet.mesh.getName(), meshSet.setName, meshSetStats ); + + m_aggregator->forRegionStatistics( meshSet, meshSetStats, + [&] ( CellElementRegion & region, + RegionStatistics & setRegionStats ) + { + outputRegionStats( region.getName(), setRegionStats.getSetName(), setRegionStats ); + } ); } ); // append to csv file diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.hpp index 498333248aa..c42e45133c4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.hpp @@ -97,11 +97,11 @@ class StatsTask : public FieldStatisticsBase< SinglePhaseBase > void outputLogStats( real64 statsTime, MeshLevel & mesh, - RegionStatistics & meshRegionsStatistics ); + RegionStatistics & meshSetsStatistics ); void outputCsvStats( real64 statsTime, MeshLevel & mesh, - RegionStatistics & meshRegionsStatistics ); + RegionStatistics & meshSetsStatistics ); /// For each discretization (MeshLevel name), table formatter for log output. stdMap< string, std::unique_ptr< TableTextFormatter > > m_logFormatters; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/unitTests/testFlowStatistics.cpp b/src/coreComponents/physicsSolvers/fluidFlow/unitTests/testFlowStatistics.cpp index e61551c70c3..ed50856e940 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/unitTests/testFlowStatistics.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/unitTests/testFlowStatistics.cpp @@ -221,7 +221,7 @@ real64 getTotalFluidMass( ProblemManager & problem, .getMeshBody( 0 ) .getMeshLevel( solver.getDiscretizationName() ); auto const & statsAggregator = statsTask.getStatisticsAggregator(); - auto const & stats = statsAggregator.getRegionsStatistics( mesh ); + auto const & stats = statsAggregator.getMeshLevelStatistics( mesh ); return stats.m_totalMass; } From d30b810f211db2308353128343b6fc77208a49cc Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Tue, 24 Mar 2026 14:42:34 +0100 Subject: [PATCH 14/25] =?UTF-8?q?=F0=9F=9A=A7=20infrastructure=20to=20supp?= =?UTF-8?q?ort=20statistics=20aggregation=20of=20intersecting=20element=20?= =?UTF-8?q?sets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StatisticsAggregatorBase.hpp | 19 +- .../StatisticsAggregatorBaseHelpers.hpp | 162 ++++++++++++------ ...sitionalMultiphaseStatisticsAggregator.hpp | 6 +- .../CompositionalMultiphaseStatisticsTask.cpp | 4 +- .../SinglePhaseStatisticsAggregator.hpp | 6 +- .../fluidFlow/SinglePhaseStatisticsTask.cpp | 4 +- 6 files changed, 136 insertions(+), 65 deletions(-) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index 3b024c44ed6..b514d77fbf5 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -97,6 +97,8 @@ class StatsAggregatorBase using SetType = SortedArray< localIndex >; + using SetViewType = SortedArrayView< localIndex const >; + /** * @brief Standard function signature for any functor that applies on statistics group instances (StatsGroupType) * - param 0: OwnerType &, the group instance containing the data for which we want to aggregate the statistics (MeshLevel, @@ -131,6 +133,8 @@ class StatsAggregatorBase constexpr static char const * setsStatisticsString() { return "setsStatistics"; } /// String for the region statistics group constexpr static char const * regionsStatisticsString() { return "regionsStatistics"; } + /// on-purpose generated compound set name + constexpr static char const * compoundSetNameString() { return "__compound"; } }; /** @@ -188,10 +192,13 @@ class StatsAggregatorBase * @brief Execute the given functor on each set present in the given mesh-level (discretization). * @param mesh the target mesh-level. * @param meshSetsStats the instance mesh-level statistics data structure. + * @param enableCompoundSet if true, the functor will also be applied on the compound set (which + * is an optional internal computation data structure). * @param functor the function to execute. */ void forRegionStatistics( MeshLevel & mesh, StatsGroupType & meshSetsStats, + bool enableCompoundSet, RegionStatsFunc< MeshLevelSet > const & functor ) const; /** @@ -294,8 +301,8 @@ class StatsAggregatorBase string_array m_setNames; /// the regions names in the mesh-level / mesh level string_array m_regionNames; - /// TODO: if m_isAnySetsIntersecting is true, a compound set is needed to compute mesh-level statistics. - // SetType meshLevelSetsCompound; + /// if at least one set intersects with another, a compound set is needed to compute mesh-level statistics. + SetType m_setsCompound; }; /// @see getOwnerName() @@ -339,6 +346,14 @@ class StatsAggregatorBase */ MeshLevel & getMeshLevel( DiscretizationSetPath const & path ) const; + /** + * @return An optional statistics data structure (see StatsGroupType), aggregated from all sets + * over all targeted regions, for the given set in the given mesh-level. + * @param mesh the mesh-level (discretization). + * @throw InputError if no compound set exists, for instance if isSetsCompoundEnabled == false. + */ + StatsGroupType & getCompoundSetStatistics( MeshLevel & mesh ) const; + /** * @brief TODO */ diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp index d0f1cabad0b..3ea0a332405 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp @@ -113,6 +113,7 @@ StatsAggregatorBase< Impl >::initStatisticsAggregation( dataRepository::Group & /* .m_meshLevel = */ mesh.getIndexInParent(), /* .m_setNames = */ string_array( foundSetNames.begin(), foundSetNames.end()), /* .m_regionNames = */ regionNames, + /* .m_setsCompound = */ SetType{}, }; m_discretizationsPaths.emplace_back( path ); } @@ -131,64 +132,89 @@ StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegis if( m_setNames.empty()) m_setNames.emplace( "all" ); - integer regionCount = 0; - integer subRegionCount = 0; + bool regionFound = false; + bool subRegionFound = false; std::set< string > confirmedSets; - for( auto const & path : m_discretizationsPaths ) + for( auto & path : m_discretizationsPaths ) { MeshLevel & mesh = getMeshLevel( path ); ElementRegionManager & elemManager = mesh.getElemManager(); dataRepository::Group & statisticsGroup = getInstanceStatisticsGroup( mesh ); - StatsGroupType & meshStats = registerStatsFunc( statisticsGroup, - ViewKeys::regionsStatisticsString(), - "", - m_dataOutputEnabled ); + StatsGroupType & meshStats = registerStatsFunc( statisticsGroup, ViewKeys::regionsStatisticsString(), + "", m_dataOutputEnabled ); + SetType meshLevelSetsCompound; + bool isAnySetIntersects = false; + // registering all stats Group in the dataRepository for each set for( string const & setName : m_setNames ) { - StatsGroupType & meshSetStats = registerStatsFunc( meshStats, - setName, - setName, - m_dataOutputEnabled ); + StatsGroupType & meshSetStats = registerStatsFunc( meshStats, setName, + setName, m_dataOutputEnabled ); for( size_t regionId = 0; regionId < path.m_regionNames.size(); ++regionId ) { CellElementRegion & region = elemManager.getRegion< CellElementRegion >( path.m_regionNames[regionId] ); - StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, - region.getName(), - setName, - m_dataOutputEnabled ); - ++regionCount; + StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, region.getName(), + setName, m_dataOutputEnabled ); + regionFound = true; region.forElementSubRegions< CellElementSubRegion >( [&] ( CellElementSubRegion & subRegion ) { - registerStatsFunc( setRegionStats, - subRegion.getName(), - setName, - false ); - ++subRegionCount; - - dataRepository::Group const & subRegionSets = subRegion.sets(); - if( subRegionSets.hasWrapper( setName ) && - subRegionSets.getWrapperBase( setName ).size() > 0 ) + registerStatsFunc( setRegionStats, subRegion.getName(), + setName, false ); + subRegionFound = true; + + auto const * const subRegionSetWrapper = subRegion.sets() + .getWrapperPointer< SetType >( setName ); + if( subRegionSetWrapper != nullptr ) { confirmedSets.emplace( setName ); - // meshLevelSetsCompound.insert() TODO + + // Insert the set elements ids in the mesh-level compound. If doubles are found, sets intersect. + SetViewType const & subRegionSet = subRegionSetWrapper->reference(); + localIndex setElemCount = subRegionSet.size(); + localIndex setInsertCount = meshLevelSetsCompound.insert( subRegionSet.begin(), + subRegionSet.end() ); + isAnySetIntersects |= ( setInsertCount != setElemCount); } } ); } } - } - GEOS_ERROR_IF( regionCount == 0 || subRegionCount == 0, - GEOS_FMT( "Missing region for computing statistics:\n- {} regions,\n- {} sub-regions.", - getOwnerName(), regionCount, subRegionCount ), - m_ownerDataContext ); + if( isAnySetIntersects ) + { + // if needed, registering stats Group in the dataRepository for the compound set + string const & setName = ViewKeys::compoundSetNameString(); + StatsGroupType & meshSetStats = registerStatsFunc( meshStats, setName, + setName, false ); + for( size_t regionId = 0; regionId < path.m_regionNames.size(); ++regionId ) + { + CellElementRegion & region = elemManager.getRegion< CellElementRegion >( path.m_regionNames[regionId] ); + StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, region.getName(), + setName, false ); + + region.forElementSubRegions< CellElementSubRegion >( [&] ( CellElementSubRegion & subRegion ) + { + registerStatsFunc( setRegionStats, subRegion.getName(), + setName, false ); + } ); + } + + path.m_setsCompound = std::move( meshLevelSetsCompound ); + } + } m_regionStatsState.m_isEnabled = true; m_regionStatsState.m_isDirty = true; + GEOS_ERROR_IF( regionFound == 0 || subRegionFound == 0, + GEOS_FMT( "Missing region for computing statistics:\n- {} regions,\n- {} sub-regions.", + getOwnerName(), + regionFound ? "found" : "no", + subRegionFound ? "found" : "no" ), + m_ownerDataContext ); + // at this point, m_setNames content is element sets user *requests*: they are the same on every ranks, // but we don't know yet if any of these set is missing or empty (=> confirmedSets). std::set< string > notFoundSets; @@ -239,7 +265,7 @@ typename StatsAggregatorBase< Impl >::StatsGroupType & StatsAggregatorBase< Impl >::getSetStatistics( MeshLevel & mesh, string_view requestedSetName ) const { - // considering everything is initialized, or else, crash gracefully + // considering mesh-level stats structure is initialized, or else, crash gracefully StatsGroupType & meshStats = getMeshLevelStatistics( mesh ); string const setName = string( requestedSetName.empty() ? "all" : requestedSetName ); StatsGroupType * const stats = meshStats.template getGroupPointer< StatsGroupType >( setName ); @@ -250,6 +276,21 @@ StatsAggregatorBase< Impl >::getSetStatistics( MeshLevel & mesh, return *stats; } +template< typename Impl > +typename StatsAggregatorBase< Impl >::StatsGroupType & +StatsAggregatorBase< Impl >::getCompoundSetStatistics( MeshLevel & mesh ) const +{ + // considering mesh-level stats structure is initialized, or else, crash gracefully + StatsGroupType & meshStats = getMeshLevelStatistics( mesh ); + string const setName = ViewKeys::compoundSetNameString(); + StatsGroupType * const stats = meshStats.template getGroupPointer< StatsGroupType >( setName ); + GEOS_THROW_IF( stats == nullptr, + GEOS_FMT( "Compound element set data structure not found ({}), is the aggregator initialized? Was the compound needed?\nRequested element sets:\n- {}", + setName, stringutilities::join( m_setNames, "\n- " ) ), + InputError, m_ownerDataContext ); + return *stats; +} + template< typename Impl > typename StatsAggregatorBase< Impl >::StatsGroupType & StatsAggregatorBase< Impl >::getRegionStatistics( MeshLevel & mesh, @@ -283,16 +324,20 @@ template< typename Impl > void StatsAggregatorBase< Impl >::forRegionStatistics( MeshLevel & mesh, StatsGroupType & meshLevelStats, + bool enableCompoundSet, RegionStatsFunc< MeshLevelSet > const & func ) const { meshLevelStats.template forSubGroups< StatsGroupType >( [&] ( StatsGroupType & setStats ) { - MeshLevelSet meshSet { - /* .mesh = */ mesh, - /* .setName = */ setStats.getTargetName(), - }; + if( enableCompoundSet || setStats.getSetName() != ViewKeys::compoundSetNameString() ) + { + MeshLevelSet meshSet { + /* .mesh = */ mesh, + /* .setName = */ setStats.getTargetName(), + }; - func( meshSet, setStats ); + func( meshSet, setStats ); + } } ); } @@ -355,45 +400,46 @@ StatsAggregatorBase< Impl >::computeRegionsStatistics( real64 const timeRequest m_warnings.clear(); - // computation of sub region stats - forRegionStatistics( [&, timeRequest] ( MeshLevel & mesh, StatsGroupType & meshLevelStats ) + for( auto const & path : m_discretizationsPaths ) { + MeshLevel & mesh = getMeshLevel( path ); + StatsGroupType & meshLevelStats = getMeshLevelStatistics( mesh ); + bool const isSetsCompoundEnabled = !path.m_setsCompound.empty(); + + GEOS_ERROR_IF( isSetsCompoundEnabled, "WIP, NOT IMPLEMENTED" ); + // computation of sub region stats for each selected set + initStats( meshLevelStats, timeRequest ); forRegionStatistics( mesh, meshLevelStats, + true, [&, timeRequest] ( MeshLevelSet meshSet, StatsGroupType & setStats ) { + initStats( setStats, timeRequest ); forRegionStatistics( meshSet, setStats, [&, timeRequest] ( CellElementRegion & region, StatsGroupType & regionStats ) { + initStats( regionStats, timeRequest ); forRegionStatistics( region, regionStats, [&, timeRequest] ( CellElementSubRegion & subRegion, StatsGroupType & subRegionStats ) { initStats( subRegionStats, timeRequest ); - computeSubRegionRankStats( subRegion, subRegionStats ); + computeSubRegionRankStats( subRegion, subRegionStats /*, TODO meshSet.setName*/ ); } ); } ); } ); - } ); - - // aggregation of computations from the sub regions - forRegionStatistics( [&, timeRequest] ( MeshLevel & mesh, StatsGroupType & meshLevelStats ) - { - initStats( meshLevelStats, timeRequest ); + // aggregation of computations from the sub regions forRegionStatistics( mesh, meshLevelStats, + true, [&, timeRequest] ( MeshLevelSet meshSet, StatsGroupType & setStats ) { - initStats( setStats, timeRequest ); - forRegionStatistics( meshSet, setStats, [&, timeRequest] ( CellElementRegion & region, StatsGroupType & regionStats ) { - initStats( regionStats, timeRequest ); - forRegionStatistics( region, regionStats, [&] ( CellElementSubRegion &, StatsGroupType & subRegionStats ) @@ -407,19 +453,21 @@ StatsAggregatorBase< Impl >::computeRegionsStatistics( real64 const timeRequest postAggregateStats( regionStats ); } ); - if( !m_isAnySetsIntersecting ) + // if there is no compound set, we can simply aggregate each set statistics to the mesh-level statistics. + if( !isSetsCompoundEnabled ) aggregateStats( meshLevelStats, setStats ); mpiAggregateStats( setStats ); postAggregateStats( setStats ); } ); - if( !m_isAnySetsIntersecting ) - { - mpiAggregateStats( meshLevelStats ); - postAggregateStats( meshLevelStats ); - } - } ); + // if there is no compound set, we can simply aggregate each set statistics to the mesh-level statistics. + if( isSetsCompoundEnabled ) + aggregateStats( meshLevelStats, getCompoundSetStatistics( mesh ) ); + + mpiAggregateStats( meshLevelStats ); + postAggregateStats( meshLevelStats ); + } m_regionStatsState.m_isDirty = false; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp index f29758dba7d..93f58c09ad9 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp @@ -54,7 +54,11 @@ * | | |-> "compFlowStats" : Group (storage for this instance stats) * | | | |-> cflStatistics : CFLStatistics * | | | |-> regionsStatistics : RegionStatistics (selected sets aggregate, mpi reduced) - * | | | |-> "all" / "myBox" : RegionStatistics (set aggregate -> "all" if no set restriction, mpi reduced) + * | | | |-> "..." : RegionStatistics (set aggregate, mpi reduced) + * | | | | | - all requested sets + * | | | | | - "all" if no set restriction + * | | | | | - "__compound" if a compoud set is needed to compute mesh-level stats + * | | | | | * | | | | |-> "Channel" : RegionStatistics (region aggregate, mpi reduced) * | | | | | |-> "cb-0_0_0" : RegionStatistics (sub-region compute read-back) * stats | | | | | |-> "cb-0_0_1" : RegionStatistics (sub-region compute read-back) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp index 87742af13a0..362c8263a5e 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp @@ -345,7 +345,7 @@ void StatsTask::outputLogStats( real64 const statsTime, outputRegionStats( meshTitle, allSetsTitle, meshLevelStats ); - m_aggregator->forRegionStatistics( mesh, meshLevelStats, + m_aggregator->forRegionStatistics( mesh, meshLevelStats, false, [&] ( StatsAggregator::MeshLevelSet meshSet, RegionStatistics & meshSetStats ) { @@ -429,7 +429,7 @@ void StatsTask::outputCsvStats( real64 statsTime, if( !m_aggregator->isRestrictedToSets()) outputRegionStats( mesh.getName(), allSetsTitle, meshLevelStats ); - m_aggregator->forRegionStatistics( mesh, meshLevelStats, + m_aggregator->forRegionStatistics( mesh, meshLevelStats, false, [&] ( StatsAggregator::MeshLevelSet meshSet, RegionStatistics & meshSetStats ) { diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp index 6ccd40cff48..a8fa171f3d3 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp @@ -65,7 +65,11 @@ * | | |-> statistics : Group (storage for all stats) * | | |-> "flowStats" : Group (storage for this instance stats) * | | | |-> regionsStatistics : RegionStatistics (selected sets aggregate, mpi reduced) - * | | | |-> "all" / "myBox" : RegionStatistics (set aggregate, "all" if no set restriction, mpi reduced) + * | | | |-> "..." : RegionStatistics (set aggregate, mpi reduced) + * | | | | | - all requested sets + * | | | | | - "all" if no set restriction + * | | | | | - "__compound" if a compoud set is needed to compute mesh-level stats + * | | | | | * | | | | |-> "Channel" : RegionStatistics (region aggregate, mpi reduced) * | | | | | |-> "cb-0_0_0" : RegionStatistics (sub-region compute read-back) * stats | | | | | |-> "cb-0_0_1" : RegionStatistics (sub-region compute read-back) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp index afc3215dc57..5dabe68c2c4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp @@ -221,7 +221,7 @@ void StatsTask::outputLogStats( real64 const statsTime, outputRegionStats( meshTitle, allSetsTitle, meshLevelStats ); - m_aggregator->forRegionStatistics( mesh, meshLevelStats, + m_aggregator->forRegionStatistics( mesh, meshLevelStats, false, [&] ( StatsAggregator::MeshLevelSet meshSet, RegionStatistics & meshSetStats ) { @@ -292,7 +292,7 @@ void StatsTask::outputCsvStats( real64 statsTime, if( !m_aggregator->isRestrictedToSets()) outputRegionStats( mesh.getName(), allSetsTitle, meshLevelStats ); - m_aggregator->forRegionStatistics( mesh, meshLevelStats, + m_aggregator->forRegionStatistics( mesh, meshLevelStats, false, [&] ( StatsAggregator::MeshLevelSet meshSet, RegionStatistics & meshSetStats ) { From 18143826d156e079b76f52a457a65dca91b01891 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Tue, 24 Mar 2026 17:30:47 +0100 Subject: [PATCH 15/25] =?UTF-8?q?=E2=9C=A8=20implemented=20statistics=20on?= =?UTF-8?q?=20sets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StatisticsAggregatorBase.hpp | 7 +- .../StatisticsAggregatorBaseHelpers.hpp | 27 ++++---- ...sitionalMultiphaseStatisticsAggregator.cpp | 5 +- ...sitionalMultiphaseStatisticsAggregator.hpp | 4 +- .../SinglePhaseStatisticsAggregator.cpp | 5 +- .../SinglePhaseStatisticsAggregator.hpp | 4 +- .../compositional/StatisticsKernel.hpp | 64 ++++++++++--------- .../kernels/singlePhase/StatisticsKernel.hpp | 7 +- 8 files changed, 67 insertions(+), 56 deletions(-) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index b514d77fbf5..dd8111bdde6 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -380,10 +380,13 @@ class StatsAggregatorBase * @brief Compute the rank-local stats for the given sub-region and store the results in the given stats group. * @param subRegion * @param subRegionStats the stats group instance for the subregion + * @param targetSet * @note Must be implemented for each type that implements this template (CRTP). */ - void computeSubRegionRankStats( CellElementSubRegion & subRegion, StatsGroupType & subRegionStats ) const - { static_cast< Impl const * >(this)->computeSubRegionRankStats( subRegion, subRegionStats ); } + void computeSubRegionRankStats( CellElementSubRegion & subRegion, + StatsGroupType & subRegionStats, + SetType const & targetSet ) const + { static_cast< Impl const * >(this)->computeSubRegionRankStats( subRegion, subRegionStats, targetSet ); } /** * @brief Aggregate all instance statistics with those of another instance on the current rank. diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp index 3ea0a332405..e49cb437765 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp @@ -406,42 +406,37 @@ StatsAggregatorBase< Impl >::computeRegionsStatistics( real64 const timeRequest StatsGroupType & meshLevelStats = getMeshLevelStatistics( mesh ); bool const isSetsCompoundEnabled = !path.m_setsCompound.empty(); - GEOS_ERROR_IF( isSetsCompoundEnabled, "WIP, NOT IMPLEMENTED" ); // computation of sub region stats for each selected set initStats( meshLevelStats, timeRequest ); - forRegionStatistics( mesh, - meshLevelStats, - true, + forRegionStatistics( mesh, meshLevelStats, true, [&, timeRequest] ( MeshLevelSet meshSet, StatsGroupType & setStats ) { initStats( setStats, timeRequest ); - forRegionStatistics( meshSet, - setStats, + forRegionStatistics( meshSet, setStats, [&, timeRequest] ( CellElementRegion & region, StatsGroupType & regionStats ) { initStats( regionStats, timeRequest ); - forRegionStatistics( region, - regionStats, + forRegionStatistics( region, regionStats, [&, timeRequest] ( CellElementSubRegion & subRegion, StatsGroupType & subRegionStats ) { initStats( subRegionStats, timeRequest ); - computeSubRegionRankStats( subRegion, subRegionStats /*, TODO meshSet.setName*/ ); + + SetType const & targetSet = meshSet.setName == ViewKeys::compoundSetNameString() ? + path.m_setsCompound : + subRegion.sets().getReference< SetType >( string( meshSet.setName ) ); + computeSubRegionRankStats( subRegion, subRegionStats, targetSet ); } ); } ); } ); // aggregation of computations from the sub regions - forRegionStatistics( mesh, - meshLevelStats, - true, + forRegionStatistics( mesh, meshLevelStats, true, [&, timeRequest] ( MeshLevelSet meshSet, StatsGroupType & setStats ) { - forRegionStatistics( meshSet, - setStats, + forRegionStatistics( meshSet, setStats, [&, timeRequest] ( CellElementRegion & region, StatsGroupType & regionStats ) { - forRegionStatistics( region, - regionStats, + forRegionStatistics( region, regionStats, [&] ( CellElementSubRegion &, StatsGroupType & subRegionStats ) { aggregateStats( regionStats, subRegionStats ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp index ae57c35387f..12f36745f9f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp @@ -251,7 +251,8 @@ void StatsAggregator::initStats( RegionStatistics & stats, real64 const time ) c } void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegion, - RegionStatistics & subRegionStats ) const + RegionStatistics & subRegionStats, + SetType const & targetSet ) const { arrayView1d< integer const > const elemGhostRank = subRegion.ghostRank(); arrayView1d< real64 const > const volume = subRegion.getElementVolume(); @@ -281,7 +282,7 @@ void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegio isothermalCompositionalMultiphaseBaseKernels:: StatisticsKernel:: - launch< parallelDevicePolicy<> >( subRegion.size(), + launch< parallelDevicePolicy<> >( targetSet.toViewConst(), m_numComponents, m_numPhases, m_params.m_relpermThreshold, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp index 93f58c09ad9..e7ccf11de1d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp @@ -293,7 +293,9 @@ class StatsAggregator : public StatsAggregatorBase< StatsAggregator > /// @cond DO_NOT_DOCUMENT void initStats( RegionStatistics & stats, real64 time ) const; - void computeSubRegionRankStats( CellElementSubRegion & subRegion, RegionStatistics & subRegionStats ) const; + void computeSubRegionRankStats( CellElementSubRegion & subRegion, + RegionStatistics & subRegionStats, + SetType const & targetSet ) const; void aggregateStats( RegionStatistics & stats, RegionStatistics const & other ) const; void mpiAggregateStats( RegionStatistics & stats ) const; void postAggregateStats( RegionStatistics & stats ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp index f06c33268e9..28a6db6ccb7 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp @@ -90,7 +90,8 @@ void StatsAggregator::initStats( RegionStatistics & stats, real64 const time ) c } void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegion, - RegionStatistics & subRegionStats ) const + RegionStatistics & subRegionStats, + SetType const & targetSet ) const { static constexpr string_view solidNamesVK = SinglePhaseBase::viewKeyStruct::solidNamesString(); static constexpr string_view fluidNamesVK = FlowSolverBase::viewKeyStruct::fluidNamesString(); @@ -112,7 +113,7 @@ void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegio SingleFluidBase const & fluid = constitutiveModels.getGroup< SingleFluidBase >( fluidName ); arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const densities = fluid.density(); - singlePhaseBaseKernels::StatisticsKernel::launch( subRegion.size(), + singlePhaseBaseKernels::StatisticsKernel::launch( targetSet.toViewConst(), elemGhostRank, volume, pres, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp index a8fa171f3d3..34c2f60f266 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp @@ -205,7 +205,9 @@ class StatsAggregator : public StatsAggregatorBase< StatsAggregator > /// @cond DO_NOT_DOCUMENT void initStats( RegionStatistics & stats, real64 time ) const; - void computeSubRegionRankStats( CellElementSubRegion & subRegion, RegionStatistics & subRegionStats ) const; + void computeSubRegionRankStats( CellElementSubRegion & subRegion, + RegionStatistics & subRegionStats, + SetType const & targetSet ) const; void aggregateStats( RegionStatistics & stats, RegionStatistics const & other ) const; void mpiAggregateStats( RegionStatistics & stats ) const; void postAggregateStats( RegionStatistics & stats ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/compositional/StatisticsKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/compositional/StatisticsKernel.hpp index 3e98c375613..17a6f1a0385 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/compositional/StatisticsKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/compositional/StatisticsKernel.hpp @@ -51,7 +51,7 @@ struct StatisticsKernel template< typename POLICY > static void - launch( localIndex const size, + launch( SortedArrayView< localIndex const > const & targetSet, integer const numComps, integer const numPhases, real64 const relpermThreshold, @@ -96,36 +96,40 @@ struct StatisticsKernel // using an array of ReduceSum leads to a formal parameter overflow in CUDA. // As a workaround, we use a slice with RAJA::atomicAdd instead - forAll< parallelDevicePolicy<> >( size, [numComps, - numPhases, - relpermThreshold, - elemGhostRank, - volume, - refPorosity, - porosity, - pres, - deltaPres, - temp, - phaseDensity, - phaseVolFrac, - phaseTrappedVolFrac, - phaseRelperm, - phaseCompFraction, - subRegionMinPres, - subRegionAvgPresNumerator, - subRegionMaxPres, - subRegionMinDeltaPres, - subRegionMaxDeltaPres, - subRegionMinTemp, - subRegionAvgTempNumerator, - subRegionMaxTemp, - subRegionTotalUncompactedPoreVol, - phaseDynamicPoreVol, - phaseMass, - trappedPhaseMass, - immobilePhaseMass, - dissolvedComponentMass] GEOS_HOST_DEVICE ( localIndex const ei ) + forAll< parallelDevicePolicy<> >( targetSet.size(), + [targetSet, + numComps, + numPhases, + relpermThreshold, + elemGhostRank, + volume, + refPorosity, + porosity, + pres, + deltaPres, + temp, + phaseDensity, + phaseVolFrac, + phaseTrappedVolFrac, + phaseRelperm, + phaseCompFraction, + subRegionMinPres, + subRegionAvgPresNumerator, + subRegionMaxPres, + subRegionMinDeltaPres, + subRegionMaxDeltaPres, + subRegionMinTemp, + subRegionAvgTempNumerator, + subRegionMaxTemp, + subRegionTotalUncompactedPoreVol, + phaseDynamicPoreVol, + phaseMass, + trappedPhaseMass, + immobilePhaseMass, + dissolvedComponentMass] GEOS_HOST_DEVICE ( localIndex const setElemId ) { + localIndex ei = targetSet[setElemId]; + if( elemGhostRank[ei] >= 0 ) { return; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/StatisticsKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/StatisticsKernel.hpp index 96f8934a2ec..448bb1599b6 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/StatisticsKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/StatisticsKernel.hpp @@ -46,7 +46,7 @@ struct StatisticsKernel } static void - launch( localIndex const size, + launch( SortedArrayView< localIndex const > const & targetSet, arrayView1d< integer const > const & elemGhostRank, arrayView1d< real64 const > const & volume, arrayView1d< real64 const > const & pres, @@ -82,8 +82,11 @@ struct StatisticsKernel RAJA::ReduceSum< parallelDeviceReduce, real64 > subRegionTotalPoreVol( 0.0 ); RAJA::ReduceSum< parallelDeviceReduce, real64 > subRegionTotalMass( 0.0 ); - forAll< parallelDevicePolicy<> >( size, [=] GEOS_HOST_DEVICE ( localIndex const ei ) + forAll< parallelDevicePolicy<> >( targetSet.size(), + [=] GEOS_HOST_DEVICE ( localIndex const setElemId ) { + localIndex ei = targetSet[setElemId]; + if( elemGhostRank[ei] >= 0 ) { return; From d78bae2097885f89c25a62c30b0fd65dabd1d860 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Tue, 24 Mar 2026 18:20:01 +0100 Subject: [PATCH 16/25] =?UTF-8?q?=E2=9C=A8=20smartly=20show=20different=20?= =?UTF-8?q?levels=20of=20stats=20(if=20needed=20/=20requested)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../physicsSolvers/LogLevelsInfo.hpp | 6 +++ .../StatisticsAggregatorBase.hpp | 9 +++- .../CompositionalMultiphaseStatisticsTask.cpp | 54 +++++++++++-------- .../fluidFlow/SinglePhaseStatisticsTask.cpp | 53 ++++++++++-------- 4 files changed, 75 insertions(+), 47 deletions(-) diff --git a/src/coreComponents/physicsSolvers/LogLevelsInfo.hpp b/src/coreComponents/physicsSolvers/LogLevelsInfo.hpp index 73037d8bb04..b65b3d87af8 100644 --- a/src/coreComponents/physicsSolvers/LogLevelsInfo.hpp +++ b/src/coreComponents/physicsSolvers/LogLevelsInfo.hpp @@ -126,6 +126,12 @@ struct Statistics static constexpr std::string_view getDescription() { return "Print statistics"; } }; +struct StatisticsPerRegion +{ + static constexpr int getMinLogLevel() { return 2; } + static constexpr std::string_view getDescription() { return "Print per region statistics"; } +}; + struct SurfaceGenerator { static constexpr int getMinLogLevel() { return 1; } diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index dd8111bdde6..b8b685a6c10 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -269,7 +269,14 @@ class StatsAggregatorBase * false if the statistics are targeted on only one mesh-level-wide set */ bool isRestrictedToSets() - {return m_setNames.empty() || ( m_setNames.size() == 1 && m_setNames.count( "all" ) > 0 ); } + {return !( m_setNames.empty() || ( m_setNames.size() == 1 && m_setNames.count( "all" ) > 0 ) ); } + + /** + * @return true if the region statistics target multiple sets. + * false if the statistics are targeted on only one set + */ + bool isTargetingMultipleSets() + { return m_setNames.size() > 1; } /** * @return the name of the entity that needs the statistics. diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp index 362c8263a5e..50b306f1f37 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp @@ -152,7 +152,8 @@ void StatsTask::prepareLogTableLayouts( string_view meshName ) return; TableLayout const tableLayout = TableLayout() - .setTitle( GEOS_FMT( "{}: mesh {}", getName(), meshName ) ); + .setTitle( GEOS_FMT( "Statistics: {} / Discretization: {}", + getName(), meshName ) ); m_logFormatters.emplace( meshName, std::make_unique< TableTextFormatter >( tableLayout ) ); } @@ -186,7 +187,8 @@ void StatsTask::prepareCsvTableLayouts( string_view meshName ) TableLayout tableLayout( { TableLayout::Column( GEOS_FMT( "Time [{}]", units::getSymbol( units::Unit::Time ))), - TableLayout::Column( "Region" ), // TODO : mention this change in PR description + TableLayout::Column( "Set" ), + TableLayout::Column( "Region" ), TableLayout::Column( GEOS_FMT( "Min pressure [{}]", units::getSymbol( units::Unit::Pressure ))), TableLayout::Column( GEOS_FMT( "Average pressure [{}]", units::getSymbol( units::Unit::Pressure )) ), TableLayout::Column( GEOS_FMT( "Max pressure [{}]", units::getSymbol( units::Unit::Pressure ) ) ), @@ -272,13 +274,12 @@ void StatsTask::outputLogStats( real64 const statsTime, tableData.addRow( "Statistics time", merge, merge, statsTime ); // lamda to apply for each region statistics - auto const outputRegionStats = [&] ( string_view targetName, - string_view setName, + auto const outputRegionStats = [&] ( string_view title, RegionStatistics & stats ) { tableData.addSeparator(); tableData.addRow( merge, merge, merge, "" ); - tableData.addRow( merge, merge, merge, GEOS_FMT( "{} / {}", setName, targetName ) ); + tableData.addRow( merge, merge, merge, title ); tableData.addSeparator(); tableData.addRow( "statistics", "min", "average", "max" ); @@ -339,29 +340,38 @@ void StatsTask::outputLogStats( real64 const statsTime, stringutilities::join( stats.m_componentMass, '\n' ) ); }; - // apply the lambda for each region and, finally, the mesh summary + // apply the output lambda for the mesh sets and regions string const meshTitle = GEOS_FMT( "Discretization: '{}'", mesh.getName() ); - string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; + bool const logPerRegion = isLogLevelActive< logInfo::StatisticsPerRegion >( this->getLogLevel() ); - outputRegionStats( meshTitle, allSetsTitle, meshLevelStats ); + if( m_aggregator->isTargetingMultipleSets() ) + { + string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; + outputRegionStats( GEOS_FMT( "{} / {}", meshTitle, allSetsTitle ), + meshLevelStats ); + } m_aggregator->forRegionStatistics( mesh, meshLevelStats, false, [&] ( StatsAggregator::MeshLevelSet meshSet, RegionStatistics & meshSetStats ) { - string const setTitle = GEOS_FMT( "Element set: '{}'", meshSet.setName ); + string const setTitle = m_aggregator->isRestrictedToSets() ? + GEOS_FMT( "Element set: '{}'", meshSet.setName ) : + "All elements"; - if( m_aggregator->isRestrictedToSets() ) - outputRegionStats( meshTitle, setTitle, meshLevelStats ); + outputRegionStats( GEOS_FMT( "{} / {}", meshTitle, setTitle ), + meshLevelStats ); - m_aggregator->forRegionStatistics( meshSet, meshSetStats, - [&] ( CellElementRegion & region, - RegionStatistics & setRegionStats ) + if( logPerRegion ) { - string const regionTitle = GEOS_FMT( "Region: '{}'", region.getName() ); - - outputRegionStats( regionTitle, setTitle, setRegionStats ); - } ); + m_aggregator->forRegionStatistics( meshSet, meshSetStats, + [&] ( CellElementRegion & region, + RegionStatistics & setRegionStats ) + { + outputRegionStats( GEOS_FMT( "{} / {} / Region: '{}'", meshTitle, setTitle, region.getName() ), + setRegionStats ); + } ); + } } ); // output to log @@ -424,17 +434,15 @@ void StatsTask::outputCsvStats( real64 statsTime, }; // apply the lambda for each region and, finally, the mesh summary - string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; + string_view allSetsTitle = "Selected sets"; - if( !m_aggregator->isRestrictedToSets()) - outputRegionStats( mesh.getName(), allSetsTitle, meshLevelStats ); + outputRegionStats( mesh.getName(), allSetsTitle, meshLevelStats ); m_aggregator->forRegionStatistics( mesh, meshLevelStats, false, [&] ( StatsAggregator::MeshLevelSet meshSet, RegionStatistics & meshSetStats ) { - if( m_aggregator->isRestrictedToSets()) - outputRegionStats( meshSet.mesh.getName(), meshSet.setName, meshSetStats ); + outputRegionStats( meshSet.mesh.getName(), meshSet.setName, meshSetStats ); m_aggregator->forRegionStatistics( meshSet, meshSetStats, [&] ( CellElementRegion & region, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp index 5dabe68c2c4..3bb49bbb51a 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp @@ -98,7 +98,8 @@ void StatsTask::prepareLogTableLayouts( string_view meshName ) return; TableLayout const tableLayout = TableLayout() - .setTitle( GEOS_FMT( "{}: mesh {}", getName(), meshName ) ); + .setTitle( GEOS_FMT( "Statistics: {} / Discretization: {}", + getName(), meshName ) ); m_logFormatters.emplace( meshName, std::make_unique< TableTextFormatter >( tableLayout ) ); } @@ -113,8 +114,8 @@ void StatsTask::prepareCsvTableLayouts( string_view meshName ) TableLayout tableLayout( { TableLayout::Column( GEOS_FMT( "Time [{}]", units::getSymbol( units::Unit::Time ))), - TableLayout::Column( "Set" ), // TODO : mention this change in PR description - TableLayout::Column( "Region" ), // TODO : mention this change in PR description + TableLayout::Column( "Set" ), + TableLayout::Column( "Region" ), TableLayout::Column( GEOS_FMT( "Min pressure [{}]", units::getSymbol( units::Unit::Pressure ))), TableLayout::Column( GEOS_FMT( "Average pressure [{}]", units::getSymbol( units::Unit::Pressure )) ), TableLayout::Column( GEOS_FMT( "Max pressure [{}]", units::getSymbol( units::Unit::Pressure ) ) ), @@ -187,13 +188,12 @@ void StatsTask::outputLogStats( real64 const statsTime, tableData.addRow( "Statistics time", merge, merge, statsTime ); // lamda to apply for each region statistics - auto const outputRegionStats = [&] ( string_view targetName, - string_view setName, + auto const outputRegionStats = [&] ( string_view title, RegionStatistics & stats ) { tableData.addSeparator(); tableData.addRow( merge, merge, merge, "" ); - tableData.addRow( merge, merge, merge, GEOS_FMT( "{} / {}", setName, targetName ) ); + tableData.addRow( merge, merge, merge, title ); tableData.addSeparator(); tableData.addRow( "statistics", "min", "average", "max" ); @@ -217,27 +217,36 @@ void StatsTask::outputLogStats( real64 const statsTime, // apply the output lambda for the mesh sets and regions string const meshTitle = GEOS_FMT( "Discretization: '{}'", mesh.getName() ); - string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; + bool const logPerRegion = isLogLevelActive< logInfo::StatisticsPerRegion >( this->getLogLevel() ); - outputRegionStats( meshTitle, allSetsTitle, meshLevelStats ); + if( m_aggregator->isTargetingMultipleSets() ) + { + string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; + outputRegionStats( GEOS_FMT( "{} / {}", meshTitle, allSetsTitle ), + meshLevelStats ); + } m_aggregator->forRegionStatistics( mesh, meshLevelStats, false, [&] ( StatsAggregator::MeshLevelSet meshSet, RegionStatistics & meshSetStats ) { - string const setTitle = GEOS_FMT( "Element set: '{}'", meshSet.setName ); + string const setTitle = m_aggregator->isRestrictedToSets() ? + GEOS_FMT( "Element set: '{}'", meshSet.setName ) : + "All elements"; - if( m_aggregator->isRestrictedToSets() ) - outputRegionStats( meshTitle, setTitle, meshLevelStats ); + outputRegionStats( GEOS_FMT( "{} / {}", meshTitle, setTitle ), + meshLevelStats ); - m_aggregator->forRegionStatistics( meshSet, meshSetStats, - [&] ( CellElementRegion & region, - RegionStatistics & setRegionStats ) + if( logPerRegion ) { - string const regionTitle = GEOS_FMT( "Region: '{}'", region.getName() ); - - outputRegionStats( regionTitle, setTitle, setRegionStats ); - } ); + m_aggregator->forRegionStatistics( meshSet, meshSetStats, + [&] ( CellElementRegion & region, + RegionStatistics & setRegionStats ) + { + outputRegionStats( GEOS_FMT( "{} / {} / Region: '{}'", meshTitle, setTitle, region.getName() ), + setRegionStats ); + } ); + } } ); // output to log @@ -287,17 +296,15 @@ void StatsTask::outputCsvStats( real64 statsTime, }; // apply the output lambda for the mesh sets and regions - string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; + string_view allSetsTitle = "Selected sets"; - if( !m_aggregator->isRestrictedToSets()) - outputRegionStats( mesh.getName(), allSetsTitle, meshLevelStats ); + outputRegionStats( mesh.getName(), allSetsTitle, meshLevelStats ); m_aggregator->forRegionStatistics( mesh, meshLevelStats, false, [&] ( StatsAggregator::MeshLevelSet meshSet, RegionStatistics & meshSetStats ) { - if( m_aggregator->isRestrictedToSets()) - outputRegionStats( meshSet.mesh.getName(), meshSet.setName, meshSetStats ); + outputRegionStats( meshSet.mesh.getName(), meshSet.setName, meshSetStats ); m_aggregator->forRegionStatistics( meshSet, meshSetStats, [&] ( CellElementRegion & region, From 9778ad7abbb296bfcef17a5d9d192bd5f4374a81 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Wed, 25 Mar 2026 15:41:28 +0100 Subject: [PATCH 17/25] =?UTF-8?q?=E2=9C=A8=20added=20elements=20count=20in?= =?UTF-8?q?=20log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CompositionalMultiphaseStatisticsAggregator.cpp | 8 ++++++++ .../CompositionalMultiphaseStatisticsAggregator.hpp | 3 +++ .../CompositionalMultiphaseStatisticsTask.cpp | 9 ++++++--- .../fluidFlow/SinglePhaseStatisticsAggregator.cpp | 10 +++++++++- .../fluidFlow/SinglePhaseStatisticsAggregator.hpp | 4 ++-- .../fluidFlow/SinglePhaseStatisticsTask.cpp | 9 ++++++--- 6 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp index 12f36745f9f..8dd26fb7984 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp @@ -225,6 +225,8 @@ void StatsAggregator::initStats( RegionStatistics & stats, real64 const time ) c { stats.m_time = time; + stats.m_elemCount = 0; + stats.m_averagePressure = 0.0; stats.m_maxPressure = 0.0; stats.m_minPressure = LvArray::NumericLimits< real64 >::max; @@ -312,12 +314,16 @@ void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegio subRegionStats.m_trappedPhaseMass.toView(), subRegionStats.m_immobilePhaseMass.toView(), subRegionStats.m_componentMass.toView() ); + + subRegionStats.m_elemCount += targetSet.size(); } void StatsAggregator::aggregateStats( RegionStatistics & stats, RegionStatistics const & other ) const { + stats.m_elemCount += other.m_elemCount; + stats.m_averagePressure += other.m_averagePressure; stats.m_minPressure = LvArray::math::min( stats.m_minPressure, other.m_minPressure ); stats.m_maxPressure = LvArray::math::max( stats.m_maxPressure, other.m_maxPressure ); @@ -347,6 +353,8 @@ void StatsAggregator::aggregateStats( RegionStatistics & stats, void StatsAggregator::mpiAggregateStats( RegionStatistics & stats ) const { + stats.m_elemCount = MpiWrapper::sum( stats.m_elemCount ); + stats.m_averagePressure = MpiWrapper::sum( stats.m_averagePressure ); stats.m_minPressure = MpiWrapper::min( stats.m_minPressure ); stats.m_maxPressure = MpiWrapper::max( stats.m_maxPressure ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp index e7ccf11de1d..904e077c1a6 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp @@ -120,6 +120,9 @@ class RegionStatistics : public RegionStatisticsBase { public: + /// Element Count + globalIndex m_elemCount; + /// average region pressure (numerator value before postAggregateCompute()) real64 m_averagePressure; /// minimum region pressure diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp index 50b306f1f37..7df0f20439f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp @@ -347,7 +347,8 @@ void StatsTask::outputLogStats( real64 const statsTime, if( m_aggregator->isTargetingMultipleSets() ) { string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; - outputRegionStats( GEOS_FMT( "{} / {}", meshTitle, allSetsTitle ), + outputRegionStats( GEOS_FMT( "{} / {} ({} elements)", + meshTitle, allSetsTitle, meshLevelStats.m_elemCount ), meshLevelStats ); } @@ -359,7 +360,8 @@ void StatsTask::outputLogStats( real64 const statsTime, GEOS_FMT( "Element set: '{}'", meshSet.setName ) : "All elements"; - outputRegionStats( GEOS_FMT( "{} / {}", meshTitle, setTitle ), + outputRegionStats( GEOS_FMT( "{} / {} ({} elements)", + meshTitle, setTitle, meshSetStats.m_elemCount ), meshLevelStats ); if( logPerRegion ) @@ -368,7 +370,8 @@ void StatsTask::outputLogStats( real64 const statsTime, [&] ( CellElementRegion & region, RegionStatistics & setRegionStats ) { - outputRegionStats( GEOS_FMT( "{} / {} / Region: '{}'", meshTitle, setTitle, region.getName() ), + outputRegionStats( GEOS_FMT( "{} / {} / Region: '{}' ({} elements)", + meshTitle, setTitle, region.getName(), setRegionStats.m_elemCount ), setRegionStats ); } ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp index 28a6db6ccb7..6a16d0394c3 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp @@ -72,6 +72,8 @@ void StatsAggregator::initStats( RegionStatistics & stats, real64 const time ) c { stats.m_time = time; + stats.m_elemCount = 0; + stats.m_averagePressure = 0.0; stats.m_maxPressure = 0.0; stats.m_minPressure = LvArray::NumericLimits< real64 >::max; @@ -91,7 +93,7 @@ void StatsAggregator::initStats( RegionStatistics & stats, real64 const time ) c void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegion, RegionStatistics & subRegionStats, - SetType const & targetSet ) const + SetType const & targetSet ) const { static constexpr string_view solidNamesVK = SinglePhaseBase::viewKeyStruct::solidNamesString(); static constexpr string_view fluidNamesVK = FlowSolverBase::viewKeyStruct::fluidNamesString(); @@ -133,12 +135,16 @@ void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegio subRegionStats.m_totalUncompactedPoreVolume, subRegionStats.m_totalDynamicPoreVolume, subRegionStats.m_totalMass ); + + subRegionStats.m_elemCount += targetSet.size(); } void StatsAggregator::aggregateStats( RegionStatistics & stats, RegionStatistics const & other ) const { + stats.m_elemCount += other.m_elemCount; + stats.m_averagePressure += other.m_averagePressure; stats.m_minPressure = LvArray::math::min( stats.m_minPressure, other.m_minPressure ); stats.m_maxPressure = LvArray::math::max( stats.m_maxPressure, other.m_maxPressure ); @@ -158,6 +164,8 @@ void StatsAggregator::aggregateStats( RegionStatistics & stats, void StatsAggregator::mpiAggregateStats( RegionStatistics & stats ) const { + stats.m_elemCount = MpiWrapper::sum( stats.m_elemCount ); + stats.m_averagePressure = MpiWrapper::sum( stats.m_averagePressure ); stats.m_minPressure = MpiWrapper::min( stats.m_minPressure ); stats.m_maxPressure = MpiWrapper::max( stats.m_maxPressure ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp index 34c2f60f266..700cf63e7fa 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp @@ -122,8 +122,8 @@ class RegionStatistics : public RegionStatisticsBase { public: - /// Time of statistics computation - real64 m_time; + /// Element Count + globalIndex m_elemCount; /// average region pressure (numerator value before postAggregateCompute()) real64 m_averagePressure; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp index 3bb49bbb51a..06e20f178ff 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp @@ -222,7 +222,8 @@ void StatsTask::outputLogStats( real64 const statsTime, if( m_aggregator->isTargetingMultipleSets() ) { string const allSetsTitle = m_aggregator->isRestrictedToSets() ? "Selected sets" : "All elements"; - outputRegionStats( GEOS_FMT( "{} / {}", meshTitle, allSetsTitle ), + outputRegionStats( GEOS_FMT( "{} / {} ({} elements)", + meshTitle, allSetsTitle, meshLevelStats.m_elemCount ), meshLevelStats ); } @@ -234,7 +235,8 @@ void StatsTask::outputLogStats( real64 const statsTime, GEOS_FMT( "Element set: '{}'", meshSet.setName ) : "All elements"; - outputRegionStats( GEOS_FMT( "{} / {}", meshTitle, setTitle ), + outputRegionStats( GEOS_FMT( "{} / {} ({} elements)", + meshTitle, setTitle, meshSetStats.m_elemCount ), meshLevelStats ); if( logPerRegion ) @@ -243,7 +245,8 @@ void StatsTask::outputLogStats( real64 const statsTime, [&] ( CellElementRegion & region, RegionStatistics & setRegionStats ) { - outputRegionStats( GEOS_FMT( "{} / {} / Region: '{}'", meshTitle, setTitle, region.getName() ), + outputRegionStats( GEOS_FMT( "{} / {} / Region: '{}' ({} elements)", + meshTitle, setTitle, region.getName(), setRegionStats.m_elemCount ), setRegionStats ); } ); } From 3265e392f806127c98bc43c4696656699415bbb0 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Wed, 25 Mar 2026 17:39:14 +0100 Subject: [PATCH 18/25] =?UTF-8?q?=F0=9F=90=9B=20wrong=20stats=20shown=20at?= =?UTF-8?q?=20set=20level?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fluidFlow/CompositionalMultiphaseStatisticsTask.cpp | 2 +- .../physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp index 41a17e8d002..aa92704d5df 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp @@ -366,7 +366,7 @@ void StatsTask::outputLogStats( real64 const statsTime, outputRegionStats( GEOS_FMT( "{} / {} ({} elements)", meshTitle, setTitle, meshSetStats.m_elemCount ), - meshLevelStats ); + meshSetStats ); if( logPerRegion ) { diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp index 06e20f178ff..6be880d84d6 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp @@ -237,7 +237,7 @@ void StatsTask::outputLogStats( real64 const statsTime, outputRegionStats( GEOS_FMT( "{} / {} ({} elements)", meshTitle, setTitle, meshSetStats.m_elemCount ), - meshLevelStats ); + meshSetStats ); if( logPerRegion ) { From 5b328baa0a07f7f6dd6f53ba592868139d5b68d5 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Wed, 25 Mar 2026 17:45:24 +0100 Subject: [PATCH 19/25] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20naming=20&=20explain?= =?UTF-8?q?ing=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../physicsSolvers/StatisticsAggregatorBase.hpp | 2 -- .../physicsSolvers/StatisticsAggregatorBaseHelpers.hpp | 7 +++++-- .../CompositionalMultiphaseStatisticsAggregator.hpp | 4 ++-- .../fluidFlow/SinglePhaseStatisticsAggregator.hpp | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index 6b229b529d7..c15a2a00465 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -131,8 +131,6 @@ class StatsAggregatorBase constexpr static char const * statisticsString() { return "statistics"; } /// String for the region statistics group constexpr static char const * setsStatisticsString() { return "setsStatistics"; } - /// String for the region statistics group - constexpr static char const * regionsStatisticsString() { return "regionsStatistics"; } /// on-purpose generated compound set name constexpr static char const * compoundSetNameString() { return "__compound"; } }; diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp index e49cb437765..141e9ac7b7c 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp @@ -141,7 +141,7 @@ StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegis MeshLevel & mesh = getMeshLevel( path ); ElementRegionManager & elemManager = mesh.getElemManager(); dataRepository::Group & statisticsGroup = getInstanceStatisticsGroup( mesh ); - StatsGroupType & meshStats = registerStatsFunc( statisticsGroup, ViewKeys::regionsStatisticsString(), + StatsGroupType & meshStats = registerStatsFunc( statisticsGroup, ViewKeys::setsStatisticsString(), "", m_dataOutputEnabled ); SetType meshLevelSetsCompound; bool isAnySetIntersects = false; @@ -257,7 +257,7 @@ getMeshLevelStatistics( MeshLevel & mesh ) const { // considering everything is initialized, or else, crash gracefully dataRepository::Group & instanceStatisticsGroup = getInstanceStatisticsGroup( mesh ); - return instanceStatisticsGroup.getGroup< StatsGroupType >( ViewKeys::regionsStatisticsString() ); + return instanceStatisticsGroup.getGroup< StatsGroupType >( ViewKeys::setsStatisticsString() ); } template< typename Impl > @@ -440,6 +440,9 @@ StatsAggregatorBase< Impl >::computeRegionsStatistics( real64 const timeRequest [&] ( CellElementSubRegion &, StatsGroupType & subRegionStats ) { aggregateStats( regionStats, subRegionStats ); + // sub-region stats finalization is disabled, it does not seem useful + // mpiAggregateStats( subRegionStats ); + // postAggregateStats( subRegionStats ); } ); aggregateStats( setStats, regionStats ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp index 904e077c1a6..ce84e5db6d6 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.hpp @@ -53,10 +53,10 @@ * | | |-> statistics : Group (storage for all stats) * | | |-> "compFlowStats" : Group (storage for this instance stats) * | | | |-> cflStatistics : CFLStatistics - * | | | |-> regionsStatistics : RegionStatistics (selected sets aggregate, mpi reduced) + * | | | |-> setsStatistics : RegionStatistics (selected sets aggregate, mpi reduced) * | | | |-> "..." : RegionStatistics (set aggregate, mpi reduced) * | | | | | - all requested sets - * | | | | | - "all" if no set restriction + * | | | | | - "all" if no set restriction or if requested * | | | | | - "__compound" if a compoud set is needed to compute mesh-level stats * | | | | | * | | | | |-> "Channel" : RegionStatistics (region aggregate, mpi reduced) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp index 700cf63e7fa..7c8e1a120f6 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.hpp @@ -64,10 +64,10 @@ * ____ | | * | | |-> statistics : Group (storage for all stats) * | | |-> "flowStats" : Group (storage for this instance stats) - * | | | |-> regionsStatistics : RegionStatistics (selected sets aggregate, mpi reduced) + * | | | |-> setsStatistics : RegionStatistics (selected sets aggregate, mpi reduced) * | | | |-> "..." : RegionStatistics (set aggregate, mpi reduced) * | | | | | - all requested sets - * | | | | | - "all" if no set restriction + * | | | | | - "all" if no set restriction or if requested * | | | | | - "__compound" if a compoud set is needed to compute mesh-level stats * | | | | | * | | | | |-> "Channel" : RegionStatistics (region aggregate, mpi reduced) From da67ced59b554baec4ebf32fc61ce11de7061e9a Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Wed, 25 Mar 2026 17:53:10 +0100 Subject: [PATCH 20/25] =?UTF-8?q?=E2=9C=85=20add=20sets=20statistics=20to?= =?UTF-8?q?=20integrated=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../simpleCo2InjTutorial_base.xml | 26 +++++++++++++------ .../simpleCo2InjTutorial_smoke.xml | 15 +++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml b/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml index 2dd5fda291d..644c0be6256 100644 --- a/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml +++ b/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml @@ -191,28 +191,38 @@ + + + - + + - + + - + setNames="{domainBottom, domainTop}" + logLevel="1" + writeCSV="1"/> + + + + + + @@ -87,6 +97,11 @@ cycleFrequency="10" target="/Tasks/domainFlowStats"/> + + Date: Thu, 26 Mar 2026 10:08:58 +0100 Subject: [PATCH 21/25] =?UTF-8?q?=E2=9A=B0=EF=B8=8F=20useless=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StatisticsAggregatorBaseHelpers.hpp | 1 - ...sitionalMultiphaseStatisticsAggregator.cpp | 56 ------------------- 2 files changed, 57 deletions(-) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp index 141e9ac7b7c..c9d5226c7bb 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp @@ -69,7 +69,6 @@ StatsAggregatorBase< Impl >::getMeshLevelPartialSetNames( MeshLevel const & mesh dataRepository::Group const & sets = subRegion.sets(); sets.forWrappers< SetType >( [&] ( dataRepository::Wrapper< SetType > const & set ) { - // if( set.getName() != "all" ) // TODO: is it useful? foundSetNames.emplace( set.getName() ); } ); } ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp index cb97f68bceb..166cbb96c8e 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp @@ -13,62 +13,6 @@ * ------------------------------------------------------------------------------------------------------------ */ -/** - * @file CompositionalMultiphaseStatistics.cpp - * @details Region statistics data is stored as follow: - - * Problem : ProblemManager - * |-> domain : DomainPartition - * |-> MeshBodies : Group - * |-> cartesianMesh : MeshBody - * |-> meshLevels : Group - * |-> Level0 : MeshLevel - * | |-> nodeManager : NodeManager - * | | |-> sets : Group - * | | | * all : Wrapper< index array > - * | | | * xneg : Wrapper< index array > - * | | [...] (other element sets) - * | | - * | |-> ElementRegions : ElementRegionManager - * | | |-> Channel : CellElementRegion - * | | | |-> cb-0_0_0 : CellElementSubRegion - * | | | | | * pressure : Wrapper< real64 array > - * | | | | | * temperature : Wrapper< real64 array > - * | | | | [...] (other fields) - * | | | | - * | | | |-> cb-0_0_1 : CellElementSubRegion - * | | | | | * pressure : Wrapper< real64 array > - * | | | | | * temperature : Wrapper< real64 array > - * | | | | [...] (other fields) - * | | | | - * | | | [...] (other sub-regions) - * | | | - * | | |-> Barrier : CellElementRegion - * | | |-> cb-1_0_0 : CellElementSubRegion - * | | |-> cb-1_0_1 : CellElementSubRegion - * | | [...] (other sub-regions) - * | | - * | [...] (other element managers) - * ____ | | - * | | |-> statistics : Group (storage for all stats) - * | | |-> compFlowStats : Group (storage for this instance stats) - * | | | |-> cflStatistics : CFLStatistics - * | | | |-> regionsStatistics : RegionStatistics (aggregate) - * | | | |-> Channel : RegionStatistics (aggregate, mpi reduced) - * | | | | |-> cb-0_0_0 : RegionStatistics (compute read-back) - * stats | | | | |-> cb-0_0_1 : RegionStatistics (compute read-back) - * data -> | | | | [...] (other sub-regions stats) - * | | | | - * | | | |-> Barrier : RegionStatistics (aggregate, mpi reduced) - * | | | |-> cb-1_0_0 : RegionStatistics (compute read-back) - * | | | |-> cb-1_0_1 : RegionStatistics (compute read-back) - * | | | [...] (other sub-regions stats) - * | | | - * |___ | [...] (other stats storages) - * | - * [...] (other discretizations) - */ - #include "CompositionalMultiphaseStatisticsAggregator.hpp" #include "physicsSolvers/StatisticsAggregatorBaseHelpers.hpp" From bb3e106cea905c1e208baf2b1c3694c903c8c5ff Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Thu, 26 Mar 2026 10:47:35 +0100 Subject: [PATCH 22/25] =?UTF-8?q?=F0=9F=93=9D=20docs=20adjustments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fluidFlow/CompositionalMultiphaseStatisticsTask.cpp | 5 +++-- .../physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp index aa92704d5df..70b33bbf81e 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsTask.cpp @@ -44,9 +44,10 @@ StatsTask::StatsTask( string const & name, Group * const parent ): setInputFlag( InputFlags::OPTIONAL ). setSizedFromParent( 0 ). setDescription( "Optional targeted mesh element set(s) for which the statistics will be restricted. " - "A set can be be defined by a 'Geometry' component, or correspond to imported sets in case of an external mesh. " + "A set can be be defined by a 'Geometry' component, or correspond to an imported index set " + "of mesh elements in case of an external mesh. " "If empty, all mesh regions will be processed. " - "Be aware that only the regions that are computed by the solver will be taken into account." ); + "Be aware that only the regions that are processed by the solver will be taken into account." ); registerWrapper( viewKeyStruct::computeCFLNumbersString(), &m_computeCFLNumbers ). setApplyDefaultValue( 0 ). diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp index 6be880d84d6..e3b70d8350b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsTask.cpp @@ -38,9 +38,10 @@ StatsTask::StatsTask( const string & name, Group * const parent ): setInputFlag( InputFlags::OPTIONAL ). setSizedFromParent( 0 ). setDescription( "Optional targeted mesh element set(s) for which the statistics will be restricted. " - "A set can be be defined by a 'Geometry' component, or correspond to imported sets in case of an external mesh. " + "A set can be be defined by a 'Geometry' component, or correspond to an imported index set " + "of mesh elements in case of an external mesh. " "If empty, all mesh regions will be processed. " - "Be aware that only the regions that are computed by the solver will be taken into account." ); + "Be aware that only the regions that are processed by the solver will be taken into account." ); addLogLevel< logInfo::Statistics >(); } From 3c16d9c3a71b9f0dd67aa8e20ea02dfd40b14e5a Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Thu, 26 Mar 2026 11:29:31 +0100 Subject: [PATCH 23/25] =?UTF-8?q?=F0=9F=90=9B=20fix=20set=20stats=20exampl?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../simpleCo2InjTutorial_base.xml | 4 ++-- .../simpleCo2InjTutorial_smoke.xml | 13 ++++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml b/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml index 644c0be6256..bcf4ce1e61b 100644 --- a/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml +++ b/inputFiles/compositionalMultiphaseWell/simpleCo2InjTutorial_base.xml @@ -206,7 +206,7 @@ + target="/Tasks/domainAndInjectorFlowStats"/> - - + target="/Tasks/domainTopAndDownFlowStats"/> From 2a0e64e5e1a5219e0d94c8f4c7e230041c8b353a Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Thu, 26 Mar 2026 11:29:48 +0100 Subject: [PATCH 24/25] =?UTF-8?q?=F0=9F=93=A6=20schema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/coreComponents/schema/schema.xsd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreComponents/schema/schema.xsd b/src/coreComponents/schema/schema.xsd index 8f3fed44503..45ffe698e1c 100644 --- a/src/coreComponents/schema/schema.xsd +++ b/src/coreComponents/schema/schema.xsd @@ -6324,7 +6324,7 @@ Information output from lower logLevels is added with the desired log level - + @@ -6544,7 +6544,7 @@ Information output from lower logLevels is added with the desired log level 1 - Print statistics--> - + From c8544d17bd4cbb6af96a94a2a5aedbbe7f855896 Mon Sep 17 00:00:00 2001 From: MelReyCG Date: Wed, 1 Apr 2026 16:58:11 +0200 Subject: [PATCH 25/25] =?UTF-8?q?=F0=9F=90=9B=20correct=20way=20to=20take?= =?UTF-8?q?=20into=20account=20compound=20sets=20over=20MPI=20ranks=20(+?= =?UTF-8?q?=20minor=20string=5Fview=20replacement)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StatisticsAggregatorBase.hpp | 18 +++-- .../StatisticsAggregatorBaseHelpers.hpp | 68 ++++++++++++------- ...sitionalMultiphaseStatisticsAggregator.cpp | 3 +- .../SinglePhaseStatisticsAggregator.cpp | 3 +- .../compositional/StatisticsKernel.hpp | 13 +++- .../kernels/singlePhase/StatisticsKernel.hpp | 9 ++- 6 files changed, 75 insertions(+), 39 deletions(-) diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp index c15a2a00465..b4ad6706ff4 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBase.hpp @@ -128,11 +128,11 @@ class StatsAggregatorBase struct ViewKeys { /// String for the mesh-level statistics group - constexpr static char const * statisticsString() { return "statistics"; } + constexpr static string_view statisticsString() { return "statistics"; } /// String for the region statistics group - constexpr static char const * setsStatisticsString() { return "setsStatistics"; } + constexpr static string_view setsStatisticsString() { return "setsStatistics"; } /// on-purpose generated compound set name - constexpr static char const * compoundSetNameString() { return "__compound"; } + constexpr static string_view compoundSetNameString() { return "__compound"; } }; /** @@ -296,6 +296,8 @@ class StatsAggregatorBase bool m_isDirty = false; }; + using SetsCompound = stdMap< string, stdMap< string, SetType > >; + struct DiscretizationSetPath { /// The id of the mesh body in the "meshBodies" Group @@ -306,8 +308,8 @@ class StatsAggregatorBase string_array m_setNames; /// the regions names in the mesh-level / mesh level string_array m_regionNames; - /// if at least one set intersects with another, a compound set is needed to compute mesh-level statistics. - SetType m_setsCompound; + /// if at least one set intersects with another, a compound of (local element index) set is needed to compute the mesh-level statistics. + SetsCompound m_setsCompound; }; /// @see getOwnerName() @@ -359,6 +361,12 @@ class StatsAggregatorBase */ StatsGroupType & getCompoundSetStatistics( MeshLevel & mesh ) const; + /** + * @return true if the RegionStatistics is processed from a compound set of other instances. + * @param stats a statistics data structure + */ + bool isCompoundSetStatistics( StatsGroupType const & stats ) const; + /** * @brief TODO */ diff --git a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp index c9d5226c7bb..3ff6a1e7b95 100644 --- a/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp +++ b/src/coreComponents/physicsSolvers/StatisticsAggregatorBaseHelpers.hpp @@ -89,9 +89,9 @@ StatsAggregatorBase< Impl >::initStatisticsAggregation( dataRepository::Group & string_array const & regionNames ) { // getting the container of all requesters statistics groups (can be already initialized) - dataRepository::Group * meshStatsGroup = mesh.getGroupPointer( ViewKeys::statisticsString() ); + dataRepository::Group * meshStatsGroup = mesh.getGroupPointer( string( ViewKeys::statisticsString()) ); if( meshStatsGroup == nullptr ) - meshStatsGroup = &mesh.registerGroup( ViewKeys::statisticsString() ); + meshStatsGroup = &mesh.registerGroup( string( ViewKeys::statisticsString() ) ); // registering the container of instance statistics groups (must be unique for this instance) string const & ownerName = getOwnerName(); @@ -112,7 +112,7 @@ StatsAggregatorBase< Impl >::initStatisticsAggregation( dataRepository::Group & /* .m_meshLevel = */ mesh.getIndexInParent(), /* .m_setNames = */ string_array( foundSetNames.begin(), foundSetNames.end()), /* .m_regionNames = */ regionNames, - /* .m_setsCompound = */ SetType{}, + /* .m_setsCompound = */ {}, }; m_discretizationsPaths.emplace_back( path ); } @@ -140,9 +140,9 @@ StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegis MeshLevel & mesh = getMeshLevel( path ); ElementRegionManager & elemManager = mesh.getElemManager(); dataRepository::Group & statisticsGroup = getInstanceStatisticsGroup( mesh ); - StatsGroupType & meshStats = registerStatsFunc( statisticsGroup, ViewKeys::setsStatisticsString(), + StatsGroupType & meshStats = registerStatsFunc( statisticsGroup, string( ViewKeys::setsStatisticsString() ), "", m_dataOutputEnabled ); - SetType meshLevelSetsCompound; + SetsCompound meshSetsCompounds; bool isAnySetIntersects = false; // registering all stats Group in the dataRepository for each set @@ -156,6 +156,7 @@ StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegis CellElementRegion & region = elemManager.getRegion< CellElementRegion >( path.m_regionNames[regionId] ); StatsGroupType & setRegionStats = registerStatsFunc( meshSetStats, region.getName(), setName, m_dataOutputEnabled ); + stdMap< string, SetType > & regionSetsCompounds = meshSetsCompounds.get_inserted( region.getName() ); regionFound = true; region.forElementSubRegions< CellElementSubRegion >( [&] ( CellElementSubRegion & subRegion ) @@ -164,28 +165,35 @@ StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegis setName, false ); subRegionFound = true; - auto const * const subRegionSetWrapper = subRegion.sets() - .getWrapperPointer< SetType >( setName ); + auto const * const subRegionSetWrapper = subRegion.sets().getWrapperPointer< SetType >( setName ); if( subRegionSetWrapper != nullptr ) { confirmedSets.emplace( setName ); // Insert the set elements ids in the mesh-level compound. If doubles are found, sets intersect. SetViewType const & subRegionSet = subRegionSetWrapper->reference(); - localIndex setElemCount = subRegionSet.size(); - localIndex setInsertCount = meshLevelSetsCompound.insert( subRegionSet.begin(), - subRegionSet.end() ); - isAnySetIntersects |= ( setInsertCount != setElemCount); + arrayView1d< integer const > const elemGhostRank = subRegion.ghostRank(); + SetType & subRegionSetsCompound = regionSetsCompounds.get_inserted( subRegion.getName() ); + for( localIndex setIter = 0; setIter < subRegionSet.size(); ++setIter ) + { + localIndex elemId = subRegionSet[setIter]; + if( elemGhostRank[elemId] < 0 ) + { + if( !subRegionSetsCompound.insert( elemId ) ) + isAnySetIntersects = true; + } + } } } ); } } + // if needed, registering stats Group in the dataRepository for the compound set + isAnySetIntersects = (bool)( MpiWrapper::max( (unsigned char)( isAnySetIntersects ) ) ); if( isAnySetIntersects ) { - // if needed, registering stats Group in the dataRepository for the compound set - string const & setName = ViewKeys::compoundSetNameString(); - StatsGroupType & meshSetStats = registerStatsFunc( meshStats, setName, + string_view setName = ViewKeys::compoundSetNameString(); + StatsGroupType & meshSetStats = registerStatsFunc( meshStats, string( setName ), setName, false ); for( size_t regionId = 0; regionId < path.m_regionNames.size(); ++regionId ) { @@ -197,10 +205,14 @@ StatsAggregatorBase< Impl >::enableRegionStatisticsAggregation( RegionStatsRegis { registerStatsFunc( setRegionStats, subRegion.getName(), setName, false ); + + path.m_setsCompound + .get_inserted( region.getName()) + .insert( meshSetsCompounds + .at( region.getName() ) + .extract( subRegion.getName() ) ); } ); } - - path.m_setsCompound = std::move( meshLevelSetsCompound ); } } @@ -244,7 +256,7 @@ dataRepository::Group & StatsAggregatorBase< Impl >::getInstanceStatisticsGroup( MeshLevel & mesh ) const { // considering everything is initialized, or else, crash gracefully - dataRepository::Group & meshStatsGroup = mesh.getGroup( ViewKeys::statisticsString() ); + dataRepository::Group & meshStatsGroup = mesh.getGroup( string( ViewKeys::statisticsString() ) ); dataRepository::Group & instanceStatisticsGroup = meshStatsGroup.getGroup( getOwnerName() ); return instanceStatisticsGroup; } @@ -256,7 +268,7 @@ getMeshLevelStatistics( MeshLevel & mesh ) const { // considering everything is initialized, or else, crash gracefully dataRepository::Group & instanceStatisticsGroup = getInstanceStatisticsGroup( mesh ); - return instanceStatisticsGroup.getGroup< StatsGroupType >( ViewKeys::setsStatisticsString() ); + return instanceStatisticsGroup.getGroup< StatsGroupType >( string( ViewKeys::setsStatisticsString()) ); } template< typename Impl > @@ -281,7 +293,7 @@ StatsAggregatorBase< Impl >::getCompoundSetStatistics( MeshLevel & mesh ) const { // considering mesh-level stats structure is initialized, or else, crash gracefully StatsGroupType & meshStats = getMeshLevelStatistics( mesh ); - string const setName = ViewKeys::compoundSetNameString(); + string const setName = string( ViewKeys::compoundSetNameString() ); StatsGroupType * const stats = meshStats.template getGroupPointer< StatsGroupType >( setName ); GEOS_THROW_IF( stats == nullptr, GEOS_FMT( "Compound element set data structure not found ({}), is the aggregator initialized? Was the compound needed?\nRequested element sets:\n- {}", @@ -290,6 +302,13 @@ StatsAggregatorBase< Impl >::getCompoundSetStatistics( MeshLevel & mesh ) const return *stats; } +template< typename Impl > +bool +StatsAggregatorBase< Impl >::isCompoundSetStatistics( StatsGroupType const & setStats ) const +{ + return setStats.getSetName() == ViewKeys::compoundSetNameString(); +} + template< typename Impl > typename StatsAggregatorBase< Impl >::StatsGroupType & StatsAggregatorBase< Impl >::getRegionStatistics( MeshLevel & mesh, @@ -421,7 +440,7 @@ StatsAggregatorBase< Impl >::computeRegionsStatistics( real64 const timeRequest initStats( subRegionStats, timeRequest ); SetType const & targetSet = meshSet.setName == ViewKeys::compoundSetNameString() ? - path.m_setsCompound : + path.m_setsCompound.at( region.getName() ).at( subRegion.getName() ) : subRegion.sets().getReference< SetType >( string( meshSet.setName ) ); computeSubRegionRankStats( subRegion, subRegionStats, targetSet ); } ); @@ -451,17 +470,16 @@ StatsAggregatorBase< Impl >::computeRegionsStatistics( real64 const timeRequest } ); // if there is no compound set, we can simply aggregate each set statistics to the mesh-level statistics. - if( !isSetsCompoundEnabled ) + // if there is one, we will only take into account the statistics of the compound set. + if( !isSetsCompoundEnabled || isCompoundSetStatistics( setStats ) ) + { aggregateStats( meshLevelStats, setStats ); + } mpiAggregateStats( setStats ); postAggregateStats( setStats ); } ); - // if there is no compound set, we can simply aggregate each set statistics to the mesh-level statistics. - if( isSetsCompoundEnabled ) - aggregateStats( meshLevelStats, getCompoundSetStatistics( mesh ) ); - mpiAggregateStats( meshLevelStats ); postAggregateStats( meshLevelStats ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp index 166cbb96c8e..17fc9191292 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseStatisticsAggregator.cpp @@ -244,6 +244,7 @@ void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegio phaseVolFrac, phaseTrappedVolFrac, phaseRelperm, + subRegionStats.m_elemCount, subRegionStats.m_minPressure, subRegionStats.m_averagePressure, subRegionStats.m_maxPressure, @@ -258,8 +259,6 @@ void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegio subRegionStats.m_trappedPhaseMass.toView(), subRegionStats.m_immobilePhaseMass.toView(), subRegionStats.m_componentMass.toView() ); - - subRegionStats.m_elemCount += targetSet.size(); } void StatsAggregator::aggregateStats( RegionStatistics & stats, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp index 4bf5e211e39..d75c477be8b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseStatisticsAggregator.cpp @@ -124,6 +124,7 @@ void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegio refPorosity, porosity, densities, + subRegionStats.m_elemCount, subRegionStats.m_minPressure, subRegionStats.m_averagePressure, subRegionStats.m_maxPressure, @@ -135,8 +136,6 @@ void StatsAggregator::computeSubRegionRankStats( CellElementSubRegion & subRegio subRegionStats.m_totalUncompactedPoreVolume, subRegionStats.m_totalDynamicPoreVolume, subRegionStats.m_totalMass ); - - subRegionStats.m_elemCount += targetSet.size(); } void StatsAggregator::aggregateStats( RegionStatistics & stats, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/compositional/StatisticsKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/compositional/StatisticsKernel.hpp index 17a6f1a0385..65f53880255 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/compositional/StatisticsKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/compositional/StatisticsKernel.hpp @@ -67,6 +67,7 @@ struct StatisticsKernel arrayView2d< real64 const, compflow::USD_PHASE > const & phaseVolFrac, arrayView3d< real64 const, constitutive::relperm::USD_RELPERM > const & phaseTrappedVolFrac, arrayView3d< real64 const, constitutive::relperm::USD_RELPERM > const & phaseRelperm, + globalIndex & elemCount, real64 & minPres, real64 & avgPresNumerator, real64 & maxPres, @@ -82,6 +83,7 @@ struct StatisticsKernel arrayView1d< real64 > const & immobilePhaseMass, arrayView2d< real64 > const & dissolvedComponentMass ) { + RAJA::ReduceSum< parallelDeviceReduce, localIndex > subRegionElemCount( 0 ); RAJA::ReduceMin< parallelDeviceReduce, real64 > subRegionMinPres( LvArray::NumericLimits< real64 >::max ); RAJA::ReduceSum< parallelDeviceReduce, real64 > subRegionAvgPresNumerator( 0.0 ); RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPres( -LvArray::NumericLimits< real64 >::max ); @@ -113,6 +115,7 @@ struct StatisticsKernel phaseTrappedVolFrac, phaseRelperm, phaseCompFraction, + subRegionElemCount, subRegionMinPres, subRegionAvgPresNumerator, subRegionMaxPres, @@ -131,14 +134,14 @@ struct StatisticsKernel localIndex ei = targetSet[setElemId]; if( elemGhostRank[ei] >= 0 ) - { return; - } // To match our "reference", we have to use reference porosity here, not the actual porosity when we compute averages real64 const uncompactedPoreVol = volume[ei] * refPorosity[ei]; real64 const dynamicPoreVol = volume[ei] * porosity[ei][0]; - + + subRegionElemCount += 1; + subRegionMinPres.min( pres[ei] ); subRegionAvgPresNumerator += uncompactedPoreVol * pres[ei]; subRegionMaxPres.max( pres[ei] ); @@ -172,14 +175,18 @@ struct StatisticsKernel } ); + elemCount = globalIndex( subRegionElemCount.get() ); + minPres = subRegionMinPres.get(); avgPresNumerator = subRegionAvgPresNumerator.get(); maxPres = subRegionMaxPres.get(); minDeltaPres = subRegionMinDeltaPres.get(); maxDeltaPres = subRegionMaxDeltaPres.get(); + minTemp = subRegionMinTemp.get(); avgTempNumerator = subRegionAvgTempNumerator.get(); maxTemp = subRegionMaxTemp.get(); + totalUncompactedPoreVol = subRegionTotalUncompactedPoreVol.get(); // dummy loop to bring data back to the CPU diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/StatisticsKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/StatisticsKernel.hpp index 448bb1599b6..3cdca4b6e43 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/StatisticsKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/StatisticsKernel.hpp @@ -55,6 +55,7 @@ struct StatisticsKernel arrayView1d< real64 const > const & refPorosity, arrayView2d< real64 const > const & porosity, arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const & density, + globalIndex & elemCount, real64 & minPres, real64 & avgPresNumerator, real64 & maxPres, @@ -67,6 +68,8 @@ struct StatisticsKernel real64 & totalPoreVol, real64 & totalMass ) { + RAJA::ReduceSum< parallelDeviceReduce, localIndex > subRegionElemCount( 0 ); + RAJA::ReduceMin< parallelDeviceReduce, real64 > subRegionMinPres( LvArray::NumericLimits< real64 >::max ); RAJA::ReduceSum< parallelDeviceReduce, real64 > subRegionAvgPresNumerator( 0.0 ); RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPres( -LvArray::NumericLimits< real64 >::max ); @@ -88,14 +91,14 @@ struct StatisticsKernel localIndex ei = targetSet[setElemId]; if( elemGhostRank[ei] >= 0 ) - { return; - } // To match our "reference", we have to use reference porosity here, not the actual porosity when we compute averages real64 const uncompactedPoreVol = volume[ei] * refPorosity[ei]; real64 const dynamicPoreVol = volume[ei] * porosity[ei][0]; + subRegionElemCount += 1; + subRegionMinPres.min( pres[ei] ); subRegionAvgPresNumerator += uncompactedPoreVol * pres[ei]; subRegionMaxPres.max( pres[ei] ); @@ -112,6 +115,8 @@ struct StatisticsKernel subRegionTotalMass += dynamicPoreVol * density[ei][0]; } ); + elemCount = globalIndex( subRegionElemCount.get() ); + minPres = subRegionMinPres.get(); avgPresNumerator = subRegionAvgPresNumerator.get(); maxPres = subRegionMaxPres.get();