diff --git a/kratos/containers/variable.h b/kratos/containers/variable.h index 1b42e09b0bbe..98321013917b 100644 --- a/kratos/containers/variable.h +++ b/kratos/containers/variable.h @@ -95,9 +95,7 @@ class Variable : public VariableData : VariableData(NewName, sizeof(TDataType)), mZero(Zero), mpTimeDerivativeVariable(pTimeDerivativeVariable) - { - RegisterThisVariable(); - } + {} /** * @brief Constructor with specific name and zero value * @param NewName The name to be assigned to the new variable @@ -110,9 +108,7 @@ class Variable : public VariableData : VariableData(NewName, sizeof(TDataType)), mZero(TDataType()), mpTimeDerivativeVariable(pTimeDerivativeVariable) - { - RegisterThisVariable(); - } + {} /** * @brief Constructor for creating a component of other variable @@ -128,9 +124,7 @@ class Variable : public VariableData ) : VariableData(rNewName, sizeof(TDataType), pSourceVariable, ComponentIndex), mZero(Zero) - { - RegisterThisVariable(); - } + {} /** * @brief Constructor for creating a component of other variable @@ -149,9 +143,7 @@ class Variable : public VariableData : VariableData(rNewName, sizeof(TDataType), pSourceVariable, ComponentIndex), mZero(Zero), mpTimeDerivativeVariable(pTimeDerivativeVariable) - { - RegisterThisVariable(); - } + {} /** * Copy constructor. @@ -325,6 +317,19 @@ class Variable : public VariableData return GetValueByIndex(static_cast(pSource),GetComponentIndex()); } + /// Add the variable to the Kratos Registry + void Register() const { + const std::string variable_path("variables.all."+Name()); + if (!Registry::HasItem(variable_path)) { + Registry::AddItem(variable_path, *this); + Registry::AddItem("variables."+Registry::GetCurrentSource()+"."+Name(), *this); + } else if(!Registry::GetItem(variable_path).IsSameType(*this)) { + KRATOS_ERROR << "Attempting to register " << Name() + << " but a variable with the same name and different type already exists" + << std::endl; + } + } + ///@} ///@name Access ///@{ @@ -471,13 +476,6 @@ class Variable : public VariableData return *static_cast(pValue + index); } - void RegisterThisVariable(){ - std::string variable_path = "variables.all." + Name(); - if(!Registry::HasItem(variable_path)){ - Registry::AddItem(variable_path, *this); - } - } - ///@} ///@name Serialization ///@{ diff --git a/kratos/includes/define.h b/kratos/includes/define.h index abf561b6f04d..6ebd1362faa4 100644 --- a/kratos/includes/define.h +++ b/kratos/includes/define.h @@ -431,7 +431,8 @@ catch(...) { Block KRATOS_THROW_ERROR(std::runtime_error, "Unknown error", MoreI #endif #define KRATOS_REGISTER_VARIABLE(name) \ AddKratosComponent(name.Name(), name); \ - KratosComponents::Add(name.Name(), name); + KratosComponents::Add(name.Name(), name); \ + name.Register(); #ifdef KRATOS_REGISTER_3D_VARIABLE_WITH_COMPONENTS #undef KRATOS_REGISTER_3D_VARIABLE_WITH_COMPONENTS diff --git a/kratos/includes/kratos_application.h b/kratos/includes/kratos_application.h index 1982ee2a3721..aa9b30c7a7d4 100644 --- a/kratos/includes/kratos_application.h +++ b/kratos/includes/kratos_application.h @@ -133,7 +133,7 @@ class KRATOS_API(KRATOS_CORE) KratosApplication { /// Destructor. virtual ~KratosApplication() { - // This must be commented until tests have been fixed. + DeregisterVariables(); DeregisterCommonComponents(); DeregisterApplication(); } @@ -149,6 +149,8 @@ class KRATOS_API(KRATOS_CORE) KratosApplication { void RegisterKratosCore(); + void DeregisterVariables(); + template void DeregisterComponent(std::string const & rComponentName); diff --git a/kratos/includes/registry_item.h b/kratos/includes/registry_item.h index ad1eab81bdd3..44907605ce12 100644 --- a/kratos/includes/registry_item.h +++ b/kratos/includes/registry_item.h @@ -23,7 +23,7 @@ #include #else #include -#endif +#endif // External includes @@ -257,7 +257,7 @@ class KRATOS_API(KRATOS_CORE) RegistryItem KRATOS_CATCH(""); } - template + template TCastType const& GetValueAs() const { KRATOS_TRY @@ -285,6 +285,16 @@ class KRATOS_API(KRATOS_CORE) RegistryItem bool HasItem(std::string const& rItemName) const; + template + bool IsSameType(const OtherType& rOther) const { + try { + GetValue(); + } catch (...) { + return false; + } + return true; + } + ///@} ///@name Input and output ///@{ diff --git a/kratos/sources/kratos_application.cpp b/kratos/sources/kratos_application.cpp index 7807b58e5942..033400022995 100644 --- a/kratos/sources/kratos_application.cpp +++ b/kratos/sources/kratos_application.cpp @@ -350,6 +350,20 @@ void KratosApplication::RegisterKratosCore() { RegisterVoxelMesherOperation(); } + +void KratosApplication::DeregisterVariables() { + const std::string path = "variables."+mApplicationName; + if (Registry::HasItem(path)) { + auto& r_variables = Registry::GetItem(path); + // Iterate over items at path. For each item, remove it from the mappers.all branch too + for (auto i_key = r_variables.KeyConstBegin(); i_key != r_variables.KeyConstEnd(); ++i_key) { + Registry::RemoveItem("variables.all."+*i_key); + } + Registry::RemoveItem(path); + } +} + + template void KratosApplication::DeregisterComponent(std::string const & rComponentName) { auto path = std::string(rComponentName)+"."+mApplicationName; diff --git a/kratos/tests/cpp_tests/containers/test_variables.cpp b/kratos/tests/cpp_tests/containers/test_variables.cpp index fb6934eb03ea..91d41e70b2c7 100644 --- a/kratos/tests/cpp_tests/containers/test_variables.cpp +++ b/kratos/tests/cpp_tests/containers/test_variables.cpp @@ -71,7 +71,25 @@ KRATOS_TEST_CASE_IN_SUITE(VariablesKeyOrder, KratosCoreFastSuite) { } } +KRATOS_TEST_CASE_IN_SUITE(VariablesRegister, KratosCoreFastSuite) { + Variable new_var("NEW_DUMMY_VARIABLE"); + new_var.Register(); + KRATOS_EXPECT_TRUE(Registry::HasItem("variables.all.NEW_DUMMY_VARIABLE")); + KRATOS_EXPECT_TRUE(Registry::HasItem("variables.KratosMultiphysics.NEW_DUMMY_VARIABLE")); + // Attempting to register a variable with the same name and type does nothing + Variable duplicate_variable("NEW_DUMMY_VARIABLE"); + duplicate_variable.Register(); + KRATOS_EXPECT_TRUE(Registry::HasItem("variables.all.NEW_DUMMY_VARIABLE")); + KRATOS_EXPECT_TRUE(Registry::HasItem("variables.KratosMultiphysics.NEW_DUMMY_VARIABLE")); + + // Attempting to register a variable with the same name and different type is an error + Variable wrong_type_variable("NEW_DUMMY_VARIABLE"); + KRATOS_EXPECT_EXCEPTION_IS_THROWN( + wrong_type_variable.Register(), + "Attempting to register NEW_DUMMY_VARIABLE but a variable with the same name and different type already exists" + ) +} } diff --git a/kratos/tests/cpp_tests/sources/test_registry.cpp b/kratos/tests/cpp_tests/sources/test_registry.cpp index afdfc96a8ffa..06f046345a28 100644 --- a/kratos/tests/cpp_tests/sources/test_registry.cpp +++ b/kratos/tests/cpp_tests/sources/test_registry.cpp @@ -99,7 +99,7 @@ KRATOS_TEST_CASE_IN_SUITE(RegistryDataValue, KratosCoreFastSuite) { double value = 3.14; RegistryItem value_registry_item("value_item", value); - + KRATOS_EXPECT_EQ(value_registry_item.Name(),"value_item"); KRATOS_EXPECT_TRUE(value_registry_item.HasValue()); KRATOS_EXPECT_FALSE(value_registry_item.HasItems()); @@ -115,7 +115,7 @@ KRATOS_TEST_CASE_IN_SUITE(RegistryJsonValue, KratosCoreFastSuite) std::string value_item_json = R"({ "value_item": "3.14" })"; - + KRATOS_EXPECT_EQ(value_registry_item.ToJson(), value_item_json); } @@ -125,7 +125,7 @@ KRATOS_TEST_CASE_IN_SUITE(RegistryJsonSubValue, KratosCoreFastSuite) RegistryItem registry_item("items"); registry_item.AddItem("sub_value_item", value); - + KRATOS_EXPECT_FALSE(registry_item.HasValue()); KRATOS_EXPECT_TRUE(registry_item.HasItems()); KRATOS_EXPECT_FALSE(registry_item.HasItem("test")); @@ -138,15 +138,15 @@ KRATOS_TEST_CASE_IN_SUITE(RegistrySubValue, KratosCoreFastSuite) { double value = 3.14; RegistryItem registry_item("items"); - + registry_item.AddItem("sub_value_item", value); auto& sub_item = registry_item.GetItem("sub_value_item"); - + KRATOS_EXPECT_EQ(sub_item.Name(),"sub_value_item"); KRATOS_EXPECT_TRUE(sub_item.HasValue()); - + registry_item.RemoveItem("sub_value_item"); - + KRATOS_EXPECT_FALSE(registry_item.HasItems()); KRATOS_EXPECT_FALSE(registry_item.HasItem("sub_value_item")); } @@ -309,6 +309,11 @@ KRATOS_TEST_CASE_IN_SUITE(RegistrySomeRegisteredVariables, KratosCoreFastSuite){ KRATOS_EXPECT_TRUE(Registry::HasItem("variables.all.DISPLACEMENT_Z")); } +KRATOS_TEST_CASE_IN_SUITE(RegistryIsSameType, KratosCoreFastSuite) { + Variable test_double("TEST_DOUBLE"); + KRATOS_EXPECT_TRUE(Registry::GetItem("variables.all.TEMPERATURE").IsSameType(test_double)); + KRATOS_EXPECT_FALSE(Registry::GetItem("variables.all.VELOCITY").IsSameType(test_double)); +} } } // namespace Kratos.