diff --git a/kratos/includes/define.h b/kratos/includes/define.h index 92d3c887d1c0..abf561b6f04d 100644 --- a/kratos/includes/define.h +++ b/kratos/includes/define.h @@ -696,43 +696,73 @@ catch(...) { Block KRATOS_THROW_ERROR(std::runtime_error, "Unknown error", MoreI #ifdef KRATOS_REGISTER_GEOMETRY #undef KRATOS_REGISTER_GEOMETRY #endif -#define KRATOS_REGISTER_GEOMETRY(name, reference) \ - KratosComponents>::Add(name, reference); \ +#define KRATOS_REGISTER_GEOMETRY(name, reference) \ + KratosComponents>::Add(name, reference); \ + if(!Registry::HasItem("geometries."+Registry::GetCurrentSource()+"."+name) && \ + !Registry::HasItem("components."+std::string(name))){ \ + Registry::AddItem("geometries."+Registry::GetCurrentSource()+"."+name); \ + Registry::AddItem("components."+std::string(name)); \ + } \ Serializer::Register(name, reference); #ifdef KRATOS_REGISTER_ELEMENT #undef KRATOS_REGISTER_ELEMENT #endif -#define KRATOS_REGISTER_ELEMENT(name, reference) \ - KratosComponents::Add(name, reference); \ +#define KRATOS_REGISTER_ELEMENT(name, reference) \ + KratosComponents::Add(name, reference); \ + if(!Registry::HasItem("elements."+Registry::GetCurrentSource()+"."+name) && \ + !Registry::HasItem("components."+std::string(name))){ \ + Registry::AddItem("elements."+Registry::GetCurrentSource()+"."+name); \ + Registry::AddItem("components."+std::string(name)); \ + } \ Serializer::Register(name, reference); #ifdef KRATOS_REGISTER_CONDITION #undef KRATOS_REGISTER_CONDITION #endif -#define KRATOS_REGISTER_CONDITION(name, reference) \ - KratosComponents::Add(name, reference); \ +#define KRATOS_REGISTER_CONDITION(name, reference) \ + KratosComponents::Add(name, reference); \ + if(!Registry::HasItem("conditions."+Registry::GetCurrentSource()+"."+name) && \ + !Registry::HasItem("components."+std::string(name))){ \ + Registry::AddItem("conditions."+Registry::GetCurrentSource()+"."+name); \ + Registry::AddItem("components."+std::string(name)); \ + } \ Serializer::Register(name, reference); #ifdef KRATOS_REGISTER_CONSTRAINT #undef KRATOS_REGISTER_CONSTRAINT #endif -#define KRATOS_REGISTER_CONSTRAINT(name, reference) \ - KratosComponents::Add(name, reference); \ +#define KRATOS_REGISTER_CONSTRAINT(name, reference) \ + KratosComponents::Add(name, reference); \ + if(!Registry::HasItem("constraints."+Registry::GetCurrentSource()+"."+name) && \ + !Registry::HasItem("components."+std::string(name))){ \ + Registry::AddItem("constraints."+Registry::GetCurrentSource()+"."+name); \ + Registry::AddItem("components."+std::string(name)); \ + } \ Serializer::Register(name, reference); #ifdef KRATOS_REGISTER_MODELER #undef KRATOS_REGISTER_MODELER #endif -#define KRATOS_REGISTER_MODELER(name, reference) \ - KratosComponents::Add(name, reference); \ +#define KRATOS_REGISTER_MODELER(name, reference) \ + KratosComponents::Add(name, reference); \ + if(!Registry::HasItem("modelers."+Registry::GetCurrentSource()+"."+name) && \ + !Registry::HasItem("components."+std::string(name))){ \ + Registry::AddItem("modelers."+Registry::GetCurrentSource()+"."+name); \ + Registry::AddItem("components."+std::string(name)); \ + } \ Serializer::Register(name, reference); #ifdef KRATOS_REGISTER_CONSTITUTIVE_LAW #undef KRATOS_REGISTER_CONSTITUTIVE_LAW #endif -#define KRATOS_REGISTER_CONSTITUTIVE_LAW(name, reference) \ - KratosComponents::Add(name, reference); \ +#define KRATOS_REGISTER_CONSTITUTIVE_LAW(name, reference) \ + KratosComponents::Add(name, reference); \ + if(!Registry::HasItem("constitutive_laws."+Registry::GetCurrentSource()+"."+name) && \ + !Registry::HasItem("components."+std::string(name))){ \ + Registry::AddItem("constitutive_laws."+Registry::GetCurrentSource()+"."+name); \ + Registry::AddItem("components."+std::string(name)); \ + } \ Serializer::Register(name, reference); #define KRATOS_DEPRECATED [[deprecated]] diff --git a/kratos/includes/kratos_application.h b/kratos/includes/kratos_application.h index 7cc7004c339b..ee8d2e26f9b5 100644 --- a/kratos/includes/kratos_application.h +++ b/kratos/includes/kratos_application.h @@ -128,7 +128,12 @@ class KRATOS_API(KRATOS_CORE) KratosApplication { mpModelers(rOther.mpModelers) {} /// Destructor. - virtual ~KratosApplication() {} + virtual ~KratosApplication() + { + // This must be commented until tests have been fixed. + // DeregisterCommonComponents(); + // DeregisterApplication(); + } ///@} ///@name Operations @@ -141,6 +146,28 @@ class KRATOS_API(KRATOS_CORE) KratosApplication { void RegisterKratosCore(); + template + void DeregisterComponent(std::string const & rComponentName); + + /** + * @brief This method is used to unregister common components of the application. + * @details This method is used to unregister common components of the application. + * The list of unregistered components are the ones exposed in the common KratosComponents interface: + * - Geometries + * - Elements + * - Conditions + * - MasterSlaveConstraints + * - Modelers + * - ConstitutiveLaws + */ + void DeregisterCommonComponents(); + + /** + * @brief This method is used to unregister specific application components. + * @details This method is used to unregister specific application components. + */ + virtual void DeregisterApplication(); + /////////////////////////////////////////////////////////////////// void RegisterVariables(); // This contains the whole list of common variables in the Kratos Core void RegisterDeprecatedVariables(); //TODO: remove, this variables should not be there diff --git a/kratos/includes/registry.h b/kratos/includes/registry.h index 111d604ddc6c..2201940c8aaf 100644 --- a/kratos/includes/registry.h +++ b/kratos/includes/registry.h @@ -151,6 +151,18 @@ class KRATOS_API(KRATOS_CORE) Registry final static void RemoveItem(std::string const& ItemName); + /** Sets the current source of the registry + * This function is used to keep track of which application is adding items to the registry + * @param rCurrentSource The current source of the registry + */ + static void SetCurrentSource(std::string const & rCurrentSource); + + /** Gets the current source of the registry + * This function is used to keep track of which application is adding items to the registry + * @param return The current source of the registry + */ + static std::string GetCurrentSource(); + ///@} ///@name Inquiry ///@{ diff --git a/kratos/includes/registry_item.h b/kratos/includes/registry_item.h index f13de15f9999..ad1eab81bdd3 100644 --- a/kratos/includes/registry_item.h +++ b/kratos/includes/registry_item.h @@ -18,7 +18,12 @@ #include #include #include -#include + +#if defined (__GNUC__) && __GNUC__ <= 8 && __GNUC_MINOR__ <= 3 + #include +#else + #include +#endif // External includes @@ -243,7 +248,11 @@ class KRATOS_API(KRATOS_CORE) RegistryItem { KRATOS_TRY +#if defined (__GNUC__) && __GNUC__ <= 8 && __GNUC_MINOR__ <= 3 + return *(boost::any_cast>(mpValue)); +#else return *(std::any_cast>(mpValue)); +#endif KRATOS_CATCH(""); } @@ -253,7 +262,11 @@ class KRATOS_API(KRATOS_CORE) RegistryItem { KRATOS_TRY +#if defined (__GNUC__) && __GNUC__ <= 8 && __GNUC_MINOR__ <= 3 + return *std::dynamic_pointer_cast(boost::any_cast>(mpValue)); +#else return *std::dynamic_pointer_cast(std::any_cast>(mpValue)); +#endif KRATOS_CATCH(""); } @@ -293,7 +306,11 @@ class KRATOS_API(KRATOS_CORE) RegistryItem ///@{ std::string mName; +#if defined (__GNUC__) && __GNUC__ <= 8 && __GNUC_MINOR__ <= 3 + boost::any mpValue; +#else std::any mpValue; +#endif std::string (RegistryItem::*mGetValueStringMethod)() const; ///@} diff --git a/kratos/sources/kratos_application.cpp b/kratos/sources/kratos_application.cpp index 3797b4000999..756d186c6018 100644 --- a/kratos/sources/kratos_application.cpp +++ b/kratos/sources/kratos_application.cpp @@ -116,7 +116,16 @@ KratosApplication::KratosApplication(const std::string& ApplicationName) mpConditions(KratosComponents::pGetComponents()), mpModelers(KratosComponents::pGetComponents()), mpRegisteredObjects(&(Serializer::GetRegisteredObjects())), - mpRegisteredObjectsName(&(Serializer::GetRegisteredObjectsName())) {} + mpRegisteredObjectsName(&(Serializer::GetRegisteredObjectsName())) { + + Registry::SetCurrentSource(mApplicationName); + + for (auto component : {"geometries", "elements", "conditions", "constraints", "modelers", "constitutive_laws"}) { + if (!Registry::HasItem(std::string(component))) { + Registry::AddItem(std::string(component)+"."+mApplicationName); + } + } + } void KratosApplication::RegisterKratosCore() { @@ -295,4 +304,60 @@ void KratosApplication::RegisterKratosCore() { // Register ConstitutiveLaw BaseClass KRATOS_REGISTER_CONSTITUTIVE_LAW("ConstitutiveLaw", mConstitutiveLaw); } + +template +void KratosApplication::DeregisterComponent(std::string const & rComponentName) { + auto path = std::string(rComponentName)+"."+mApplicationName; + + // Remove only if the application has this type of components registered + if (Registry::HasItem(path)) { + + // Generate a temporal list with all the keys to avoid invalidating the iterator (Convert this into a transform range when C++20 is available) + std::vector keys; + std::transform(Registry::GetItem(path).cbegin(), Registry::GetItem(path).cend(), std::back_inserter(keys), [](auto & key){return std::string(key.first);}); + + for (auto & key : keys) { + auto cmpt_key = "components."+key; + auto type_key = path+"."+key; + + // Remove from KratosComponents + KratosComponents::Remove(key); + + // Remove from registry general component list + if (Registry::HasItem(cmpt_key)) { + Registry::RemoveItem(cmpt_key); + } else { + KRATOS_ERROR << "Trying ro remove: " << cmpt_key << " which was not found in registry" << std::endl; + } + + // Remove from registry component typed list + if (Registry::HasItem(type_key)) { + Registry::RemoveItem(type_key); + } else { + KRATOS_ERROR << "Trying ro remove: " << type_key << " which was not found in registry" << std::endl; + } + } + + // Finally, remove the entry all together + Registry::RemoveItem(path); + } +} + +void KratosApplication::DeregisterCommonComponents() +{ + KRATOS_INFO("") << "Deregistering " << mApplicationName << std::endl; + + DeregisterComponent>("geometries"); + DeregisterComponent("elements"); + DeregisterComponent("conditions"); + DeregisterComponent("constraints"); + DeregisterComponent("modelers"); + DeregisterComponent("constitutive_laws"); +} + +void KratosApplication::DeregisterApplication() { + // DeregisterLinearSolvers(); + // DeregisterPreconditioners(); +} + } // namespace Kratos. diff --git a/kratos/sources/registry.cpp b/kratos/sources/registry.cpp index 17487dbecefd..96bf2491fc6c 100644 --- a/kratos/sources/registry.cpp +++ b/kratos/sources/registry.cpp @@ -80,6 +80,30 @@ namespace } } + void Registry::SetCurrentSource(std::string const & rCurrentSource) + { + // If context key not present, create it + if (Registry::HasItem("CurrentContext")){ + Registry::RemoveItem("CurrentContext"); + } + + // It is needed to create a std::string explicitly copying the '"CurrentContext"+rCurrentSource' to avoid casting problems + // involing std::any_cast to a reference type which key references a string that may not be alive when invoked. + std::string context_key = std::string("CurrentContext." + rCurrentSource); + + Registry::AddItem(context_key); + } + + std::string Registry::GetCurrentSource() + { + // If context key not present, create it + if (!Registry::HasItem("CurrentContext")){ + Registry::AddItem("CurrentContext.KratosMultiphysics"); + } + + return Registry::GetItem("CurrentContext").begin()->first; + } + std::size_t Registry::size() { return mspRootRegistryItem->size(); diff --git a/kratos/sources/registry_item.cpp b/kratos/sources/registry_item.cpp index 6b312ebe7177..ad82fbc3d4e3 100644 --- a/kratos/sources/registry_item.cpp +++ b/kratos/sources/registry_item.cpp @@ -23,13 +23,21 @@ namespace Kratos RegistryItem::SubRegistryItemType& RegistryItem::GetSubRegistryItemMap() { KRATOS_ERROR_IF(HasValue()) << "Item " << Name() << " has value and cannot be iterated." << std::endl; +#if defined (__GNUC__) && __GNUC__ <= 8 && __GNUC_MINOR__ <= 3 + return *(boost::any_cast(mpValue)); +#else return *(std::any_cast(mpValue)); +#endif } RegistryItem::SubRegistryItemType& RegistryItem::GetSubRegistryItemMap() const { KRATOS_ERROR_IF(HasValue()) << "Item " << Name() << " has value and cannot be iterated." << std::endl; +#if defined (__GNUC__) && __GNUC__ <= 8 && __GNUC_MINOR__ <= 3 + return *(boost::any_cast(mpValue)); +#else return *(std::any_cast(mpValue)); +#endif } RegistryItem::SubRegistryItemType::iterator RegistryItem::begin()