diff --git a/inputFiles/lagrangianContactMechanics/TFrac_smoke.xml b/inputFiles/lagrangianContactMechanics/TFrac_smoke.xml index cd3543f0806..d16decc713b 100644 --- a/inputFiles/lagrangianContactMechanics/TFrac_smoke.xml +++ b/inputFiles/lagrangianContactMechanics/TFrac_smoke.xml @@ -17,14 +17,6 @@ - - - - - - - - - - - diff --git a/inputFiles/wavePropagation/acous3D_Q3_firstOrder_fs_smoke.xml b/inputFiles/wavePropagation/acous3D_Q3_firstOrder_fs_smoke.xml index 12182662931..0b7e9505c18 100644 --- a/inputFiles/wavePropagation/acous3D_Q3_firstOrder_fs_smoke.xml +++ b/inputFiles/wavePropagation/acous3D_Q3_firstOrder_fs_smoke.xml @@ -25,13 +25,4 @@ xMin="{ -0.01, -0.01, 100.99 }" xMax="{ 101.01, 101.01, 101.01 }"/> - - - - - diff --git a/inputFiles/wavePropagation/acous3D_abc_fs_smoke.xml b/inputFiles/wavePropagation/acous3D_abc_fs_smoke.xml index 662545c6496..e55e5c839cc 100644 --- a/inputFiles/wavePropagation/acous3D_abc_fs_smoke.xml +++ b/inputFiles/wavePropagation/acous3D_abc_fs_smoke.xml @@ -25,13 +25,4 @@ xMin="{ -0.01, -0.01, 100.99 }" xMax="{ 101.01, 101.01, 101.01 }"/> - - - - - diff --git a/inputFiles/wavePropagation/acous3D_firstOrder_fs_smoke.xml b/inputFiles/wavePropagation/acous3D_firstOrder_fs_smoke.xml index 6796a8c1bc9..32d063c95a4 100644 --- a/inputFiles/wavePropagation/acous3D_firstOrder_fs_smoke.xml +++ b/inputFiles/wavePropagation/acous3D_firstOrder_fs_smoke.xml @@ -25,13 +25,4 @@ xMin="{ -0.01, -0.01, 100.99 }" xMax="{ 101.01, 101.01, 101.01 }"/> - - - - - diff --git a/inputFiles/wavePropagation/acous3D_vti_smoke.xml b/inputFiles/wavePropagation/acous3D_vti_smoke.xml index 4305ac12319..bd5d931fe43 100644 --- a/inputFiles/wavePropagation/acous3D_vti_smoke.xml +++ b/inputFiles/wavePropagation/acous3D_vti_smoke.xml @@ -165,14 +165,6 @@ fieldName="acousticVelocity" scale="1500" setNames="{ all }"/> - - - sizedFromParent() ) { string const wrapperName = makeFieldName( this->getName(), wrapper.first ); - parent.registerWrapper( wrapper.second->clone( wrapperName, parent ) ). + parent.registerWrapper( wrapper.second->clone( wrapperName, parent ), true ). setRestartFlags( RestartFlags::NO_WRITE ); } } @@ -64,7 +64,7 @@ void ConstitutiveBase::allocateConstitutiveData( Group & parent, localIndex cons if( wrapper.second->sizedFromParent() ) { string const wrapperName = makeFieldName( this->getName(), wrapper.first ); - parent.registerWrapper( wrapper.second->clone( wrapperName, parent ) ). + parent.registerWrapper( wrapper.second->clone( wrapperName, parent ), true ). setRestartFlags( RestartFlags::NO_WRITE ); } } diff --git a/src/coreComponents/constitutive/ConstitutiveManager.cpp b/src/coreComponents/constitutive/ConstitutiveManager.cpp index fd7a0ac1b82..8731bb28796 100644 --- a/src/coreComponents/constitutive/ConstitutiveManager.cpp +++ b/src/coreComponents/constitutive/ConstitutiveManager.cpp @@ -41,12 +41,14 @@ ConstitutiveManager::~ConstitutiveManager() {} -Group * ConstitutiveManager::createChild( string const & childKey, string const & childName ) +Group * ConstitutiveManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< ConstitutiveBase > material = ConstitutiveBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return ®isterGroup< ConstitutiveBase >( childName, std::move( material ) ); + return ®isterGroup< ConstitutiveBase >( std::move( material ), allowExistence ); } @@ -92,7 +94,7 @@ ConstitutiveManager::hangConstitutiveRelation( string const & constitutiveRelati numConstitutivePointsPerParentIndex ) ); ConstitutiveBase & - materialGroup = constitutiveGroup->registerGroup< ConstitutiveBase >( constitutiveRelationInstanceName, std::move( material ) ); + materialGroup = constitutiveGroup->registerGroup< ConstitutiveBase >( std::move( material ) ); materialGroup.setSizedFromParent( 1 ); materialGroup.resize( constitutiveGroup->size() ); diff --git a/src/coreComponents/constitutive/ConstitutiveManager.hpp b/src/coreComponents/constitutive/ConstitutiveManager.hpp index 2e3d7cec562..232744ccc35 100644 --- a/src/coreComponents/constitutive/ConstitutiveManager.hpp +++ b/src/coreComponents/constitutive/ConstitutiveManager.hpp @@ -48,7 +48,9 @@ class ConstitutiveManager : public dataRepository::Group ConstitutiveManager( string const & name, Group * const parent ); - virtual Group * createChild( string const & childKey, string const & childName ) override final; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override final; /// This function is used to expand any catalogs in the data structure virtual void expandObjectCatalogs() override; diff --git a/src/coreComponents/constitutive/fluid/multifluid/MultiFluidBase.cpp b/src/coreComponents/constitutive/fluid/multifluid/MultiFluidBase.cpp index 3deec40ea99..c8f7f039585 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/MultiFluidBase.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/MultiFluidBase.cpp @@ -37,16 +37,16 @@ MultiFluidBase::MultiFluidBase( string const & name, Group * const parent ) registerWrapper( viewKeyStruct::componentNamesString(), &m_componentNames ). setInputFlag( InputFlags::OPTIONAL ). - setDescription( "List of component names" ); + setDescription( "List of fluid components (e.g. CH4, H2O, C5H12)" ); registerWrapper( viewKeyStruct::componentMolarWeightString(), &m_componentMolarWeight ). setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Component molar weights" ); + setDescription( "Molar weights of components" ); registerWrapper( viewKeyStruct::phaseNamesString(), &m_phaseNames ). setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ). setInputFlag( InputFlags::OPTIONAL ). - setDescription( "List of fluid phases" ); + setDescription( "List of fluid phases (e.g. gas, water, oil)" ); registerWrapper( viewKeyStruct::useMassString(), &m_useMass ). setRestartFlags( RestartFlags::NO_WRITE ). diff --git a/src/coreComponents/constitutive/fluid/multifluid/constant/InvariantImmiscibleFluid.cpp b/src/coreComponents/constitutive/fluid/multifluid/constant/InvariantImmiscibleFluid.cpp index a676abdf379..51ace961a13 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/constant/InvariantImmiscibleFluid.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/constant/InvariantImmiscibleFluid.cpp @@ -11,18 +11,14 @@ InvariantImmiscibleFluid::InvariantImmiscibleFluid( string const & name, Group * : MultiFluidBase( name, parent ) { // Override input flags for mandatory options + getWrapperBase( viewKeyStruct::componentNamesString() ) + .setInputFlag( dataRepository::InputFlags::REQUIRED ); - registerWrapper( viewKeyStruct::componentNamesString(), &m_componentNames ) - .setInputFlag( dataRepository::InputFlags::REQUIRED ) - .setDescription( "List of fluid components (e.g. CH4, H2O, C5H12)" ); - - registerWrapper( viewKeyStruct::phaseNamesString(), &m_phaseNames ) - .setInputFlag( dataRepository::InputFlags::REQUIRED ) - .setDescription( "List of fluid phases (e.g. gas, water, oil)" ); + getWrapperBase( viewKeyStruct::componentMolarWeightString() ) + .setInputFlag( dataRepository::InputFlags::REQUIRED ); - registerWrapper( viewKeyStruct::componentMolarWeightString(), &m_componentMolarWeight ) - .setInputFlag( dataRepository::InputFlags::REQUIRED ) - .setDescription( "Molar weights of components" ); + getWrapperBase( viewKeyStruct::phaseNamesString() ) + .setInputFlag( dataRepository::InputFlags::REQUIRED ); // Densities: constant phase densities registerWrapper( "densities", &m_densities ) diff --git a/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp b/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp index 72cfec6501c..2cc42f544f8 100644 --- a/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp +++ b/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp @@ -516,7 +516,7 @@ void FluidModelTest< FLUID_TYPE, NUM_COMP, NUM_PHASE >::createFunctionManager() // TODO: FunctionManager is a singleton string const name = FunctionManager::catalogName(); auto functionManager = std::make_unique< FunctionManager >( name, &m_parent ); - m_parent.registerGroup( name, std::move( functionManager ) ); + m_parent.registerGroup( std::move( functionManager ) ); } } // namespace testing diff --git a/src/coreComponents/dataRepository/Group.cpp b/src/coreComponents/dataRepository/Group.cpp index 94a78c3e512..c6160a8f075 100644 --- a/src/coreComponents/dataRepository/Group.cpp +++ b/src/coreComponents/dataRepository/Group.cpp @@ -67,13 +67,6 @@ Group::CatalogInterface::CatalogType & Group::getCatalog() return catalog; } -WrapperBase & Group::registerWrapper( std::unique_ptr< WrapperBase > wrapper ) -{ - // Extract `wrapperName` first to prevent from UB call order in the `insert` call. - string const wrapperName = wrapper->getName(); - return *m_wrappers.insert( wrapperName, wrapper.release(), true ); -} - void Group::deregisterWrapper( string const & name ) { GEOS_ERROR_IF( !hasWrapper( name ), @@ -275,12 +268,10 @@ void Group::registerDataOnMeshRecursive( Group & meshBodies ) } } -Group * Group::createChild( string const & childKey, string const & childName ) +Group * Group::createChild( string const & childKey, string const & childName, bool const allowExistence ) { GEOS_LOG_RANK_0( "Adding Object " << childKey<<" named "<< childName<<" from Group::Catalog." ); - return ®isterGroup( childName, - CatalogInterface::factory( childKey, getDataContext(), - childName, this ) ); + return ®isterGroup( CatalogInterface::factory( childKey, getDataContext(), childName, this ), allowExistence ); } void Group::printDataHierarchy( integer const indent ) const @@ -749,5 +740,67 @@ stdVector< string > Group::getWrappersNames() const return wrappersNames; } +void Group::insertWrapper( std::unique_ptr< WrapperBase > wrapper, bool const allowExistence ) +{ + GEOS_ERROR_IF( !wrapper, "Trying to register a nullptr WrapperBase with " << getPath() ); + + // Extract data from wrapper in case it's free'd in insert. + string const name = wrapper->getName(); + std::type_info const & typeId = wrapper->getTypeId(); + string const typeName = wrapper->getRTTypeName(); + + WrapperBase * const ret = m_wrappers.insert( name, wrapper.release(), true ); + + if( ret == nullptr ) + { + WrapperBase const & existingWrapper = getWrapperBase( name ); + bool const typesMatch = existingWrapper.getTypeId() == typeId; + + if( !allowExistence || !typesMatch ) + { + string registrationString = ""; + if( !existingWrapper.getRegisteringObjects().empty() ) + { + std::ostringstream oss; + oss << ". The existing wrapper was registered by the following:"; + for( string const & object : existingWrapper.getRegisteringObjects() ) + { + oss << "\n\t" << object; + } + + registrationString = oss.str(); + } + + GEOS_ERROR( "Tried registering a wrapper \"" << name << "\" of type " << typeName << + " with \"" << getPath() << "\"\n" << + "A wrapper of this name already exists with type " << existingWrapper.getRTTypeName() << registrationString ); + } + } +} + +void Group::insertGroup( Group * const newObject, bool const takeOwnership, bool const allowExistence ) +{ + GEOS_ERROR_IF( !newObject, "Attempting to register a nullptr as a subgroup of " << getPath() ); + + newObject->m_parent = this; + + // Extract data from newObject in case it's free'd in insert. + string const name = newObject->getName(); + std::type_info const & typeId = typeid( *newObject ); + + Group * const ret = m_subGroups.insert( name, newObject, takeOwnership ); + + if( ret == nullptr ) + { + Group const & existingGroup = getGroup( name ); + std::type_info const & existingTypeId = typeid( existingGroup ); + + GEOS_ERROR_IF( !allowExistence || (existingTypeId != typeId), + "Tried registering a Group \"" << name << "\" of type " << rtTypes::getTypeName( typeId ) << + " with \"" << getPath() << "\"\n" << + "A Group of this name already exists with type " << rtTypes::getTypeName( existingTypeId ) ); + } +} + } /* end namespace dataRepository */ } /* end namespace geos */ diff --git a/src/coreComponents/dataRepository/Group.hpp b/src/coreComponents/dataRepository/Group.hpp index 0aef2b787b8..34359bdbfda 100644 --- a/src/coreComponents/dataRepository/Group.hpp +++ b/src/coreComponents/dataRepository/Group.hpp @@ -69,10 +69,10 @@ class Group public: //START_SPHINX_INCLUDE_01 /// The template specialization of MappedVector to use for the collection of sub-Group objects. - using subGroupMap = MappedVector< Group, Group *, keyType, indexType >; + using subGroupMap = MappedVector< Group, keyType, indexType >; /// The template specialization of MappedVector to use for the collection wrappers objects. - using wrapperMap = MappedVector< WrapperBase, WrapperBase *, keyType, indexType >; + using wrapperMap = MappedVector< WrapperBase, keyType, indexType >; //END_SPHINX_INCLUDE_01 /** @@ -190,61 +190,70 @@ class Group * @brief Register a new Group as a sub-group of current Group. * * @tparam T The type of the Group to add/register. This should be a type that derives from Group. - * @param[in] name The name of the group to use as a string key. - * @param[in] newObject A unique_ptr to the object that is being registered. - * @return A pointer to the newly registered Group. + * @param[in] newObject A unique_ptr to the object that is being registered under `newObject->getName()`. + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. + * @return A pointer to the newly registered Group. * * Registers a Group or class derived from Group as a subgroup of this Group and takes ownership. */ template< typename T = Group > - T & registerGroup( string const & name, std::unique_ptr< T > newObject ) + T & registerGroup( std::unique_ptr< T > newObject, bool const allowExistence=false ) { - newObject->m_parent = this; - return dynamicCast< T & >( *m_subGroups.insert( name, newObject.release(), true ) ); + GEOS_ERROR_IF( !newObject, "Trying to register a nullptr." ); + string const name = newObject->getName(); + insertGroup( newObject.release(), true, allowExistence ); + return getGroup< T >( name ); } /** - * @brief @copybrief registerGroup(string const &,std::unique_ptr) + * @brief Register a new Group as a sub-group of current Group. * * @tparam T The type of the Group to add/register. This should be a type that derives from Group. - * @param[in] name The name of the group to use as a string key. - * @param[in] newObject A unique_ptr to the object that is being registered. - * @return A pointer to the newly registered Group. + * @param[in] newObject A pointer to the object that is being registered under `newObject->getName()`. + * @return A reference to the newly registered Group. * * Registers a Group or class derived from Group as a subgroup of this Group but does not take ownership. */ template< typename T = Group > - T & registerGroup( string const & name, T * newObject ) - { return dynamicCast< T & >( *m_subGroups.insert( name, newObject, false ) ); } - + std::enable_if_t< std::is_base_of_v< Group, T >, T & > + registerGroup( T * newObject ) + { + GEOS_ERROR_IF( !newObject, "Trying to register a nullptr." ); + string const name = newObject->getName(); + insertGroup( newObject, false ); + return getGroup< T >( name ); + } /** - * @brief @copybrief registerGroup(string const &,std::unique_ptr) + * @brief Register a new Group as a sub-group of current Group. * * @tparam T The type of the Group to add/register. This should be a type that derives from Group. * @param[in] name The name of the group to use as a string key. - * @return A pointer to the newly registered Group. + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. + * @return A reference to the newly registered Group. * * Creates and registers a Group or class derived from Group as a subgroup of this Group. */ template< typename T = Group > - T & registerGroup( string const & name ) - { return registerGroup< T >( name, std::make_unique< T >( name, this ) ); } + T & registerGroup( string const & name, bool const allowExistence=false ) + { return registerGroup< T >( std::make_unique< T >( name, this ), allowExistence ); } /** - * @brief @copybrief registerGroup(string const &,std::unique_ptr) + * @brief Register a new Group as a sub-group of current Group. * * @tparam T The type of the Group to add/register. This should be a type that derives from Group. * @param keyIndex A KeyIndexT object that will be used to specify the name of * the new group. The index of the KeyIndex will also be set. - * @return A pointer to the newly registered Group, or @c nullptr if no group was registered. + * @return A reference to the newly registered Group, or @c nullptr if no group was registered. * * Creates and registers a Group or class derived from Group as a subgroup of this Group. */ template< typename T = Group > T & registerGroup( subGroupMap::KeyIndex const & keyIndex ) { - T & rval = registerGroup< T >( keyIndex.key(), std::make_unique< T >( keyIndex.key(), this ) ); + T & rval = registerGroup< T >( std::make_unique< T >( keyIndex.key(), this ) ); keyIndex.setIndex( m_subGroups.getIndex( keyIndex.key() ) ); return rval; } @@ -257,13 +266,15 @@ class Group /** * @brief Creates a new sub-Group using the ObjectCatalog functionality. - * @param[in] childKey The name of the new object type's key in the - * ObjectCatalog. - * @param[in] childName The name of the new object in the collection of - * sub-Groups. + * @param[in] childKey The name of the new object type's key in the ObjectCatalog. + * @param[in] childName The name of the new object in the collection of sub-Groups. + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return A pointer to the new Group created by this function. */ - virtual Group * createChild( string const & childKey, string const & childName ); + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ); ///@} @@ -805,6 +816,22 @@ class Group */ ///@{ + /** + * @brief Register a new Wrapper. + * @param[in] newObject The wrapper to register + * @param[in] allowExistence Whether to error out if an wrapper already exists with the same name, + * or return the existing object. + * @return A reference to the newly registered Wrapper + */ + WrapperBase & registerWrapper( std::unique_ptr< WrapperBase > newObject, + bool const allowExistence=false ) + { + GEOS_ERROR_IF( !newObject, "Trying to register a nullptr." ); + string const name = newObject->getName(); + insertWrapper( std::move( newObject ), allowExistence ); + return getWrapperBase( name ); + } + /** * @brief Create and register a Wrapper around a new object. * @tparam T The type of the object allocated. @@ -812,32 +839,42 @@ class Group * @param[in] name the name of the wrapper to use as a string key * @param[out] rkey a pointer to a index type that will be filled with the new * Wrapper index in this Group + * @param[in] allowExistence Whether to error out if an wrapper already exists with the same name, + * or return the existing object. * @return A reference to the newly registered/created Wrapper */ template< typename T, typename TBASE=T > Wrapper< TBASE > & registerWrapper( string const & name, - wrapperMap::KeyIndex::index_type * const rkey = nullptr ); + wrapperMap::KeyIndex::index_type * const rkey = nullptr, + bool const allowExistence=false ); /** - * @copybrief registerWrapper(string const &,wrapperMap::KeyIndex::index_type * const) + * @brief Register a new Wrapper. * @tparam T the type of the wrapped object * @tparam TBASE the base type to cast the returned wrapper to * @param[in] viewKey The KeyIndex that contains the name of the new Wrapper. + * @param[in] allowExistence Whether to error out if an wrapper already exists with the same name, + * or return the existing object. * @return A reference to the newly registered/created Wrapper */ template< typename T, typename TBASE=T > - Wrapper< TBASE > & registerWrapper( Group::wrapperMap::KeyIndex const & viewKey ); + Wrapper< TBASE > & registerWrapper( Group::wrapperMap::KeyIndex const & viewKey, + bool const allowExistence=false ); /** * @brief Register a Wrapper around a given object and take ownership. * @tparam T the type of the wrapped object * @param[in] name the name of the wrapper to use as a string key * @param[in] newObject an owning pointer to the object that is being registered + * @param[in] allowExistence Whether to error out if an wrapper already exists with the same name, + * or return the existing object. * @return A reference to the newly registered/created Wrapper * @note Not intended to register a @p WrapperBase instance. Use dedicated member function instead. */ template< typename T > - Wrapper< T > & registerWrapper( string const & name, std::unique_ptr< T > newObject ); + Wrapper< T > & registerWrapper( string const & name, + std::unique_ptr< T > newObject, + bool const allowExistence=false ); /** * @brief Register a Wrapper around an existing object, does not take ownership of the object. @@ -848,15 +885,7 @@ class Group * @note Not intended to register a @p WrapperBase instance. Use dedicated member function instead. */ template< typename T > - Wrapper< T > & registerWrapper( string const & name, - T * newObject ); - - /** - * @brief Register and take ownership of an existing Wrapper. - * @param wrapper A pointer to the an existing wrapper. - * @return An un-typed pointer to the newly registered/created wrapper - */ - WrapperBase & registerWrapper( std::unique_ptr< WrapperBase > wrapper ); + Wrapper< T > & registerWrapper( string const & name, T * newObject ); /** * @brief Removes a Wrapper from this group. @@ -1605,6 +1634,21 @@ class Group bool onDevice, parallelDeviceEvents & events ) const; + /** + * @brief Insert into m_wrappers. + * @param[in] wrapper The wrapper to insert with the key wrapper->getName(). + * @param[in] allowExistence Whether to error out if an wrapper already exists with the same name. + */ + void insertWrapper( std::unique_ptr< WrapperBase > wrapper, bool const allowExistence=false ); + + /** + * @brief Insert into m_subGroups. + * @param[in] newObject The group to insert with the key newObject->getName(). + * @param[in] takeOwnership Whether to take ownership of newObject or not. + * @param[in] allowExistence Whether to error out if an wrapper already exists with the same name. + */ + void insertGroup( Group * const newObject, bool const takeOwnership, bool const allowExistence=false ); + //START_SPHINX_INCLUDE_02 /// The parent Group that contains "this" Group in its "sub-Group" collection. Group * m_parent = nullptr; @@ -1667,12 +1711,12 @@ using ViewKey = Group::wrapperMap::KeyIndex; /// @cond DO_NOT_DOCUMENT template< typename T, typename TBASE > Wrapper< TBASE > & Group::registerWrapper( string const & name, - ViewKey::index_type * const rkey ) + ViewKey::index_type * const rkey, + bool const allowExistence ) { std::unique_ptr< TBASE > newObj = std::make_unique< T >(); - m_wrappers.insert( name, - new Wrapper< TBASE >( name, *this, std::move( newObj ) ), - true ); + + insertWrapper( std::make_unique< Wrapper< TBASE > >( name, *this, std::move( newObj ) ), allowExistence ); if( rkey != nullptr ) { @@ -1682,17 +1726,17 @@ Wrapper< TBASE > & Group::registerWrapper( string const & name, Wrapper< TBASE > & rval = getWrapper< TBASE >( name ); if( rval.sizedFromParent() == 1 ) { - rval.resize( size()); + rval.resize( size() ); } return rval; } /// @endcond template< typename T, typename TBASE > -Wrapper< TBASE > & Group::registerWrapper( ViewKey const & viewKey ) +Wrapper< TBASE > & Group::registerWrapper( ViewKey const & viewKey, bool const allowExistence ) { ViewKey::index_type index; - Wrapper< TBASE > & rval = registerWrapper< T, TBASE >( viewKey.key(), &index ); + Wrapper< TBASE > & rval = registerWrapper< T, TBASE >( viewKey.key(), &index, allowExistence ); viewKey.setIndex( index ); return rval; @@ -1701,12 +1745,11 @@ Wrapper< TBASE > & Group::registerWrapper( ViewKey const & viewKey ) template< typename T > Wrapper< T > & Group::registerWrapper( string const & name, - std::unique_ptr< T > newObject ) + std::unique_ptr< T > newObject, + bool const allowExistence ) { static_assert( !std::is_base_of< WrapperBase, T >::value, "This function should not be used for `WrapperBase`. Use the dedicated `registerWrapper` instead." ); - m_wrappers.insert( name, - new Wrapper< T >( name, *this, std::move( newObject ) ), - true ); + insertWrapper( std::make_unique< Wrapper< T > >( name, *this, std::move( newObject ) ), allowExistence ); Wrapper< T > & rval = getWrapper< T >( name ); if( rval.sizedFromParent() == 1 ) @@ -1721,14 +1764,12 @@ Wrapper< T > & Group::registerWrapper( string const & name, T * newObject ) { static_assert( !std::is_base_of< WrapperBase, T >::value, "This function should not be used for `WrapperBase`. Use the dedicated `registerWrapper` instead." ); - m_wrappers.insert( name, - new Wrapper< T >( name, *this, newObject ), - true ); + insertWrapper( std::make_unique< Wrapper< T > >( name, *this, newObject ) ); Wrapper< T > & rval = getWrapper< T >( name ); if( rval.sizedFromParent() == 1 ) { - rval.resize( size()); + rval.resize( size() ); } return rval; } diff --git a/src/coreComponents/dataRepository/MappedVector.hpp b/src/coreComponents/dataRepository/MappedVector.hpp index 4619363528c..d5a89f5042a 100644 --- a/src/coreComponents/dataRepository/MappedVector.hpp +++ b/src/coreComponents/dataRepository/MappedVector.hpp @@ -22,6 +22,7 @@ // Source includes #include "KeyIndexT.hpp" + #include "common/StdContainerWrappers.hpp" #include "common/GeosxMacros.hpp" #include "common/logger/Logger.hpp" #include "LvArray/src/limits.hpp" @@ -36,33 +37,29 @@ namespace geos * * This class defines a stl-like container that stores values in an stl vector, * and has a map lookup table to access the values by a key. It combines the - * random access performance of a vector when the index is known, the flexibility - * of a mapped key lookup O(n) if only the key is known. + * random access performance of a vector when the index is known with the flexibility + * of a mapped key hash lookupif only the key is known. * * In addition, a keyIndex can be used for lookup, which will give similar * performance to an index lookup after the first use of a keyIndex. */ template< typename T, - typename T_PTR=T *, typename KEY_TYPE=string, typename INDEX_TYPE = int > class MappedVector { public: - static_assert( std::is_same< T_PTR, T * >::value || std::is_same< T_PTR, std::unique_ptr< T > >::value, - "invalid second template argument for MappedVector. Allowable types are T * and std::unique_ptr." ); - /// The type used for the key of the map using key_type = KEY_TYPE; /// pointer to the value type - using mapped_type = T_PTR; + using mapped_type = T *; /// the type of the lookup map using LookupMapType = stdUnorderedMap< KEY_TYPE, INDEX_TYPE >; /// the type of the values held in the vector - using value_type = typename std::pair< KEY_TYPE, T_PTR >; + using value_type = typename std::pair< KEY_TYPE, T * >; /// the type of the values with const keys held in the vector using const_key_value_type = typename std::pair< KEY_TYPE const, T * >; @@ -109,8 +106,7 @@ class MappedVector /// alias for the KeyIndex itself using KeyIndex = KeyIndexT< KEY_TYPE const, INDEX_TYPE >; - - /// deleted default constructor + /// default constructor MappedVector() = default; /// default destructor @@ -119,8 +115,6 @@ class MappedVector clear(); } - - /** * @brief Default copy constructor. */ @@ -143,14 +137,11 @@ class MappedVector */ MappedVector & operator=( MappedVector && ) = default; - - /** * @name element access functions */ ///@{ - /** * @param index * @return pointer to const T @@ -158,7 +149,7 @@ class MappedVector inline T const * operator[]( INDEX_TYPE index ) const { return ( index>KeyIndex::invalid_index && - index( m_values.size() ) ) ? const_cast< T const * >(&(*(m_values[index].second))) : nullptr; + index( m_values.size() ) ) ? m_values[index].second : nullptr; } /** @@ -167,7 +158,7 @@ class MappedVector * @return pointer to T */ inline T * operator[]( INDEX_TYPE index ) - { return const_cast< T * >( const_cast< MappedVector< T, T_PTR, KEY_TYPE, INDEX_TYPE > const * >(this)->operator[]( index ) ); } + { return const_cast< T * >( const_cast< MappedVector< T, KEY_TYPE, INDEX_TYPE > const * >(this)->operator[]( index ) ); } /** * @@ -186,7 +177,9 @@ class MappedVector * @return pointer to T */ inline T * operator[]( KEY_TYPE const & keyName ) - { return const_cast< T * >( const_cast< MappedVector< T, T_PTR, KEY_TYPE, INDEX_TYPE > const * >(this)->operator[]( keyName ) ); } + { + return const_cast< T * >( const_cast< MappedVector< T, KEY_TYPE, INDEX_TYPE > const * >( this )->operator[]( keyName ) ); + } /** * @@ -202,13 +195,11 @@ class MappedVector index = getIndex( keyIndex.key() ); keyIndex.setIndex( index ); } -#ifdef MAPPED_VECTOR_RANGE_CHECKING - else if( m_values[index].first!=keyIndex.Key() ) + else if( m_values[index].first!=keyIndex.key() ) { - index = getIndex( keyIndex.Key() ); + index = getIndex( keyIndex.key() ); keyIndex.setIndex( index ); } -#endif return this->operator[]( index ); } @@ -219,11 +210,10 @@ class MappedVector * @return pointer to T */ inline T * operator[]( KeyIndex const & keyIndex ) - { return const_cast< T * >( const_cast< MappedVector< T, T_PTR, KEY_TYPE, INDEX_TYPE > const * >(this)->operator[]( keyIndex ) ); } + { return const_cast< T * >( const_cast< MappedVector< T, KEY_TYPE, INDEX_TYPE > const * >(this)->operator[]( keyIndex ) ); } ///@} - /** * @name iterator functions */ @@ -295,15 +285,36 @@ class MappedVector * @param keyName key name to assocaite with the new object * @param source pointer to object * @param takeOwnership whether or not to take ownership of the object - * @param overwrite if the key already exists, overwrite indicates whether or not overwrite the existing entry - * @return pointer to the object that is held in the MappedVector + * @return pointer to the object that is held in the MappedVector, or a nullptr + * if @p keyName already existed. */ T * insert( KEY_TYPE const & keyName, - T_PTR source, - bool takeOwnership, - bool overwrite = false ); + T * const source, + bool const takeOwnership ) + { + GEOS_ASSERT_MSG( source, "Trying to insert a nullptr with name: " << keyName ); + + typename LookupMapType::iterator iterKeyLookup = m_keyLookup.find( keyName ); + if( iterKeyLookup != m_keyLookup.end() ) + { + T const * const existingPointer = m_values[ iterKeyLookup->second ].second; + if( takeOwnership && existingPointer != source ) delete source; + return nullptr; + } + + INDEX_TYPE const index = LvArray::integerConversion< INDEX_TYPE >( m_values.size() ); + + m_values.emplace_back( keyName, source ); + m_constKeyValues.emplace_back( keyName, source ); + m_constValues.emplace_back( keyName, source ); + + m_ownsValues.push_back( takeOwnership ); + + m_keyLookup.insert( std::make_pair( keyName, index ) ); + return source; + } /** * @brief Remove element at given index @@ -329,8 +340,8 @@ class MappedVector m_constValues.resize( index ); for( typename valueContainer::size_type i = index; i < m_values.size(); ++i ) { - m_constKeyValues.emplace_back( m_values[i].first, rawPtr( i ) ); - m_constValues.emplace_back( m_values[i].first, rawPtr( i ) ); + m_constKeyValues.emplace_back( m_values[i] ); + m_constValues.emplace_back( m_values[i] ); } // adjust lookup map indices @@ -382,14 +393,13 @@ class MappedVector { deleteValue( LvArray::integerConversion< INDEX_TYPE >( a ) ); } + m_values.clear(); m_constKeyValues.clear(); m_constValues.clear(); - m_values.clear(); m_ownsValues.clear(); m_keyLookup.clear(); } - ///@} /** @@ -408,13 +418,6 @@ class MappedVector inline valueContainer const & values() { return this->m_values; } - /** - * @brief access for value container - * @return reference to const valueContainer - */ - inline constValueContainer const & values() const - { return this->m_constValues; } - /** * @brief access for key lookup * @return reference lookup map @@ -422,17 +425,9 @@ class MappedVector inline LookupMapType const & keys() const { return m_keyLookup; } - private: - T * rawPtr( INDEX_TYPE index ) - { - return &(*(m_values[index].second)); - } - - template< typename U = T_PTR > - typename std::enable_if< std::is_same< U, T * >::value, void >::type - deleteValue( INDEX_TYPE index ) + void deleteValue( INDEX_TYPE index ) { if( m_ownsValues[index] ) { @@ -440,11 +435,6 @@ class MappedVector } } - template< typename U = T_PTR > - typename std::enable_if< !std::is_same< U, T * >::value, void >::type - deleteValue( INDEX_TYPE GEOS_UNUSED_PARAM( index ) ) - {} - /// random access container that holds the values valueContainer m_values; @@ -461,75 +451,6 @@ class MappedVector stdVector< int > m_ownsValues; }; -template< typename T, typename T_PTR, typename KEY_TYPE, typename INDEX_TYPE > -T * MappedVector< T, T_PTR, KEY_TYPE, INDEX_TYPE >::insert( KEY_TYPE const & keyName, - T_PTR source, - bool takeOwnership, - bool overwrite ) -{ - INDEX_TYPE index = KeyIndex::invalid_index; - typename LookupMapType::iterator iterKeyLookup = m_keyLookup.find( keyName ); - - - // if the key was not found, make DataObject and insert - if( iterKeyLookup == m_keyLookup.end() ) - { - value_type newEntry = std::make_pair( keyName, std::move( source ) ); - m_values.push_back( std::move( newEntry ) ); - //TODO this needs to be a safe conversion - index = static_cast< INDEX_TYPE >(m_values.size()) - 1; - m_ownsValues.resize( index + 1 ); - if( takeOwnership ) - { - m_ownsValues[index] = true; - } - - m_keyLookup.insert( std::make_pair( keyName, index ) ); - m_constKeyValues.emplace_back( keyName, rawPtr( index ) ); - m_constValues.emplace_back( keyName, rawPtr( index ) ); - - } - // if key was found - else - { - index = iterKeyLookup->second; - - if( takeOwnership ) - { - m_ownsValues[index] = true; - } - - // if value is empty, then move source into value slot - if( m_values[index].second==nullptr ) - { - m_values[index].second = std::move( source ); - m_constKeyValues[index].second = rawPtr( index ); - m_constValues[index].second = rawPtr( index ); - } - else - { - if( overwrite ) - { - deleteValue( index ); - m_values[index].second = std::move( source ); - m_constKeyValues[index].second = rawPtr( index ); - m_constValues[index].second = rawPtr( index ); - } - else if( typeid( source ) != typeid( m_values[index].second ) ) - { - GEOS_ERROR( "MappedVector::insert(): Tried to insert existing key (" << keyName << - ") with a different type without overwrite flag\n " << " " << LvArray::system::demangleType( source ) << - " != " << LvArray::system::demangleType( m_values[ index ].second ) ); - } - else - { - delete source; - } - } - } - - return &(*(m_values[index].second)); -} -} +} // namespace geos #endif /* GEOS_DATAREPOSITORY_MAPPEDVECTOR_HPP_ */ diff --git a/src/coreComponents/discretizationMethods/NumericalMethodsManager.cpp b/src/coreComponents/discretizationMethods/NumericalMethodsManager.cpp index f9dbbb06bc3..f09361eb87e 100644 --- a/src/coreComponents/discretizationMethods/NumericalMethodsManager.cpp +++ b/src/coreComponents/discretizationMethods/NumericalMethodsManager.cpp @@ -31,15 +31,16 @@ NumericalMethodsManager::NumericalMethodsManager( string const & name, Group * c { setInputFlags( InputFlags::OPTIONAL ); - this->registerGroup( groupKeysStruct::finiteElementDiscretizationsString(), &m_finiteElementDiscretizationManager ); - this->registerGroup( groupKeysStruct::finiteVolumeManagerString(), &m_finiteVolumeManager ); + this->registerGroup( &m_finiteElementDiscretizationManager ); + this->registerGroup( &m_finiteVolumeManager ); } NumericalMethodsManager::~NumericalMethodsManager() {} Group * NumericalMethodsManager::createChild( string const & GEOS_UNUSED_PARAM( childKey ), - string const & GEOS_UNUSED_PARAM( childName ) ) + string const & GEOS_UNUSED_PARAM( childName ), + bool const GEOS_UNUSED_PARAM( allowExistence ) ) { // Unused as all children are created within the constructor return nullptr; diff --git a/src/coreComponents/discretizationMethods/NumericalMethodsManager.hpp b/src/coreComponents/discretizationMethods/NumericalMethodsManager.hpp index 503647f206a..688a763c693 100644 --- a/src/coreComponents/discretizationMethods/NumericalMethodsManager.hpp +++ b/src/coreComponents/discretizationMethods/NumericalMethodsManager.hpp @@ -53,7 +53,9 @@ class NumericalMethodsManager : public dataRepository::Group virtual ~NumericalMethodsManager() override; - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /// Contains the keys for the object names in the data repository. struct groupKeysStruct diff --git a/src/coreComponents/events/EventBase.cpp b/src/coreComponents/events/EventBase.cpp index 00aed4b5d15..0da65bafc60 100644 --- a/src/coreComponents/events/EventBase.cpp +++ b/src/coreComponents/events/EventBase.cpp @@ -119,12 +119,14 @@ EventBase::CatalogInterface::CatalogType & EventBase::getCatalog() return catalog; } -Group * EventBase::createChild( string const & childKey, string const & childName ) +Group * EventBase::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< EventBase > event = EventBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup< EventBase >( childName, std::move( event ) ); + return &this->registerGroup< EventBase >( std::move( event ), allowExistence ); } diff --git a/src/coreComponents/events/EventBase.hpp b/src/coreComponents/events/EventBase.hpp index d069d7cd1eb..a3d27452cf0 100644 --- a/src/coreComponents/events/EventBase.hpp +++ b/src/coreComponents/events/EventBase.hpp @@ -94,7 +94,9 @@ class EventBase : public ExecutableGroup * * @endcode */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /** * @brief Expand any catalogs in the data structure. diff --git a/src/coreComponents/events/EventManager.cpp b/src/coreComponents/events/EventManager.cpp index 7e2415131b7..759c14cacb2 100644 --- a/src/coreComponents/events/EventManager.cpp +++ b/src/coreComponents/events/EventManager.cpp @@ -92,12 +92,14 @@ EventManager::~EventManager() -Group * EventManager::createChild( string const & childKey, string const & childName ) +Group * EventManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< EventBase > event = EventBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup< EventBase >( childName, std::move( event ) ); + return &this->registerGroup< EventBase >( std::move( event ), allowExistence ); } diff --git a/src/coreComponents/events/EventManager.hpp b/src/coreComponents/events/EventManager.hpp index 0e5024fb07c..ff3099a6e2a 100644 --- a/src/coreComponents/events/EventManager.hpp +++ b/src/coreComponents/events/EventManager.hpp @@ -59,9 +59,13 @@ class EventManager : public dataRepository::Group * @brief Create a child EventManager * @param[in] childKey the key of the Event to be added * @param[in] childName the name of the child to be added + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return the Event */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /** * @brief This method is used to expand any catalogs in the data structure diff --git a/src/coreComponents/events/tasks/TasksManager.cpp b/src/coreComponents/events/tasks/TasksManager.cpp index 7dfec005c62..4be12b39443 100644 --- a/src/coreComponents/events/tasks/TasksManager.cpp +++ b/src/coreComponents/events/tasks/TasksManager.cpp @@ -36,12 +36,14 @@ TasksManager::TasksManager( string const & name, TasksManager::~TasksManager() { } -Group * TasksManager::createChild( string const & childKey, string const & childName ) +Group * TasksManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< TaskBase > task = TaskBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup< TaskBase >( childName, std::move( task ) ); + return &this->registerGroup< TaskBase >( std::move( task ), allowExistence ); } void TasksManager::expandObjectCatalogs() diff --git a/src/coreComponents/events/tasks/TasksManager.hpp b/src/coreComponents/events/tasks/TasksManager.hpp index 852e0fd8cf4..172c6e8d54f 100644 --- a/src/coreComponents/events/tasks/TasksManager.hpp +++ b/src/coreComponents/events/tasks/TasksManager.hpp @@ -39,7 +39,9 @@ class TasksManager : public dataRepository::Group virtual ~TasksManager() override; /// @copydoc geos::dataRepository::Group::createChild - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /// This function is used to expand any catalogs in the data structure virtual void expandObjectCatalogs() override; diff --git a/src/coreComponents/fieldSpecification/FieldSpecificationManager.cpp b/src/coreComponents/fieldSpecification/FieldSpecificationManager.cpp index f725a44fafd..30857f2bd78 100644 --- a/src/coreComponents/fieldSpecification/FieldSpecificationManager.cpp +++ b/src/coreComponents/fieldSpecification/FieldSpecificationManager.cpp @@ -50,12 +50,14 @@ FieldSpecificationManager & FieldSpecificationManager::getInstance() return *m_instance; } -Group * FieldSpecificationManager::createChild( string const & childKey, string const & childName ) +Group * FieldSpecificationManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< FieldSpecificationBase > bc = FieldSpecificationBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup( childName, std::move( bc ) ); + return &this->registerGroup( std::move( bc ), allowExistence ); } @@ -64,7 +66,7 @@ void FieldSpecificationManager::expandObjectCatalogs() // During schema generation, register one of each type derived from BoundaryConditionBase here for( auto & catalogIter: FieldSpecificationBase::getCatalog()) { - createChild( catalogIter.first, catalogIter.first ); + createChild( catalogIter.first, catalogIter.first, true ); } } diff --git a/src/coreComponents/fieldSpecification/FieldSpecificationManager.hpp b/src/coreComponents/fieldSpecification/FieldSpecificationManager.hpp index b1d929e6561..84fc2d095b7 100644 --- a/src/coreComponents/fieldSpecification/FieldSpecificationManager.hpp +++ b/src/coreComponents/fieldSpecification/FieldSpecificationManager.hpp @@ -67,9 +67,13 @@ class FieldSpecificationManager : public dataRepository::Group * @brief Create a new FieldSpecificationBase object as a child of this group. * @param childKey the catalog key of the new FieldSpecificationBase derived type to create * @param childName the name of the new FieldSpecificationBase object in the repository + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return the group child */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /// This function is used to expand any catalogs in the data structure virtual void expandObjectCatalogs() override; diff --git a/src/coreComponents/fileIO/Outputs/OutputManager.cpp b/src/coreComponents/fileIO/Outputs/OutputManager.cpp index 7fcafb8aa98..61ae32d955a 100644 --- a/src/coreComponents/fileIO/Outputs/OutputManager.cpp +++ b/src/coreComponents/fileIO/Outputs/OutputManager.cpp @@ -37,12 +37,14 @@ OutputManager::~OutputManager() -Group * OutputManager::createChild( string const & childKey, string const & childName ) +Group * OutputManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< OutputBase > output = OutputBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup< OutputBase >( childName, std::move( output ) ); + return &this->registerGroup< OutputBase >( std::move( output ), allowExistence ); } diff --git a/src/coreComponents/fileIO/Outputs/OutputManager.hpp b/src/coreComponents/fileIO/Outputs/OutputManager.hpp index 38a68c06568..27a1b9a04b0 100644 --- a/src/coreComponents/fileIO/Outputs/OutputManager.hpp +++ b/src/coreComponents/fileIO/Outputs/OutputManager.hpp @@ -46,8 +46,10 @@ class OutputManager : public dataRepository::Group /// Destructor virtual ~OutputManager() override; - /// @copydoc geos::dataRepository::Group::createChild( string const & childKey, string const & childName ) - virtual Group * createChild( string const & childKey, string const & childName ) override; + /// @copydoc geos::dataRepository::Group::createChild( string const & childKey, string const & childName, bool const allowExistence ) + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /// This function is used to expand any catalogs in the data structure virtual void expandObjectCatalogs() override; diff --git a/src/coreComponents/fileIO/silo/SiloFile.cpp b/src/coreComponents/fileIO/silo/SiloFile.cpp index 06da0c5ad09..4f7b6356549 100644 --- a/src/coreComponents/fileIO/silo/SiloFile.cpp +++ b/src/coreComponents/fileIO/silo/SiloFile.cpp @@ -1245,7 +1245,7 @@ void SiloFile::writeElementRegionSilo( ElementRegionBase const & elemRegion, { using ArrayType = camp::first< decltype( tupleOfTypes ) >; Wrapper< ArrayType > const & sourceWrapper = Wrapper< ArrayType >::cast( wrapper ); - Wrapper< ArrayType > & newWrapper = fakeGroup.registerWrapper< ArrayType >( fieldName ); + Wrapper< ArrayType > & newWrapper = fakeGroup.registerWrapper< ArrayType >( fieldName, true ); newWrapper.setPlotLevel( PlotLevel::LEVEL_0 ); newWrapper.reference().resize( ArrayType::NDIM, sourceWrapper.reference().dims() ); diff --git a/src/coreComponents/finiteElement/FiniteElementDiscretizationManager.cpp b/src/coreComponents/finiteElement/FiniteElementDiscretizationManager.cpp index 9bc4e70c5ce..41c4f594477 100644 --- a/src/coreComponents/finiteElement/FiniteElementDiscretizationManager.cpp +++ b/src/coreComponents/finiteElement/FiniteElementDiscretizationManager.cpp @@ -37,13 +37,15 @@ FiniteElementDiscretizationManager::~FiniteElementDiscretizationManager() } -Group * FiniteElementDiscretizationManager::createChild( string const & childKey, string const & childName ) +Group * FiniteElementDiscretizationManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { // These objects should probably not be registered on managed group... GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< Group > fem = Group::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup( childName, std::move( fem ) ); + return &this->registerGroup( std::move( fem ), allowExistence ); } diff --git a/src/coreComponents/finiteElement/FiniteElementDiscretizationManager.hpp b/src/coreComponents/finiteElement/FiniteElementDiscretizationManager.hpp index e82a8b99244..4870f15d856 100644 --- a/src/coreComponents/finiteElement/FiniteElementDiscretizationManager.hpp +++ b/src/coreComponents/finiteElement/FiniteElementDiscretizationManager.hpp @@ -32,7 +32,9 @@ class FiniteElementDiscretizationManager : public dataRepository::Group FiniteElementDiscretizationManager( string const & name, Group * const parent ); virtual ~FiniteElementDiscretizationManager() override; - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /// This function is used to expand any catalogs in the data structure virtual void expandObjectCatalogs() override; diff --git a/src/coreComponents/finiteVolume/FiniteVolumeManager.cpp b/src/coreComponents/finiteVolume/FiniteVolumeManager.cpp index ef6c94b5fb5..82ce02701bf 100644 --- a/src/coreComponents/finiteVolume/FiniteVolumeManager.cpp +++ b/src/coreComponents/finiteVolume/FiniteVolumeManager.cpp @@ -39,19 +39,21 @@ FiniteVolumeManager::FiniteVolumeManager( string const & name, Group * const par FiniteVolumeManager::~FiniteVolumeManager() {} -Group * FiniteVolumeManager::createChild( string const & childKey, string const & childName ) +Group * FiniteVolumeManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); if( childKey == HybridMimeticDiscretization::catalogName() ) { std::unique_ptr< HybridMimeticDiscretization > hm = std::make_unique< HybridMimeticDiscretization >( childName, this ); - return &this->registerGroup< HybridMimeticDiscretization >( childName, std::move( hm ) ); + return &this->registerGroup< HybridMimeticDiscretization >( std::move( hm ), allowExistence ); } else { std::unique_ptr< FluxApproximationBase > approx = FluxApproximationBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup< FluxApproximationBase >( childName, std::move( approx )); + return &this->registerGroup< FluxApproximationBase >( std::move( approx ), allowExistence ); } } @@ -68,7 +70,7 @@ void FiniteVolumeManager::expandObjectCatalogs() { string const childName = catalogIter.first; std::unique_ptr< HybridMimeticDiscretization > hm = std::make_unique< HybridMimeticDiscretization >( childName, this ); - this->registerGroup< HybridMimeticDiscretization >( childName, std::move( hm ) ); + this->registerGroup< HybridMimeticDiscretization >( std::move( hm ) ); } } diff --git a/src/coreComponents/finiteVolume/FiniteVolumeManager.hpp b/src/coreComponents/finiteVolume/FiniteVolumeManager.hpp index 82e2e638854..3b5d1c87f0a 100644 --- a/src/coreComponents/finiteVolume/FiniteVolumeManager.hpp +++ b/src/coreComponents/finiteVolume/FiniteVolumeManager.hpp @@ -56,7 +56,9 @@ class FiniteVolumeManager : public dataRepository::Group */ virtual ~FiniteVolumeManager() override; - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; virtual void expandObjectCatalogs() override; diff --git a/src/coreComponents/finiteVolume/FluxApproximationBase.cpp b/src/coreComponents/finiteVolume/FluxApproximationBase.cpp index 673d6f1b53c..6c6bfe018b0 100644 --- a/src/coreComponents/finiteVolume/FluxApproximationBase.cpp +++ b/src/coreComponents/finiteVolume/FluxApproximationBase.cpp @@ -102,7 +102,7 @@ void FluxApproximationBase::initializePreSubGroups() { Group & parentMesh = mesh.getShallowParent(); Group & parentStencilParentGroup = parentMesh.getGroup( groupKeyStruct::stencilMeshGroupString() ); - mesh.registerGroup( groupKeyStruct::stencilMeshGroupString(), &parentStencilParentGroup ); + mesh.registerGroup( &parentStencilParentGroup ); } } } ); @@ -180,7 +180,7 @@ void FluxApproximationBase::initializePostInitialConditionsPreSubGroups() { Group & parentMesh = mesh.getShallowParent(); Group & parentStencilParentGroup = parentMesh.getGroup( groupKeyStruct::stencilMeshGroupString() ); - mesh.registerGroup( groupKeyStruct::stencilMeshGroupString(), &parentStencilParentGroup ); + mesh.registerGroup( &parentStencilParentGroup ); } } } ); diff --git a/src/coreComponents/functions/FunctionManager.cpp b/src/coreComponents/functions/FunctionManager.cpp index 2f8425beb99..0049e73a11c 100644 --- a/src/coreComponents/functions/FunctionManager.cpp +++ b/src/coreComponents/functions/FunctionManager.cpp @@ -51,12 +51,13 @@ FunctionManager & FunctionManager::getInstance() } Group * FunctionManager::createChild( string const & functionCatalogKey, - string const & functionName ) + string const & functionName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), functionCatalogKey, functionName ) ); std::unique_ptr< FunctionBase > function = FunctionBase::CatalogInterface::factory( functionCatalogKey, getDataContext(), functionName, this ); - return &this->registerGroup< FunctionBase >( functionName, std::move( function ) ); + return &this->registerGroup< FunctionBase >( std::move( function ), allowExistence ); } @@ -65,7 +66,7 @@ void FunctionManager::expandObjectCatalogs() // During schema generation, register one of each type derived from FunctionBase here for( auto & catalogIter: FunctionBase::getCatalog()) { - createChild( catalogIter.first, catalogIter.first ); + createChild( catalogIter.first, catalogIter.first, true ); } } diff --git a/src/coreComponents/functions/FunctionManager.hpp b/src/coreComponents/functions/FunctionManager.hpp index dac7ad85b0a..12735afebd0 100644 --- a/src/coreComponents/functions/FunctionManager.hpp +++ b/src/coreComponents/functions/FunctionManager.hpp @@ -59,9 +59,13 @@ class FunctionManager : public dataRepository::Group * @brief Create a new FunctionManager object as a child of this group. * @param functionCatalogKey the catalog key of the new FunctionManager derived type to create * @param functionName the name of the new FunctionManager object in the repository + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return the group child */ - virtual Group * createChild( string const & functionCatalogKey, string const & functionName ) override; + virtual Group * createChild( string const & functionCatalogKey, + string const & functionName, + bool const allowExistence=false ) override; /** * @brief This function is used to expand any catalogs in the data structure diff --git a/src/coreComponents/functions/unitTests/testFunctions.cpp b/src/coreComponents/functions/unitTests/testFunctions.cpp index 04ca26acca6..2607c21166a 100644 --- a/src/coreComponents/functions/unitTests/testFunctions.cpp +++ b/src/coreComponents/functions/unitTests/testFunctions.cpp @@ -791,7 +791,7 @@ TEST( FunctionTests, 2DMultivariableTable ) values[( i * axisPoints[1] + j ) * nOps + 2] = operator3( x, y ); } - MultivariableTableFunction & table_g = dynamicCast< MultivariableTableFunction & >( *functionManager->createChild( "MultivariableTableFunction", "table_f" ) ); + MultivariableTableFunction & table_g = dynamicCast< MultivariableTableFunction & >( *functionManager->createChild( "MultivariableTableFunction", "table_g" ) ); table_g.setTableCoordinates( nDims, nOps, axisMins, axisMaxs, axisPoints ); table_g.setTableValues( values ); table_g.initializeFunction(); @@ -835,7 +835,7 @@ TEST( FunctionTests, MultivariableTableFromFile ) // Setup table - MultivariableTableFunction & table_h = dynamicCast< MultivariableTableFunction & >( *functionManager->createChild( "MultivariableTableFunction", "table_f" ) ); + MultivariableTableFunction & table_h = dynamicCast< MultivariableTableFunction & >( *functionManager->createChild( "MultivariableTableFunction", "table_h" ) ); writeTableToFile( "tableData.txt", multivariableTableFileContent ); table_h.initializeFunctionFromFile ( "tableData.txt" ); diff --git a/src/coreComponents/integrationTests/fluidFlowTests/testCompFlowUtils.hpp b/src/coreComponents/integrationTests/fluidFlowTests/testCompFlowUtils.hpp index c5e2492cb16..5ed9a33e476 100644 --- a/src/coreComponents/integrationTests/fluidFlowTests/testCompFlowUtils.hpp +++ b/src/coreComponents/integrationTests/fluidFlowTests/testCompFlowUtils.hpp @@ -80,25 +80,10 @@ void setupProblemFromXML( ProblemManager & problemManager, char const * const xm dataRepository::Group & commandLine = problemManager.getGroup< dataRepository::Group >( problemManager.groupKeys.commandLine ); - commandLine.registerWrapper< integer >( problemManager.viewKeys.xPartitionsOverride.key() ). + commandLine.getWrapper< integer >( problemManager.viewKeys.xPartitionsOverride.key() ). setApplyDefaultValue( mpiSize ); - xmlWrapper::xmlNode xmlProblemNode = xmlDocument.getChild( dataRepository::keys::ProblemManager ); - problemManager.processInputFileRecursive( xmlDocument, xmlProblemNode ); - - DomainPartition & domain = problemManager.getDomainPartition(); - - constitutive::ConstitutiveManager & constitutiveManager = domain.getConstitutiveManager(); - xmlWrapper::xmlNode topLevelNode = xmlProblemNode.child( constitutiveManager.getName().c_str()); - constitutiveManager.processInputFileRecursive( xmlDocument, topLevelNode ); - - MeshManager & meshManager = problemManager.getGroup< MeshManager >( problemManager.groupKeys.meshManager ); - meshManager.generateMeshLevels( domain ); - - ElementRegionManager & elementManager = domain.getMeshBody( 0 ).getBaseDiscretization().getElemManager(); - topLevelNode = xmlProblemNode.child( elementManager.getName().c_str()); - elementManager.processInputFileRecursive( xmlDocument, topLevelNode ); - + problemManager.parseXMLDocument( xmlDocument ); problemManager.problemSetup(); problemManager.applyInitialConditions(); } diff --git a/src/coreComponents/integrationTests/fluidFlowTests/testSingleFlowUtils.hpp b/src/coreComponents/integrationTests/fluidFlowTests/testSingleFlowUtils.hpp index 24f57efc242..24fb5c59a72 100644 --- a/src/coreComponents/integrationTests/fluidFlowTests/testSingleFlowUtils.hpp +++ b/src/coreComponents/integrationTests/fluidFlowTests/testSingleFlowUtils.hpp @@ -66,25 +66,10 @@ void setupProblemFromXML( ProblemManager & problemManager, char const * const xm dataRepository::Group & commandLine = problemManager.getGroup< dataRepository::Group >( problemManager.groupKeys.commandLine ); - commandLine.registerWrapper< integer >( problemManager.viewKeys.xPartitionsOverride.key() ). + commandLine.getWrapper< integer >( problemManager.viewKeys.xPartitionsOverride.key() ). setApplyDefaultValue( mpiSize ); - xmlWrapper::xmlNode xmlProblemNode = xmlDocument.getChild( dataRepository::keys::ProblemManager ); - problemManager.processInputFileRecursive( xmlDocument, xmlProblemNode ); - - DomainPartition & domain = problemManager.getDomainPartition(); - - constitutive::ConstitutiveManager & constitutiveManager = domain.getConstitutiveManager(); - xmlWrapper::xmlNode topLevelNode = xmlProblemNode.child( constitutiveManager.getName().c_str()); - constitutiveManager.processInputFileRecursive( xmlDocument, topLevelNode ); - - MeshManager & meshManager = problemManager.getGroup< MeshManager >( problemManager.groupKeys.meshManager ); - meshManager.generateMeshLevels( domain ); - - ElementRegionManager & elementManager = domain.getMeshBody( 0 ).getBaseDiscretization().getElemManager(); - topLevelNode = xmlProblemNode.child( elementManager.getName().c_str()); - elementManager.processInputFileRecursive( xmlDocument, topLevelNode ); - + problemManager.parseXMLDocument( xmlDocument ); problemManager.problemSetup(); problemManager.applyInitialConditions(); } diff --git a/src/coreComponents/integrationTests/linearAlgebraTests/CMakeLists.txt b/src/coreComponents/integrationTests/linearAlgebraTests/CMakeLists.txt index 96d7e65f993..25e4cb3dcda 100644 --- a/src/coreComponents/integrationTests/linearAlgebraTests/CMakeLists.txt +++ b/src/coreComponents/integrationTests/linearAlgebraTests/CMakeLists.txt @@ -25,7 +25,8 @@ foreach(test ${LAI_tests}) if ( ENABLE_MPI ) geos_add_test( NAME ${test_name} COMMAND ${test_name} -x ${nranks} - NUM_MPI_TASKS ${nranks} ) + NUM_MPI_TASKS ${nranks} + NUM_OMP_THREADS 1 ) else() geos_add_test( NAME ${test_name} COMMAND ${test_name} ) diff --git a/src/coreComponents/integrationTests/linearAlgebraTests/testDofManagerUtils.hpp b/src/coreComponents/integrationTests/linearAlgebraTests/testDofManagerUtils.hpp index 02dd0d8090c..e901a012434 100644 --- a/src/coreComponents/integrationTests/linearAlgebraTests/testDofManagerUtils.hpp +++ b/src/coreComponents/integrationTests/linearAlgebraTests/testDofManagerUtils.hpp @@ -50,7 +50,7 @@ void setupProblemFromXML( ProblemManager * const problemManager, char const * co int mpiSize = MpiWrapper::commSize( MPI_COMM_GEOS ); dataRepository::Group & commandLine = problemManager->getGroup< dataRepository::Group >( problemManager->groupKeys.commandLine ); - commandLine.registerWrapper< integer >( problemManager->viewKeys.xPartitionsOverride.key() ). + commandLine.getWrapper< integer >( problemManager->viewKeys.xPartitionsOverride.key() ). setApplyDefaultValue( mpiSize ); xmlWrapper::xmlNode xmlProblemNode = xmlDocument.getChild( dataRepository::keys::ProblemManager ); diff --git a/src/coreComponents/integrationTests/xmlTests/testXMLFile.cpp b/src/coreComponents/integrationTests/xmlTests/testXMLFile.cpp index 274a5d52e9b..932105fa7bb 100644 --- a/src/coreComponents/integrationTests/xmlTests/testXMLFile.cpp +++ b/src/coreComponents/integrationTests/xmlTests/testXMLFile.cpp @@ -31,9 +31,13 @@ using namespace geos; using namespace geos::dataRepository; using namespace xmlWrapper; +std::unique_ptr< CommandLineOptions > globalCommandLine = nullptr; + // Tests if the xml file parsing works with one file, one file with nested includes, and multiple files TEST( testXML, testXMLFile ) { + GeosxState state( std::make_unique< CommandLineOptions >( *globalCommandLine ) ); + geos::ProblemManager & problemManager = geos::getGlobalState().getProblemManager(); problemManager.parseCommandLineInput(); problemManager.parseInputFile(); @@ -188,6 +192,8 @@ std::set< string > getDifference( std::set< string > const & setA, // - if the resulting Group & Wrapper hierarchy matches with the input xml documents and includes hierarchy. TEST( testXML, testXMLFileLines ) { + GeosxState state( std::make_unique< CommandLineOptions >( *globalCommandLine ) ); + xmlDocument xmlDoc; ProblemManager & problemManager = getGlobalState().getProblemManager(); @@ -231,7 +237,7 @@ int main( int argc, char * * argv ) { ::testing::InitGoogleTest( &argc, argv ); - GeosxState state( basicSetup( argc, argv, true ) ); + globalCommandLine = basicSetup( argc, argv, true ); int const result = RUN_ALL_TESTS(); diff --git a/src/coreComponents/linearAlgebra/DofManagerHelpers.hpp b/src/coreComponents/linearAlgebra/DofManagerHelpers.hpp index 6ae81b10790..c6623b35e59 100644 --- a/src/coreComponents/linearAlgebra/DofManagerHelpers.hpp +++ b/src/coreComponents/linearAlgebra/DofManagerHelpers.hpp @@ -634,7 +634,7 @@ struct ArrayHelper REGIONS_CONTAINER const & GEOS_UNUSED_PARAM( regions ) ) { ObjectManagerBase & baseManager = getObjectManager< LOC >( mesh ); - baseManager.registerWrapper< ArrayType >( key ). + baseManager.registerWrapper< ArrayType >( key, true ). setApplyDefaultValue( -1 ). setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ). setRestartFlags( dataRepository::RestartFlags::NO_WRITE ). @@ -687,7 +687,7 @@ struct ArrayHelper< T, FieldLocation::Elem > mesh.getElemManager().template forElementSubRegions< SUBREGIONTYPES... >( regions, [&]( localIndex const, ElementSubRegionBase & subRegion ) { - subRegion.registerWrapper< ArrayType >( key ). + subRegion.registerWrapper< ArrayType >( key, true ). setApplyDefaultValue( -1 ). setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ). setRestartFlags( dataRepository::RestartFlags::NO_WRITE ). diff --git a/src/coreComponents/linearAlgebra/unitTests/CMakeLists.txt b/src/coreComponents/linearAlgebra/unitTests/CMakeLists.txt index 39de3a6a8b1..f3995b7f4d6 100644 --- a/src/coreComponents/linearAlgebra/unitTests/CMakeLists.txt +++ b/src/coreComponents/linearAlgebra/unitTests/CMakeLists.txt @@ -32,7 +32,8 @@ foreach(test ${parallel_tests}) if ( ENABLE_MPI ) geos_add_test( NAME ${test_name} COMMAND ${test_name} -x ${nranks} - NUM_MPI_TASKS ${nranks} ) + NUM_MPI_TASKS ${nranks} + NUM_OMP_THREADS 1 ) else() geos_add_test( NAME _${test_name} COMMAND ${test_name} ) diff --git a/src/coreComponents/mainInterface/ProblemManager.cpp b/src/coreComponents/mainInterface/ProblemManager.cpp index decbae981ef..3dd9315c1eb 100644 --- a/src/coreComponents/mainInterface/ProblemManager.cpp +++ b/src/coreComponents/mainInterface/ProblemManager.cpp @@ -159,7 +159,9 @@ ProblemManager::~ProblemManager() } -Group * ProblemManager::createChild( string const & GEOS_UNUSED_PARAM( childKey ), string const & GEOS_UNUSED_PARAM( childName ) ) +Group * ProblemManager::createChild( string const & GEOS_UNUSED_PARAM( childKey ), + string const & GEOS_UNUSED_PARAM( childName ), + bool const GEOS_UNUSED_PARAM( allowExistence ) ) { // Unused as all children are created within the constructor return nullptr; @@ -351,69 +353,69 @@ void ProblemManager::setSchemaDeviations( xmlWrapper::xmlNode schemaRoot, // Add entries that are only used in the pre-processor - Group & IncludedList = this->registerGroup< Group >( xmlWrapper::includedListTag ); + Group & IncludedList = this->registerGroup< Group >( xmlWrapper::includedListTag, true ); IncludedList.setInputFlags( InputFlags::OPTIONAL ); - Group & includedFile = IncludedList.registerGroup< Group >( xmlWrapper::includedFileTag ); + Group & includedFile = IncludedList.registerGroup< Group >( xmlWrapper::includedFileTag, true ); includedFile.setInputFlags( InputFlags::OPTIONAL_NONUNIQUE ); // the name of includedFile is actually a Path. - includedFile.registerWrapper< string >( "name" ). + includedFile.registerWrapper< string >( "name", nullptr, true ). setInputFlag( InputFlags::REQUIRED ). setRTTypeName( rtTypes::getTypeName( typeid( Path ) ) ). setDescription( "The relative file path." ); schemaUtilities::SchemaConstruction( IncludedList, schemaRoot, targetChoiceNode, documentationType ); - Group & parameterList = this->registerGroup< Group >( "Parameters" ); + Group & parameterList = this->registerGroup< Group >( "Parameters", true ); parameterList.setInputFlags( InputFlags::OPTIONAL ); - Group & parameter = parameterList.registerGroup< Group >( "Parameter" ); + Group & parameter = parameterList.registerGroup< Group >( "Parameter", true ); parameter.setInputFlags( InputFlags::OPTIONAL_NONUNIQUE ); - parameter.registerWrapper< string >( "value" ). + parameter.registerWrapper< string >( "value", nullptr, true ). setInputFlag( InputFlags::REQUIRED ). setDescription( "Input parameter definition for the preprocessor" ); schemaUtilities::SchemaConstruction( parameterList, schemaRoot, targetChoiceNode, documentationType ); - Group & benchmarks = this->registerGroup< Group >( "Benchmarks" ); + Group & benchmarks = this->registerGroup< Group >( "Benchmarks", true ); benchmarks.setInputFlags( InputFlags::OPTIONAL ); for( string const machineName : {"quartz", "lassen", "crusher" } ) { - Group & machine = benchmarks.registerGroup< Group >( machineName ); + Group & machine = benchmarks.registerGroup< Group >( machineName, true ); machine.setInputFlags( InputFlags::OPTIONAL ); - Group & run = machine.registerGroup< Group >( "Run" ); + Group & run = machine.registerGroup< Group >( "Run", true ); run.setInputFlags( InputFlags::OPTIONAL ); - run.registerWrapper< string >( "name" ).setInputFlag( InputFlags::REQUIRED ). + run.registerWrapper< string >( "name", nullptr, true ).setInputFlag( InputFlags::REQUIRED ). setDescription( "The name of this benchmark." ); - run.registerWrapper< int >( "timeLimit" ).setInputFlag( InputFlags::OPTIONAL ). + run.registerWrapper< int >( "timeLimit", nullptr, true ).setInputFlag( InputFlags::OPTIONAL ). setDescription( "The time limit of the benchmark." ); - run.registerWrapper< string >( "args" ).setInputFlag( InputFlags::OPTIONAL ). + run.registerWrapper< string >( "args", nullptr, true ).setInputFlag( InputFlags::OPTIONAL ). setDescription( "Any extra command line arguments to pass to GEOSX." ); - run.registerWrapper< string >( "autoPartition" ).setInputFlag( InputFlags::OPTIONAL ). + run.registerWrapper< string >( "autoPartition", nullptr, true ).setInputFlag( InputFlags::OPTIONAL ). setDescription( "May be 'Off' or 'On', if 'On' partitioning arguments are created automatically. Default is Off." ); - run.registerWrapper< string >( "scaling" ).setInputFlag( InputFlags::OPTIONAL ). + run.registerWrapper< string >( "scaling", nullptr, true ).setInputFlag( InputFlags::OPTIONAL ). setDescription( "Whether to run a scaling, and which type of scaling to run." ); - run.registerWrapper< int >( "nodes" ).setInputFlag( InputFlags::OPTIONAL ). + run.registerWrapper< int >( "nodes", nullptr, true ).setInputFlag( InputFlags::OPTIONAL ). setDescription( "The number of nodes needed to run the base benchmark, default is 1." ); - run.registerWrapper< int >( "tasksPerNode" ).setInputFlag( InputFlags::REQUIRED ). + run.registerWrapper< int >( "tasksPerNode", nullptr, true ).setInputFlag( InputFlags::REQUIRED ). setDescription( "The number of tasks per node to run the benchmark with." ); - run.registerWrapper< int >( "threadsPerTask" ).setInputFlag( InputFlags::OPTIONAL ). + run.registerWrapper< int >( "threadsPerTask", nullptr, true ).setInputFlag( InputFlags::OPTIONAL ). setDescription( "The number of threads per task to run the benchmark with." ); - run.registerWrapper< array1d< int > >( "meshSizes" ).setInputFlag( InputFlags::OPTIONAL ). + run.registerWrapper< array1d< int > >( "meshSizes", nullptr, true ).setInputFlag( InputFlags::OPTIONAL ). setDescription( "The target number of elements in the internal mesh (per-process for weak scaling, globally for strong scaling) default doesn't modify the internalMesh." ); - run.registerWrapper< array1d< int > >( "scaleList" ).setInputFlag( InputFlags::OPTIONAL ). + run.registerWrapper< array1d< int > >( "scaleList", nullptr, true ).setInputFlag( InputFlags::OPTIONAL ). setDescription( "The scales at which to run the problem ( scale * nodes * tasksPerNode )." ); } @@ -971,7 +973,7 @@ map< std::tuple< string, string, string, string >, localIndex > ProblemManager:: std::unique_ptr< finiteElement::FiniteElementBase > newFE = feDiscretization->factory( subRegion.getElementType() ); finiteElement::FiniteElementBase & - fe = subRegion.template registerWrapper< finiteElement::FiniteElementBase >( discretizationName, std::move( newFE ) ). + fe = subRegion.template registerWrapper< finiteElement::FiniteElementBase >( discretizationName, std::move( newFE ), true ). setRestartFlags( RestartFlags::NO_WRITE ).reference(); subRegion.excludeWrappersFromPacking( { discretizationName } ); diff --git a/src/coreComponents/mainInterface/ProblemManager.hpp b/src/coreComponents/mainInterface/ProblemManager.hpp index 447ac419885..d2f640fe0b2 100644 --- a/src/coreComponents/mainInterface/ProblemManager.hpp +++ b/src/coreComponents/mainInterface/ProblemManager.hpp @@ -78,13 +78,15 @@ class ProblemManager : public dataRepository::Group /** * @brief Creates a new sub-Group using the ObjectCatalog functionality. - * @param childKey The name of the new object type's key in the - * ObjectCatalog. - * @param childName The name of the new object in the collection of - * sub-Groups. + * @param childKey The name of the new object type's key in the ObjectCatalog. + * @param childName The name of the new object in the collection of sub-Groups. + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return A pointer to the new Group created by this function. */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /** * @brief Parses command line input diff --git a/src/coreComponents/mesh/CellElementRegion.cpp b/src/coreComponents/mesh/CellElementRegion.cpp index 4251a8679b3..d9566a28d7f 100644 --- a/src/coreComponents/mesh/CellElementRegion.cpp +++ b/src/coreComponents/mesh/CellElementRegion.cpp @@ -63,7 +63,7 @@ void CellElementRegion::generateMesh( Group const & cellBlocks ) InputError ); // subRegion name must be the same as the cell-block (so we can match them and reference them in errors). - CellElementSubRegion & subRegion = subRegions.registerGroup< CellElementSubRegion >( cbName ); + CellElementSubRegion & subRegion = subRegions.registerGroup< CellElementSubRegion >( cbName, true ); subRegion.copyFromCellBlock( *cellBlock ); } } diff --git a/src/coreComponents/mesh/CellElementSubRegion.cpp b/src/coreComponents/mesh/CellElementSubRegion.cpp index 95b2ac8b269..48c77f7d554 100644 --- a/src/coreComponents/mesh/CellElementSubRegion.cpp +++ b/src/coreComponents/mesh/CellElementSubRegion.cpp @@ -95,10 +95,8 @@ void CellElementSubRegion::copyFromCellBlock( CellBlockABC const & cellBlock ) { using ArrayType = camp::first< decltype( tupleOfTypes ) >; auto const src = Wrapper< ArrayType >::cast( wrapper ).reference().toViewConst(); - ArrayType & dst = this->registerWrapper( wrapper.getName(), std::make_unique< ArrayType >() ).reference(); - // This is a hack since Array's copy ctor does not accept ArrayView source - dst.resize( ArrayType::NDIM, src.dims() ); - std::copy( src.data(), src.data() + src.size(), dst.data() ); + ArrayType & dst = this->registerWrapper( wrapper.getName(), std::make_unique< ArrayType >(), true ).reference(); + dst = src; }, wrapper ); } ); } diff --git a/src/coreComponents/mesh/ElementRegionManager.cpp b/src/coreComponents/mesh/ElementRegionManager.cpp index 0ba6bfc2b84..7d73fae6dec 100644 --- a/src/coreComponents/mesh/ElementRegionManager.cpp +++ b/src/coreComponents/mesh/ElementRegionManager.cpp @@ -77,22 +77,23 @@ auto const & getUserAvailableKeys() return keys; } -Group * ElementRegionManager::createChild( string const & childKey, string const & childName ) +Group * ElementRegionManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); GEOS_ERROR_IF( getUserAvailableKeys().count( childKey ) == 0, CatalogInterface::unknownTypeError( childKey, getDataContext(), getUserAvailableKeys() ) ); Group & elementRegions = this->getGroup( ElementRegionManager::groupKeyStruct::elementRegionsGroup() ); - return &elementRegions.registerGroup( childName, - CatalogInterface::factory( childKey, getDataContext(), - childName, &elementRegions ) ); + return &elementRegions.registerGroup( CatalogInterface::factory( childKey, getDataContext(), + childName, &elementRegions ), allowExistence ); } void ElementRegionManager::expandObjectCatalogs() { for( string const & key : getUserAvailableKeys() ) { - this->createChild( key, key ); + this->createChild( key, key, true ); } } @@ -268,7 +269,8 @@ void ElementRegionManager::buildSets( NodeManager const & nodeManager ) { arrayView1d< bool const > const nodeInCurSet = nodeInSet[setName]; - SortedArray< localIndex > & targetSet = elementSets.registerWrapper< SortedArray< localIndex > >( setName ).reference(); + SortedArray< localIndex > & targetSet = elementSets.registerWrapper< SortedArray< localIndex > >( setName, true ).reference(); + targetSet.clear(); for( localIndex k = 0; k < subRegion.size(); ++k ) { localIndex const numNodes = subRegion.numNodesPerElement( k ); diff --git a/src/coreComponents/mesh/ElementRegionManager.hpp b/src/coreComponents/mesh/ElementRegionManager.hpp index 26c705438dc..09c64bb5228 100644 --- a/src/coreComponents/mesh/ElementRegionManager.hpp +++ b/src/coreComponents/mesh/ElementRegionManager.hpp @@ -169,9 +169,13 @@ class ElementRegionManager : public ObjectManagerBase * @brief Create a new ElementRegion object as a child of this group. * @param childKey catalog key of the new ElementRegion derived type to create * @param childName name of the new ElementRegion object + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return pointer to the created ElementRegion object */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; // virtual void ReadXMLsub( xmlWrapper::xmlNode const & targetNode ) override; /** diff --git a/src/coreComponents/mesh/ElementSubRegionBase.cpp b/src/coreComponents/mesh/ElementSubRegionBase.cpp index 6234dbaca94..92fdc340244 100644 --- a/src/coreComponents/mesh/ElementSubRegionBase.cpp +++ b/src/coreComponents/mesh/ElementSubRegionBase.cpp @@ -32,7 +32,7 @@ ElementSubRegionBase::ElementSubRegionBase( string const & name, Group * const p m_elementCenter(), m_elementVolume() { - registerGroup( groupKeyStruct::constitutiveModelsString(), &m_constitutiveModels ). + registerGroup( &m_constitutiveModels ). setSizedFromParent( 1 ); registerWrapper( viewKeyStruct::numNodesPerElementString(), &m_numNodesPerElement ); diff --git a/src/coreComponents/mesh/ExternalDataSourceBase.cpp b/src/coreComponents/mesh/ExternalDataSourceBase.cpp index 9c1285764d7..65ac79e5a48 100644 --- a/src/coreComponents/mesh/ExternalDataSourceBase.cpp +++ b/src/coreComponents/mesh/ExternalDataSourceBase.cpp @@ -25,12 +25,14 @@ ExternalDataSourceBase::ExternalDataSourceBase( string const & name, Group * con setInputFlags( InputFlags::OPTIONAL_NONUNIQUE ); } -Group * ExternalDataSourceBase::createChild( string const & childKey, string const & childName ) +Group * ExternalDataSourceBase::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< ExternalDataSourceBase > event = ExternalDataSourceBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup( childName, std::move( event ) ); + return &this->registerGroup( std::move( event ), allowExistence ); } void ExternalDataSourceBase::expandObjectCatalogs() diff --git a/src/coreComponents/mesh/ExternalDataSourceBase.hpp b/src/coreComponents/mesh/ExternalDataSourceBase.hpp index 0e2f9a4ab17..a273b2bbc6a 100644 --- a/src/coreComponents/mesh/ExternalDataSourceBase.hpp +++ b/src/coreComponents/mesh/ExternalDataSourceBase.hpp @@ -56,9 +56,13 @@ class ExternalDataSourceBase : public dataRepository::Group * @brief Create a new geometric object (box, plane, etc) as a child of this group. * @param childKey the catalog key of the new geometric object to create * @param childName the name of the new geometric object in the repository + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return the group child */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /** * @brief Accessor for the singleton Catalog object diff --git a/src/coreComponents/mesh/ExternalDataSourceManager.cpp b/src/coreComponents/mesh/ExternalDataSourceManager.cpp index 969ab7a043d..dbe2c197351 100644 --- a/src/coreComponents/mesh/ExternalDataSourceManager.cpp +++ b/src/coreComponents/mesh/ExternalDataSourceManager.cpp @@ -33,12 +33,14 @@ ExternalDataSourceManager::ExternalDataSourceManager( string const & name, ExternalDataSourceManager::~ExternalDataSourceManager() {} -Group * ExternalDataSourceManager::createChild( string const & childKey, string const & childName ) +Group * ExternalDataSourceManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< ExternalDataSourceBase > externalDataSource = ExternalDataSourceBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup< ExternalDataSourceBase >( childName, std::move( externalDataSource ) ); + return &this->registerGroup< ExternalDataSourceBase >( std::move( externalDataSource ), allowExistence ); } diff --git a/src/coreComponents/mesh/ExternalDataSourceManager.hpp b/src/coreComponents/mesh/ExternalDataSourceManager.hpp index 28ccecb2fc1..3074e1a66ad 100644 --- a/src/coreComponents/mesh/ExternalDataSourceManager.hpp +++ b/src/coreComponents/mesh/ExternalDataSourceManager.hpp @@ -49,9 +49,13 @@ class ExternalDataSourceManager : public dataRepository::Group * @brief Create a new sub data repository. * @param[in] childKey the key of the new object in the ObjectCatalog * @param[in] childName the name of the new object in the collection of sub-meshes + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return A pointer to the Group node in the dataRepository of the new object created */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /// This function is used to expand any catalogs in the data structure virtual void expandObjectCatalogs() override; diff --git a/src/coreComponents/mesh/MeshBody.cpp b/src/coreComponents/mesh/MeshBody.cpp index 17d558f0fb7..1167711c7f9 100644 --- a/src/coreComponents/mesh/MeshBody.cpp +++ b/src/coreComponents/mesh/MeshBody.cpp @@ -35,12 +35,12 @@ MeshBody::MeshBody( string const & name, MeshLevel & MeshBody::createMeshLevel( localIndex const newLevel ) { - return m_meshLevels.registerGroup< MeshLevel >( intToMeshLevelString( newLevel ) ); + return m_meshLevels.registerGroup< MeshLevel >( intToMeshLevelString( newLevel ), true ); } MeshLevel & MeshBody::createMeshLevel( string const & name ) { - return m_meshLevels.registerGroup< MeshLevel >( name ); + return m_meshLevels.registerGroup< MeshLevel >( name, true ); } MeshLevel & MeshBody::createMeshLevel( string const & sourceLevelName, @@ -48,8 +48,7 @@ MeshLevel & MeshBody::createMeshLevel( string const & sourceLevelName, int const order ) { MeshLevel const & sourceMeshLevel = this->getMeshLevel( sourceLevelName ); - return m_meshLevels.registerGroup( newLevelName, - std::make_unique< MeshLevel >( newLevelName, + return m_meshLevels.registerGroup( std::make_unique< MeshLevel >( newLevelName, this, sourceMeshLevel, order ) ); @@ -60,8 +59,7 @@ MeshLevel & MeshBody::createShallowMeshLevel( string const & sourceLevelName, { MeshLevel & sourceMeshLevel = this->getMeshLevel( sourceLevelName ); - MeshLevel & rval = m_meshLevels.registerGroup( newLevelName, - std::make_unique< MeshLevel >( newLevelName, + MeshLevel & rval = m_meshLevels.registerGroup( std::make_unique< MeshLevel >( newLevelName, this, sourceMeshLevel ) ); rval.setRestartFlags( RestartFlags::NO_WRITE ); diff --git a/src/coreComponents/mesh/MeshLevel.cpp b/src/coreComponents/mesh/MeshLevel.cpp index bc59224acb8..441147b7ea3 100644 --- a/src/coreComponents/mesh/MeshLevel.cpp +++ b/src/coreComponents/mesh/MeshLevel.cpp @@ -43,22 +43,22 @@ MeshLevel::MeshLevel( string const & name, m_shallowParent( nullptr ) { - registerGroup( groupStructKeys::nodeManagerString(), m_nodeManager.get() ); + registerGroup( m_nodeManager.get() ); - registerGroup( groupStructKeys::particleManagerString(), m_particleManager.get() ); + registerGroup( m_particleManager.get() ); - registerGroup( groupStructKeys::edgeManagerString(), m_edgeManager.get() ); + registerGroup( m_edgeManager.get() ); - registerGroup< FaceManager >( groupStructKeys::faceManagerString(), m_faceManager.get() ); + registerGroup< FaceManager >( m_faceManager.get() ); m_faceManager->nodeList().setRelatedObject( *m_nodeManager ); - registerGroup< ElementRegionManager >( groupStructKeys::elemManagerString(), m_elementManager.get() ); + registerGroup< ElementRegionManager >( m_elementManager.get() ); - registerGroup< EdgeManager >( groupStructKeys::embSurfEdgeManagerString, m_embSurfEdgeManager.get() ); + registerGroup< EdgeManager >( m_embSurfEdgeManager.get() ); - registerGroup< EmbeddedSurfaceNodeManager >( groupStructKeys::embSurfNodeManagerString, m_embSurfNodeManager.get() ); + registerGroup< EmbeddedSurfaceNodeManager >( m_embSurfNodeManager.get() ); registerWrapper< integer >( viewKeys.meshLevel ); @@ -85,20 +85,20 @@ MeshLevel::MeshLevel( string const & name, { this->setRestartFlags( RestartFlags::NO_WRITE ); - registerGroup( groupStructKeys::nodeManagerString(), m_nodeManager.get() ); + registerGroup( m_nodeManager.get() ); - registerGroup( groupStructKeys::edgeManagerString(), m_edgeManager.get() ); + registerGroup( m_edgeManager.get() ); - registerGroup< FaceManager >( groupStructKeys::faceManagerString(), m_faceManager.get() ); + registerGroup< FaceManager >( m_faceManager.get() ); m_faceManager->nodeList().setRelatedObject( *m_nodeManager ); - registerGroup< ElementRegionManager >( groupStructKeys::elemManagerString(), m_elementManager.get() ); + registerGroup< ElementRegionManager >( m_elementManager.get() ); - registerGroup< EdgeManager >( groupStructKeys::embSurfEdgeManagerString, m_embSurfEdgeManager.get() ); + registerGroup< EdgeManager >( m_embSurfEdgeManager.get() ); - registerGroup< EmbeddedSurfaceNodeManager >( groupStructKeys::embSurfNodeManagerString, m_embSurfNodeManager.get() ); + registerGroup< EmbeddedSurfaceNodeManager >( m_embSurfNodeManager.get() ); registerWrapper< integer >( viewKeys.meshLevel ); @@ -502,7 +502,8 @@ void MeshLevel::generateSets() { arrayView1d< bool const > const nodeInCurSet = nodeInSet[setName]; - SortedArray< localIndex > & targetSet = elementSets.registerWrapper< SortedArray< localIndex > >( setName ).reference(); + SortedArray< localIndex > & targetSet = elementSets.getReference< SortedArray< localIndex > >( setName ); + targetSet.clear(); for( localIndex k = 0; k < subRegion.size(); ++k ) { localIndex const numNodes = subRegion.numNodesPerElement( k ); diff --git a/src/coreComponents/mesh/MeshManager.cpp b/src/coreComponents/mesh/MeshManager.cpp index 2a67aa8db22..10411ead011 100644 --- a/src/coreComponents/mesh/MeshManager.cpp +++ b/src/coreComponents/mesh/MeshManager.cpp @@ -43,12 +43,14 @@ MeshManager::MeshManager( string const & name, MeshManager::~MeshManager() {} -Group * MeshManager::createChild( string const & childKey, string const & childName ) +Group * MeshManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< MeshGeneratorBase > mesh = MeshGeneratorBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup< MeshGeneratorBase >( childName, std::move( mesh ) ); + return &this->registerGroup< MeshGeneratorBase >( std::move( mesh ), allowExistence ); } @@ -66,7 +68,7 @@ void MeshManager::generateMeshes( DomainPartition & domain ) { forSubGroups< MeshGeneratorBase >( [&]( MeshGeneratorBase & meshGen ) { - MeshBody & meshBody = domain.getMeshBodies().registerGroup< MeshBody >( meshGen.getName() ); + MeshBody & meshBody = domain.getMeshBodies().registerGroup< MeshBody >( meshGen.getName(), true ); meshBody.createMeshLevel( 0 ); SpatialPartition & partition = dynamic_cast< SpatialPartition & >(domain.getReference< PartitionBase >( keys::partitionManager ) ); @@ -87,7 +89,7 @@ void MeshManager::generateMeshLevels( DomainPartition & domain ) forSubGroups< MeshGeneratorBase >( [&]( MeshGeneratorBase & meshGen ) { string const & meshName = meshGen.getName(); - domain.getMeshBodies().registerGroup< MeshBody >( meshName ).createMeshLevel( MeshBody::groupStructKeys::baseDiscretizationString() ); + domain.getMeshBodies().registerGroup< MeshBody >( meshName, true ).createMeshLevel( MeshBody::groupStructKeys::baseDiscretizationString() ); } ); } diff --git a/src/coreComponents/mesh/MeshManager.hpp b/src/coreComponents/mesh/MeshManager.hpp index 886d85692d8..bea961c9dfe 100644 --- a/src/coreComponents/mesh/MeshManager.hpp +++ b/src/coreComponents/mesh/MeshManager.hpp @@ -50,9 +50,13 @@ class MeshManager : public dataRepository::Group * @brief Create a new sub-mesh. * @param[in] childKey the key of the new object in the ObjectCatalog * @param[in] childName the name of the new object in the collection of sub-meshes + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return A pointer to the Group node in the dataRepository of the new object created */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /// This function is used to expand any catalogs in the data structure virtual void expandObjectCatalogs() override; diff --git a/src/coreComponents/mesh/NodeManager.cpp b/src/coreComponents/mesh/NodeManager.cpp index 2454f375e53..50aaf9e1522 100644 --- a/src/coreComponents/mesh/NodeManager.cpp +++ b/src/coreComponents/mesh/NodeManager.cpp @@ -100,7 +100,8 @@ void NodeManager::buildGeometricSets( GeometricObjectManager const & geometries geometries.forSubGroups< SimpleGeometricObjectBase >( [&]( SimpleGeometricObjectBase const & object ) { string const & name = object.getName(); - SortedArray< localIndex > & targetSet = m_sets.registerWrapper< SortedArray< localIndex > >( name ).reference(); + SortedArray< localIndex > & targetSet = m_sets.registerWrapper< SortedArray< localIndex > >( name, true ).reference(); + targetSet.clear(); for( localIndex a = 0; a < numNodes; ++a ) { real64 nodeCoord[3] = LVARRAY_TENSOROPS_INIT_LOCAL_3( X[a] ); diff --git a/src/coreComponents/mesh/ObjectManagerBase.cpp b/src/coreComponents/mesh/ObjectManagerBase.cpp index cf138599d46..f836560b83d 100644 --- a/src/coreComponents/mesh/ObjectManagerBase.cpp +++ b/src/coreComponents/mesh/ObjectManagerBase.cpp @@ -39,8 +39,8 @@ ObjectManagerBase::ObjectManagerBase( string const & name, m_ghostRank(), m_neighborData() { - registerGroup( groupKeyStruct::setsString(), &m_sets ); - registerGroup( groupKeyStruct::neighborDataString(), &m_neighborGroup ); + registerGroup( &m_sets ); + registerGroup( &m_neighborGroup ); registerWrapper( viewKeyStruct::localToGlobalMapString(), &m_localToGlobalMap ). setApplyDefaultValue( -1 ). @@ -89,7 +89,9 @@ ObjectManagerBase::CatalogInterface::CatalogType & ObjectManagerBase::getCatalog SortedArray< localIndex > & ObjectManagerBase::createSet( const string & newSetName ) { - return m_sets.registerWrapper< SortedArray< localIndex > >( newSetName ).reference(); + auto & set = m_sets.registerWrapper< SortedArray< localIndex > >( newSetName, true ).reference(); + set.clear(); + return set; } void ObjectManagerBase::constructSetFromSetAndMap( SortedArrayView< localIndex const > const & inputSet, diff --git a/src/coreComponents/mesh/ObjectManagerBase.hpp b/src/coreComponents/mesh/ObjectManagerBase.hpp index 62b7814e8d1..c1838de6629 100644 --- a/src/coreComponents/mesh/ObjectManagerBase.hpp +++ b/src/coreComponents/mesh/ObjectManagerBase.hpp @@ -574,7 +574,7 @@ class ObjectManagerBase : public dataRepository::Group m_registeredField.insert( FIELD_TRAIT::key()); - return this->registerWrapper< typename FIELD_TRAIT::type >( FIELD_TRAIT::key() ). + return this->registerWrapper< typename FIELD_TRAIT::type >( FIELD_TRAIT::key(), nullptr, true ). setApplyDefaultValue( defaultValue ). setPlotLevel( FIELD_TRAIT::plotLevel ). setRestartFlags( FIELD_TRAIT::restartFlag ). @@ -887,7 +887,7 @@ class ObjectManagerBase : public dataRepository::Group { string const & rankString = std::to_string( rank ); m_neighborData.emplace( std::piecewise_construct, std::make_tuple( rank ), std::make_tuple( rankString, &m_neighborGroup ) ); - m_neighborGroup.registerGroup( rankString, &getNeighborData( rank ) ); + m_neighborGroup.registerGroup( &getNeighborData( rank ) ); } /** diff --git a/src/coreComponents/mesh/ParticleManager.cpp b/src/coreComponents/mesh/ParticleManager.cpp index 57bd1687935..d7b67d6ae34 100644 --- a/src/coreComponents/mesh/ParticleManager.cpp +++ b/src/coreComponents/mesh/ParticleManager.cpp @@ -82,13 +82,14 @@ void ParticleManager::setMaxGlobalIndex() MPI_COMM_GEOS ); } -Group * ParticleManager::createChild( string const & childKey, string const & childName ) +Group * ParticleManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); Group & particleRegions = this->getGroup( ParticleManager::groupKeyStruct::particleRegionsGroup() ); - return &particleRegions.registerGroup( childName, - CatalogInterface::factory( childKey, getDataContext(), - childName, &particleRegions ) ); + return &particleRegions.registerGroup( CatalogInterface::factory( childKey, getDataContext(), + childName, &particleRegions ), allowExistence ); } void ParticleManager::expandObjectCatalogs() @@ -101,7 +102,7 @@ void ParticleManager::expandObjectCatalogs() string const key = iter->first; if( key.find( "ParticleRegion" ) != string::npos ) { - this->createChild( key, key ); + this->createChild( key, key, true ); } } } diff --git a/src/coreComponents/mesh/ParticleManager.hpp b/src/coreComponents/mesh/ParticleManager.hpp index 18c93cd68a0..2ce44474ac8 100644 --- a/src/coreComponents/mesh/ParticleManager.hpp +++ b/src/coreComponents/mesh/ParticleManager.hpp @@ -150,9 +150,13 @@ class ParticleManager : public ObjectManagerBase * @brief Create a new ParticleRegion object as a child of this group. * @param childKey catalog key of the new ParticleRegion derived type to create * @param childName name of the new ParticleRegion object + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return pointer to the created ParticleRegion object */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; // virtual void ReadXMLsub( xmlWrapper::xmlNode const & targetNode ) override; /** diff --git a/src/coreComponents/mesh/ParticleSubRegionBase.cpp b/src/coreComponents/mesh/ParticleSubRegionBase.cpp index 6fd09c3ae5c..7e218202521 100644 --- a/src/coreComponents/mesh/ParticleSubRegionBase.cpp +++ b/src/coreComponents/mesh/ParticleSubRegionBase.cpp @@ -41,7 +41,7 @@ ParticleSubRegionBase::ParticleSubRegionBase( string const & name, Group * const m_particleType(), m_particleRVectors() { - registerGroup( groupKeyStruct::constitutiveModelsString(), &m_constitutiveModels ). + registerGroup( &m_constitutiveModels ). setSizedFromParent( 1 ); registerWrapper( viewKeyStruct::particleRankString(), &m_particleRank ). diff --git a/src/coreComponents/mesh/SurfaceElementRegion.cpp b/src/coreComponents/mesh/SurfaceElementRegion.cpp index c13b149358d..dc6bb407145 100644 --- a/src/coreComponents/mesh/SurfaceElementRegion.cpp +++ b/src/coreComponents/mesh/SurfaceElementRegion.cpp @@ -220,7 +220,8 @@ localIndex SurfaceElementRegion::addToFractureMesh( real64 const time_np1, for( auto const & setIter : faceManager->sets().wrappers() ) { SortedArrayView< localIndex const > const & faceSet = faceManager->sets().getReference< SortedArray< localIndex > >( setIter.first ); - SortedArray< localIndex > & faceElementSet = subRegion.sets().registerWrapper< SortedArray< localIndex > >( setIter.first ).reference(); + SortedArray< localIndex > & faceElementSet = subRegion.sets().getReference< SortedArray< localIndex > >( setIter.first ); + // faceElementSet.clear(); for( localIndex a = 0; a < faceMap.size( 0 ); ++a ) { if( faceSet.count( faceMap[a][0] ) ) diff --git a/src/coreComponents/mesh/WellElementSubRegion.cpp b/src/coreComponents/mesh/WellElementSubRegion.cpp index 1b61cc7c507..d3a2c79f575 100644 --- a/src/coreComponents/mesh/WellElementSubRegion.cpp +++ b/src/coreComponents/mesh/WellElementSubRegion.cpp @@ -47,7 +47,7 @@ WellElementSubRegion::WellElementSubRegion( string const & name, Group * const p registerWrapper( viewKeyStruct::topRankString(), &m_topRank ); registerWrapper( viewKeyStruct::radiusString(), &m_radius ); - registerGroup( groupKeyStruct::perforationDataString(), &m_perforationData ); + registerGroup( &m_perforationData ); registerWrapper( viewKeyStruct::wellLocalElementGlobalIndexString(), &m_globalWellElementIndex ); registerWrapper( viewKeyStruct::wellLocalElementStatusString(), &m_wellLocalElementStatus ); diff --git a/src/coreComponents/mesh/generators/CellBlock.hpp b/src/coreComponents/mesh/generators/CellBlock.hpp index 4d79fca2c7a..5a777e90a21 100644 --- a/src/coreComponents/mesh/generators/CellBlock.hpp +++ b/src/coreComponents/mesh/generators/CellBlock.hpp @@ -224,7 +224,7 @@ class CellBlock : public CellBlockABC T & addProperty( string const & propertyName ) { m_externalPropertyNames.emplace_back( propertyName ); - return this->registerWrapper< T >( propertyName ).reference(); + return this->registerWrapper< T >( propertyName, true ).reference(); } ///@} diff --git a/src/coreComponents/mesh/generators/CellBlockManager.cpp b/src/coreComponents/mesh/generators/CellBlockManager.cpp index 2c7be094170..52f75d68d6a 100644 --- a/src/coreComponents/mesh/generators/CellBlockManager.cpp +++ b/src/coreComponents/mesh/generators/CellBlockManager.cpp @@ -44,7 +44,9 @@ void CellBlockManager::resize( integer_array const & numElements, } } -Group * CellBlockManager::createChild( string const & GEOS_UNUSED_PARAM( childKey ), string const & GEOS_UNUSED_PARAM( childName ) ) +Group * CellBlockManager::createChild( string const & GEOS_UNUSED_PARAM( childKey ), + string const & GEOS_UNUSED_PARAM( childName ), + bool const GEOS_UNUSED_PARAM( allowExistence ) ) { // Unused as all children are created within the constructor return nullptr; @@ -767,7 +769,7 @@ localIndex CellBlockManager::numEdges() const CellBlock & CellBlockManager::registerCellBlock( string const & name ) { - return this->getCellBlocks().registerGroup< CellBlock >( name ); + return this->getCellBlocks().registerGroup< CellBlock >( name, true ); } CellBlock & CellBlockManager::registerCellBlock( string const & cellBlockName, diff --git a/src/coreComponents/mesh/generators/CellBlockManager.hpp b/src/coreComponents/mesh/generators/CellBlockManager.hpp index 251142d960a..0ccecc87c93 100644 --- a/src/coreComponents/mesh/generators/CellBlockManager.hpp +++ b/src/coreComponents/mesh/generators/CellBlockManager.hpp @@ -46,7 +46,9 @@ class CellBlockManager : public CellBlockManagerABC */ CellBlockManager( string const & name, Group * const parent ); - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /** * @brief Maximum number of nodes allowed (in memory) per each face. diff --git a/src/coreComponents/mesh/generators/MeshGeneratorBase.cpp b/src/coreComponents/mesh/generators/MeshGeneratorBase.cpp index 97dcfad0e97..59a32ec07a0 100644 --- a/src/coreComponents/mesh/generators/MeshGeneratorBase.cpp +++ b/src/coreComponents/mesh/generators/MeshGeneratorBase.cpp @@ -28,12 +28,14 @@ MeshGeneratorBase::MeshGeneratorBase( string const & name, Group * const parent setInputFlags( InputFlags::OPTIONAL_NONUNIQUE ); } -Group * MeshGeneratorBase::createChild( string const & childKey, string const & childName ) +Group * MeshGeneratorBase::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< MeshComponentBase > meshComp = MeshComponentBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup< MeshComponentBase >( childName, std::move( meshComp ) ); + return &this->registerGroup< MeshComponentBase >( std::move( meshComp ), allowExistence ); } void MeshGeneratorBase::expandObjectCatalogs() diff --git a/src/coreComponents/mesh/generators/MeshGeneratorBase.hpp b/src/coreComponents/mesh/generators/MeshGeneratorBase.hpp index 03ae359a7ac..dfe89d4d31d 100644 --- a/src/coreComponents/mesh/generators/MeshGeneratorBase.hpp +++ b/src/coreComponents/mesh/generators/MeshGeneratorBase.hpp @@ -64,9 +64,13 @@ class MeshGeneratorBase : public dataRepository::Group * @brief Create a new geometric object (box, plane, etc) as a child of this group. * @param childKey the catalog key of the new geometric object to create * @param childName the name of the new geometric object in the repository + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return the group child */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /** * @brief Accessor for the singleton Catalog object diff --git a/src/coreComponents/mesh/generators/ParticleBlockManager.cpp b/src/coreComponents/mesh/generators/ParticleBlockManager.cpp index f219072ab8e..f45d2afd1be 100644 --- a/src/coreComponents/mesh/generators/ParticleBlockManager.cpp +++ b/src/coreComponents/mesh/generators/ParticleBlockManager.cpp @@ -36,7 +36,9 @@ void ParticleBlockManager::resize( integer_array const & numParticles, } } -Group * ParticleBlockManager::createChild( string const & GEOS_UNUSED_PARAM( childKey ), string const & GEOS_UNUSED_PARAM( childName ) ) +Group * ParticleBlockManager::createChild( string const & GEOS_UNUSED_PARAM( childKey ), + string const & GEOS_UNUSED_PARAM( childName ), + bool const GEOS_UNUSED_PARAM( allowExistence ) ) { // Unused as all children are created within the constructor return nullptr; diff --git a/src/coreComponents/mesh/generators/ParticleBlockManager.hpp b/src/coreComponents/mesh/generators/ParticleBlockManager.hpp index 87e69c767e3..9dbd8ae1350 100644 --- a/src/coreComponents/mesh/generators/ParticleBlockManager.hpp +++ b/src/coreComponents/mesh/generators/ParticleBlockManager.hpp @@ -41,7 +41,9 @@ class ParticleBlockManager : public ParticleBlockManagerABC */ ParticleBlockManager( string const & name, Group * const parent ); - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; using Group::resize; diff --git a/src/coreComponents/mesh/generators/ParticleMeshGenerator.cpp b/src/coreComponents/mesh/generators/ParticleMeshGenerator.cpp index 334287fca69..78a31f2b07b 100644 --- a/src/coreComponents/mesh/generators/ParticleMeshGenerator.cpp +++ b/src/coreComponents/mesh/generators/ParticleMeshGenerator.cpp @@ -59,7 +59,8 @@ ParticleMeshGenerator::ParticleMeshGenerator( string const & name, Group * const } Group * ParticleMeshGenerator::createChild( string const & GEOS_UNUSED_PARAM( childKey ), - string const & GEOS_UNUSED_PARAM( childName ) ) + string const & GEOS_UNUSED_PARAM( childName ), + bool const GEOS_UNUSED_PARAM( allowExistence ) ) { return nullptr; } diff --git a/src/coreComponents/mesh/generators/ParticleMeshGenerator.hpp b/src/coreComponents/mesh/generators/ParticleMeshGenerator.hpp index 91bb1e2208e..9a33406ea27 100644 --- a/src/coreComponents/mesh/generators/ParticleMeshGenerator.hpp +++ b/src/coreComponents/mesh/generators/ParticleMeshGenerator.hpp @@ -57,9 +57,13 @@ class ParticleMeshGenerator : public MeshGeneratorBase * @brief Create a new geometric object (box, plane, etc) as a child of this group. * @param childKey the catalog key of the new geometric object to create * @param childName the name of the new geometric object in the repository + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return the group child */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; virtual void fillParticleBlockManager( ParticleBlockManager & particleBlockManager, ParticleManager & particleManager, SpatialPartition const & partition ) override; diff --git a/src/coreComponents/mesh/generators/WellGeneratorBase.cpp b/src/coreComponents/mesh/generators/WellGeneratorBase.cpp index c92967ed8dc..9d0bc8c97ec 100644 --- a/src/coreComponents/mesh/generators/WellGeneratorBase.cpp +++ b/src/coreComponents/mesh/generators/WellGeneratorBase.cpp @@ -75,7 +75,9 @@ WellGeneratorBase::WellGeneratorBase( string const & name, Group * const parent addLogLevel< logInfo::GenerateWell >(); } -Group * WellGeneratorBase::createChild( string const & childKey, string const & childName ) +Group * WellGeneratorBase::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); const auto childTypes = { viewKeyStruct::perforationString() }; @@ -85,7 +87,7 @@ Group * WellGeneratorBase::createChild( string const & childKey, string const & ++m_numPerforations; m_perforationList.emplace_back( childName ); - return ®isterGroup< Perforation >( childName ); + return ®isterGroup< Perforation >( childName, allowExistence ); } void WellGeneratorBase::expandObjectCatalogs() diff --git a/src/coreComponents/mesh/generators/WellGeneratorBase.hpp b/src/coreComponents/mesh/generators/WellGeneratorBase.hpp index e9a2dd81046..125ecb26ab6 100644 --- a/src/coreComponents/mesh/generators/WellGeneratorBase.hpp +++ b/src/coreComponents/mesh/generators/WellGeneratorBase.hpp @@ -54,9 +54,13 @@ class WellGeneratorBase : public MeshComponentBase * @brief Create a new geometric object (box, plane, etc) as a child of this group. * @param childKey the catalog key of the new geometric object to create * @param childName the name of the new geometric object in the repository + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return the group child */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /** * @brief Main function of the class that generates the well geometry diff --git a/src/coreComponents/mesh/simpleGeometricObjects/GeometricObjectManager.cpp b/src/coreComponents/mesh/simpleGeometricObjects/GeometricObjectManager.cpp index 4209636f4d5..e01b569caae 100644 --- a/src/coreComponents/mesh/simpleGeometricObjects/GeometricObjectManager.cpp +++ b/src/coreComponents/mesh/simpleGeometricObjects/GeometricObjectManager.cpp @@ -51,12 +51,14 @@ GeometricObjectManager & GeometricObjectManager::getInstance() return *m_instance; } -Group * GeometricObjectManager::createChild( string const & childKey, string const & childName ) +Group * GeometricObjectManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); - std::unique_ptr< SimpleGeometricObjectBase > geometriObject = + std::unique_ptr< SimpleGeometricObjectBase > geometricObject = SimpleGeometricObjectBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return &this->registerGroup< SimpleGeometricObjectBase >( childName, std::move( geometriObject ) ); + return &this->registerGroup< SimpleGeometricObjectBase >( std::move( geometricObject ), allowExistence ); } void GeometricObjectManager::expandObjectCatalogs() diff --git a/src/coreComponents/mesh/simpleGeometricObjects/GeometricObjectManager.hpp b/src/coreComponents/mesh/simpleGeometricObjects/GeometricObjectManager.hpp index 7aef070b24f..3729e99a403 100644 --- a/src/coreComponents/mesh/simpleGeometricObjects/GeometricObjectManager.hpp +++ b/src/coreComponents/mesh/simpleGeometricObjects/GeometricObjectManager.hpp @@ -60,7 +60,9 @@ class GeometricObjectManager : public dataRepository::Group */ static GeometricObjectManager & getInstance(); - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /** * @brief This function is used to launch a unction over the target geometric objects with region type = diff --git a/src/coreComponents/physicsSolvers/LinearSolverParameters.cpp b/src/coreComponents/physicsSolvers/LinearSolverParameters.cpp index 1c8157ef574..00dcd4c3ea5 100644 --- a/src/coreComponents/physicsSolvers/LinearSolverParameters.cpp +++ b/src/coreComponents/physicsSolvers/LinearSolverParameters.cpp @@ -39,7 +39,7 @@ using namespace dataRepository; template< typename CHILD, typename T > void registerInputBlock( Group * parent, char const * const key, T & data ) { - parent->registerGroup( key, std::make_unique< CHILD >( key, parent, data ) ).setInputFlags( InputFlags::OPTIONAL ); + parent->registerGroup( std::make_unique< CHILD >( key, parent, data ) ).setInputFlags( InputFlags::OPTIONAL ); } class BlockParametersInput final : public dataRepository::Group @@ -51,9 +51,11 @@ class BlockParametersInput final : public dataRepository::Group Group * const parent, LinearSolverParameters::Block & params ); - virtual Group * createChild( string const & childKey, string const & childName ) override + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override { - GEOS_UNUSED_VAR( childKey, childName ); + GEOS_UNUSED_VAR( childKey, childName, allowExistence ); return nullptr; } @@ -105,9 +107,11 @@ class SmootherParametersInput final : public dataRepository::Group Group * const parent, LinearSolverParameters::Multiscale::Smoother & params ); - virtual Group * createChild( string const & childKey, string const & childName ) override + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override { - GEOS_UNUSED_VAR( childKey, childName ); + GEOS_UNUSED_VAR( childKey, childName, allowExistence ); return nullptr; } @@ -158,9 +162,11 @@ class CoupledParametersInput final : public dataRepository::Group Group * const parent, LinearSolverParameters::Multiscale::Coupled & params ); - virtual Group * createChild( string const & childKey, string const & childName ) override + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override { - GEOS_UNUSED_VAR( childKey, childName ); + GEOS_UNUSED_VAR( childKey, childName, allowExistence ); return nullptr; } @@ -197,9 +203,11 @@ class StructuredParametersInput final : public dataRepository::Group Group * const parent, LinearSolverParameters::Multiscale::Coarsening::Structured & params ); - virtual Group * createChild( string const & childKey, string const & childName ) override + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override { - GEOS_UNUSED_VAR( childKey, childName ); + GEOS_UNUSED_VAR( childKey, childName, allowExistence ); return nullptr; } @@ -236,9 +244,11 @@ class MetisParametersInput final : public dataRepository::Group Group * const parent, LinearSolverParameters::Multiscale::Coarsening::Graph::Metis & params ); - virtual Group * createChild( string const & childKey, string const & childName ) override + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override { - GEOS_UNUSED_VAR( childKey, childName ); + GEOS_UNUSED_VAR( childKey, childName, allowExistence ); return nullptr; } @@ -288,9 +298,11 @@ class GraphParametersInput final : public dataRepository::Group Group * const parent, LinearSolverParameters::Multiscale::Coarsening::Graph & params ); - virtual Group * createChild( string const & childKey, string const & childName ) override + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override { - GEOS_UNUSED_VAR( childKey, childName ); + GEOS_UNUSED_VAR( childKey, childName, allowExistence ); return nullptr; } @@ -355,9 +367,11 @@ class CoarseningParametersInput final : public dataRepository::Group Group * const parent, LinearSolverParameters::Multiscale::Coarsening & params ); - virtual Group * createChild( string const & childKey, string const & childName ) override + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override { - GEOS_UNUSED_VAR( childKey, childName ); + GEOS_UNUSED_VAR( childKey, childName, allowExistence ); return nullptr; } @@ -420,9 +434,11 @@ class MsrsbParametersInput final : public dataRepository::Group Group * const parent, LinearSolverParameters::Multiscale::MsRSB & params ); - virtual Group * createChild( string const & childKey, string const & childName ) override + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override { - GEOS_UNUSED_VAR( childKey, childName ); + GEOS_UNUSED_VAR( childKey, childName, allowExistence ); return nullptr; } @@ -495,9 +511,11 @@ class MultiscaleParametersInput final : public dataRepository::Group Group * const parent, LinearSolverParameters::Multiscale & params ); - virtual Group * createChild( string const & childKey, string const & childName ) override + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override { - GEOS_UNUSED_VAR( childKey, childName ); + GEOS_UNUSED_VAR( childKey, childName, allowExistence ); return nullptr; } @@ -872,9 +890,10 @@ void LinearSolverParametersInput::postInputInitialization() } Group * LinearSolverParametersInput::createChild( string const & childKey, - string const & childName ) + string const & childName, + bool const allowExistence ) { - GEOS_UNUSED_VAR( childKey, childName ); + GEOS_UNUSED_VAR( childKey, childName, allowExistence ); return nullptr; } diff --git a/src/coreComponents/physicsSolvers/LinearSolverParameters.hpp b/src/coreComponents/physicsSolvers/LinearSolverParameters.hpp index 759b558e261..2535aaa4935 100644 --- a/src/coreComponents/physicsSolvers/LinearSolverParameters.hpp +++ b/src/coreComponents/physicsSolvers/LinearSolverParameters.hpp @@ -54,7 +54,9 @@ class LinearSolverParametersInput : public dataRepository::Group void print(); - virtual Group * createChild( string const & childKey, string const & childName ) override final; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override final; LinearSolverParameters const & get() const { return m_parameters; } diff --git a/src/coreComponents/physicsSolvers/PhysicsSolverBase.cpp b/src/coreComponents/physicsSolvers/PhysicsSolverBase.cpp index 7448c5ec46d..187bc285feb 100644 --- a/src/coreComponents/physicsSolvers/PhysicsSolverBase.cpp +++ b/src/coreComponents/physicsSolvers/PhysicsSolverBase.cpp @@ -124,9 +124,9 @@ PhysicsSolverBase::PhysicsSolverBase( string const & name, addLogLevel< logInfo::TimeStep >(); addLogLevel< logInfo::Timers >(); - registerGroup( groupKeyStruct::linearSolverParametersString(), &m_linearSolverParameters ); - registerGroup( groupKeyStruct::nonlinearSolverParametersString(), &m_nonlinearSolverParameters ); - registerGroup( groupKeyStruct::solverStatisticsString(), &m_solverStatistics ); + registerGroup( &m_linearSolverParameters ); + registerGroup( &m_nonlinearSolverParameters ); + registerGroup( &m_solverStatistics ); m_localMatrix.setName( this->getName() + "/localMatrix" ); m_matrix.setDofManager( &m_dofManager ); @@ -222,7 +222,9 @@ void PhysicsSolverBase::registerDataOnMesh( Group & meshBodies ) -Group * PhysicsSolverBase::createChild( string const & GEOS_UNUSED_PARAM( childKey ), string const & GEOS_UNUSED_PARAM( childName ) ) +Group * PhysicsSolverBase::createChild( string const & GEOS_UNUSED_PARAM( childKey ), + string const & GEOS_UNUSED_PARAM( childName ), + bool const GEOS_UNUSED_PARAM( allowExistence ) ) { // Unused as all children are created within the constructor return nullptr; diff --git a/src/coreComponents/physicsSolvers/PhysicsSolverBase.hpp b/src/coreComponents/physicsSolvers/PhysicsSolverBase.hpp index b02c106a751..a81755abd25 100644 --- a/src/coreComponents/physicsSolvers/PhysicsSolverBase.hpp +++ b/src/coreComponents/physicsSolvers/PhysicsSolverBase.hpp @@ -701,9 +701,13 @@ class PhysicsSolverBase : public ExecutableGroup * @brief creates a child group of of this PhysicsSolverBase instantiation * @param childKey the key of the child type * @param childName the name of the child + * @param[in] allowExistence Whether to error out if an sub group already exists with the same name, + * or return the existing object. * @return a pointer to the child group */ - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /** * @brief Type alias for catalog interface used by this class. See CatalogInterface. @@ -1260,12 +1264,12 @@ string PhysicsSolverBase::getConstitutiveName( ParticleSubRegionBase const & sub template< typename CONSTITUTIVE > void PhysicsSolverBase::setConstitutiveName( ElementSubRegionBase & subRegion, string const & wrapperName, string const & constitutiveType ) const { - subRegion.registerWrapper< string >( wrapperName ). - setPlotLevel( dataRepository::PlotLevel::NOPLOT ). - setRestartFlags( dataRepository::RestartFlags::NO_WRITE ). - setSizedFromParent( 0 ); + string & constitutiveName = subRegion.registerWrapper< string >( wrapperName, true ). + setPlotLevel( dataRepository::PlotLevel::NOPLOT ). + setRestartFlags( dataRepository::RestartFlags::NO_WRITE ). + setSizedFromParent( 0 ). + reference(); - string & constitutiveName = subRegion.getReference< string >( wrapperName ); constitutiveName = getConstitutiveName< CONSTITUTIVE >( subRegion ); GEOS_ERROR_IF( constitutiveName.empty(), GEOS_FMT( "{}: {} constitutive model not found on subregion {}", getDataContext(), constitutiveType, subRegion.getName() ) ); diff --git a/src/coreComponents/physicsSolvers/PhysicsSolverManager.cpp b/src/coreComponents/physicsSolvers/PhysicsSolverManager.cpp index 9301cf5ee67..428ab211a7c 100644 --- a/src/coreComponents/physicsSolvers/PhysicsSolverManager.cpp +++ b/src/coreComponents/physicsSolvers/PhysicsSolverManager.cpp @@ -44,12 +44,14 @@ PhysicsSolverManager::~PhysicsSolverManager() //START_SPHINX_INCLUDE_00 -Group * PhysicsSolverManager::createChild( string const & childKey, string const & childName ) +Group * PhysicsSolverManager::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { GEOS_LOG_RANK_0( GEOS_FMT( "{}: adding {} {}", getName(), childKey, childName ) ); std::unique_ptr< PhysicsSolverBase > solver = PhysicsSolverBase::CatalogInterface::factory( childKey, getDataContext(), childName, this ); - return ®isterGroup< PhysicsSolverBase >( childName, std::move( solver ) ); + return ®isterGroup< PhysicsSolverBase >( std::move( solver ), allowExistence ); } diff --git a/src/coreComponents/physicsSolvers/PhysicsSolverManager.hpp b/src/coreComponents/physicsSolvers/PhysicsSolverManager.hpp index 8ef3ba43312..b63741c14eb 100644 --- a/src/coreComponents/physicsSolvers/PhysicsSolverManager.hpp +++ b/src/coreComponents/physicsSolvers/PhysicsSolverManager.hpp @@ -29,7 +29,9 @@ class PhysicsSolverManager : public dataRepository::Group virtual ~PhysicsSolverManager() override; - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /// This function is used to expand any catalogs in the data structure virtual void expandObjectCatalogs() override; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseBase.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseBase.cpp index efd4c0e39fa..d48e9a3f719 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseBase.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseBase.cpp @@ -1289,7 +1289,7 @@ void CompositionalMultiphaseBase::computeHydrostaticEquilibrium( DomainPartition // Step 3.5: create hydrostatic pressure table string const tableName = fs.getName() + "_" + subRegion.getName() + "_" + phaseNames[ipInit] + "_table"; - TableFunction * const presTable = dynamicCast< TableFunction * >( functionManager.createChild( TableFunction::catalogName(), tableName ) ); + TableFunction * const presTable = dynamicCast< TableFunction * >( functionManager.createChild( TableFunction::catalogName(), tableName, true ) ); presTable->setTableCoordinates( elevationValues, { units::Distance } ); presTable->setTableValues( pressureValues, units::Pressure ); presTable->setInterpolationMethod( TableFunction::InterpolationType::Linear ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp index d57772ffe81..c27256a0576 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp @@ -585,7 +585,7 @@ void SinglePhaseBase::computeHydrostaticEquilibrium( DomainPartition & domain ) // Step 3.4: create hydrostatic pressure table string const tableName = fs.getName() + "_" + subRegion.getName() + "_table"; - TableFunction * const presTable = dynamicCast< TableFunction * >( functionManager.createChild( TableFunction::catalogName(), tableName ) ); + TableFunction * const presTable = dynamicCast< TableFunction * >( functionManager.createChild( TableFunction::catalogName(), tableName, true ) ); presTable->setTableCoordinates( elevationValues, { units::Distance } ); presTable->setTableValues( pressureValues, units::Pressure ); presTable->setInterpolationMethod( TableFunction::InterpolationType::Linear ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.cpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.cpp index 14537f0d999..435442d8a20 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.cpp @@ -249,8 +249,6 @@ void CompositionalMultiphaseWell::registerDataOnMesh( Group & meshBodies ) setSizedFromParent( 0 ). reference().resizeDimension< 0, 1 >( m_numPhases, m_numComponents + 3 ); // dP, dT, dC, dQ - wellControls.registerWrapper< real64 >( viewKeyStruct::massDensityString() ); - wellControls.registerWrapper< real64 >( viewKeyStruct::currentTotalVolRateString() ); wellControls.registerWrapper< array1d< real64 > >( viewKeyStruct::dCurrentTotalVolRateString() ). setSizedFromParent( 0 ). diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.cpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.cpp index e470984d7cd..a8112446b37 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.cpp @@ -66,7 +66,9 @@ WellSolverBase::WellSolverBase( string const & name, addLogLevel< logInfo::WellControl >(); } -Group * WellSolverBase::createChild( string const & childKey, string const & childName ) +Group * WellSolverBase::createChild( string const & childKey, + string const & childName, + bool const allowExistence ) { static std::set< string > const childTypes = { keys::wellControls, @@ -77,11 +79,11 @@ Group * WellSolverBase::createChild( string const & childKey, string const & chi CatalogInterface::unknownTypeError( childKey, getDataContext(), childTypes ) ); if( childKey == keys::wellControls ) { - return ®isterGroup< WellControls >( childName ); + return ®isterGroup< WellControls >( childName, allowExistence ); } else { - PhysicsSolverBase::createChild( childKey, childName ); + PhysicsSolverBase::createChild( childKey, childName, allowExistence ); return nullptr; } } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.hpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.hpp index a8159378b50..83abe9de7c4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.hpp @@ -68,7 +68,9 @@ class WellSolverBase : public PhysicsSolverBase /// deleted move operator WellSolverBase & operator=( WellSolverBase && ) = delete; - virtual Group * createChild( string const & childKey, string const & childName ) override; + virtual Group * createChild( string const & childKey, + string const & childName, + bool const allowExistence=false ) override; /// Expand catalog for schema generation virtual void expandObjectCatalogs() override; diff --git a/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsSolver.hpp b/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsSolver.hpp index f553759e327..7d1f44647ca 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsSolver.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsSolver.hpp @@ -207,17 +207,6 @@ class PoromechanicsSolver : public CoupledSolver< FLOW_SOLVER, MECHANICS_SOLVER [&]( localIndex const, ElementSubRegionBase & subRegion ) { - subRegion.registerWrapper< string >( viewKeyStruct::porousMaterialNamesString() ). - setPlotLevel( dataRepository::PlotLevel::NOPLOT ). - setRestartFlags( dataRepository::RestartFlags::NO_WRITE ). - setSizedFromParent( 0 ); - - // This is needed by the way the surface generator currently does things. - subRegion.registerWrapper< string >( constitutive::CoupledSolidBase::viewKeyStruct::porosityModelNameString() ). - setPlotLevel( dataRepository::PlotLevel::NOPLOT ). - setRestartFlags( dataRepository::RestartFlags::NO_WRITE ). - setSizedFromParent( 0 ); - // register the bulk density for use in the solid mechanics solver // ideally we would resize it here as well, but the solid model name is not available yet (see below) subRegion.registerField< fields::poromechanics::bulkDensity >( this->getName() ); diff --git a/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.cpp b/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.cpp index 5c271dd8b2d..12becab51c3 100644 --- a/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.cpp +++ b/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.cpp @@ -47,17 +47,17 @@ ElasticWaveEquationSEM::ElasticWaveEquationSEM( const std::string & name, WaveSolverBase( name, parent ) { - registerWrapper( viewKeyStruct::sourceConstantsString(), &m_sourceConstantsx ). + registerWrapper( viewKeyStruct::sourceConstantsXString(), &m_sourceConstantsx ). setInputFlag( InputFlags::FALSE ). setSizedFromParent( 0 ). setDescription( "Constant part of the source for the nodes listed in m_sourceNodeIds in x-direction" ); - registerWrapper( viewKeyStruct::sourceConstantsString(), &m_sourceConstantsy ). + registerWrapper( viewKeyStruct::sourceConstantsYString(), &m_sourceConstantsy ). setInputFlag( InputFlags::FALSE ). setSizedFromParent( 0 ). setDescription( "Constant part of the source for the nodes listed in m_sourceNodeIds in y-direction" ); - registerWrapper( viewKeyStruct::sourceConstantsString(), &m_sourceConstantsz ). + registerWrapper( viewKeyStruct::sourceConstantsZString(), &m_sourceConstantsz ). setInputFlag( InputFlags::FALSE ). setSizedFromParent( 0 ). setDescription( "Constant part of the source for the nodes listed in m_sourceNodeIds in z-direction" ); diff --git a/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.hpp b/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.hpp index b57180b85df..e3b859df2a6 100644 --- a/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.hpp +++ b/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.hpp @@ -117,6 +117,10 @@ class ElasticWaveEquationSEM : public WaveSolverBase struct viewKeyStruct : WaveSolverBase::viewKeyStruct { + static constexpr char const * sourceConstantsXString() { return "sourceConstantsX"; } + static constexpr char const * sourceConstantsYString() { return "sourceConstantsY"; } + static constexpr char const * sourceConstantsZString() { return "sourceConstantsZ"; } + static constexpr char const * displacementXNp1AtReceiversString() { return "displacementXNp1AtReceivers"; } static constexpr char const * displacementYNp1AtReceiversString() { return "displacementYNp1AtReceivers"; } static constexpr char const * displacementZNp1AtReceiversString() { return "displacementZNp1AtReceivers"; } diff --git a/src/coreComponents/schema/schema.xsd b/src/coreComponents/schema/schema.xsd index e29fdc5fd0b..b0fb51f9a1f 100644 --- a/src/coreComponents/schema/schema.xsd +++ b/src/coreComponents/schema/schema.xsd @@ -6377,9 +6377,9 @@ Information output from lower logLevels is added with the desired log level - + - + - + @@ -6477,9 +6477,9 @@ The expected format is "{ waterMax, oilMax }", in that order--> - + - + @@ -6489,7 +6489,7 @@ Information output from lower logLevels is added with the desired log level - Output PVT table to log Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will still be generated.--> - + @@ -6506,9 +6506,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + @@ -6518,7 +6518,7 @@ Information output from lower logLevels is added with the desired log level - Output PVT table to log Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will still be generated.--> - + @@ -6535,9 +6535,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + @@ -6547,7 +6547,7 @@ Information output from lower logLevels is added with the desired log level - Output PVT table to log Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will still be generated.--> - + @@ -6564,9 +6564,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + @@ -6576,7 +6576,7 @@ Information output from lower logLevels is added with the desired log level - Output PVT table to log Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will still be generated.--> - + @@ -6633,9 +6633,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + @@ -6643,7 +6643,7 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + @@ -6661,9 +6661,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + @@ -6676,7 +6676,7 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + @@ -6721,9 +6721,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + @@ -6738,7 +6738,7 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + @@ -6762,9 +6762,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + @@ -6777,7 +6777,7 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + @@ -6806,9 +6806,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + @@ -6821,7 +6821,7 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + @@ -6860,9 +6860,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + @@ -6873,7 +6873,7 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + @@ -6900,9 +6900,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + @@ -6913,7 +6913,7 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + @@ -7185,9 +7185,9 @@ Even if `writeCSV ="0"`, if the table is too large for the log, a csv file will - + - + - + @@ -7986,9 +7986,9 @@ If you want to do a three-phase simulation, please use instead wettingIntermedia - + - + - + @@ -8009,9 +8009,9 @@ If the table is requested to be output in the log, and it is too large, a CSV fi - + - + - + diff --git a/src/coreComponents/schema/schema.xsd.other b/src/coreComponents/schema/schema.xsd.other index 380d963e2ef..f59d2bb3aeb 100644 --- a/src/coreComponents/schema/schema.xsd.other +++ b/src/coreComponents/schema/schema.xsd.other @@ -516,7 +516,7 @@ - + @@ -957,8 +957,14 @@ - + + + + + + + @@ -1516,7 +1522,7 @@ - +