Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Core][MappingApplication] Make MapperFactory use Registry #12542

Merged
merged 5 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,6 @@ namespace Kratos {
typedef typename MPIMapperDefinitions::SparseSpaceType SparseSpaceType;
typedef typename MPIMapperDefinitions::DenseSpaceType DenseSpaceType;

template<>
std::unordered_map<std::string, typename Mapper<SparseSpaceType, DenseSpaceType>::Pointer>& MapperFactory<SparseSpaceType,
DenseSpaceType>::GetRegisteredMappersList()
{
static std::unordered_map<std::string, typename Mapper<SparseSpaceType, DenseSpaceType>::Pointer> registered_mappers;

return registered_mappers;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// Class template instantiation
template class MapperFactory< SparseSpaceType, DenseSpaceType >;
Expand Down
9 changes: 0 additions & 9 deletions kratos/factories/mapper_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,6 @@ namespace Kratos {
typedef typename MapperDefinitions::SparseSpaceType SparseSpaceType;
typedef typename MapperDefinitions::DenseSpaceType DenseSpaceType;

template<>
std::unordered_map<std::string, typename Mapper<SparseSpaceType, DenseSpaceType>::Pointer>& MapperFactory<SparseSpaceType,
DenseSpaceType>::GetRegisteredMappersList()
{
static std::unordered_map<std::string, typename Mapper<SparseSpaceType, DenseSpaceType>::Pointer> registered_mappers;

return registered_mappers;
}

/* // CommRank is used as input bcs the MyPID function of the non-MPI MapperCommunicator is used
// since this function is called before the MapperMPICommunicato is initialized
void CheckInterfaceModelParts(const int CommRank)
Expand Down
63 changes: 43 additions & 20 deletions kratos/factories/mapper_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
// Project includes
#include "includes/define.h"
#include "includes/kratos_parameters.h"
#include "includes/registry.h"
#include "containers/model.h"

#include "mappers/mapper.h"
Expand Down Expand Up @@ -74,27 +75,27 @@ class KRATOS_API(KRATOS_CORE) MapperFactory
KRATOS_ERROR_IF(TSparseSpace::IsDistributed() && !r_interface_model_part_origin.IsDistributed() && !r_interface_model_part_destination.IsDistributed()) << "Trying to construct a MPI Mapper without a distributed ModelPart. Please use \"CreateMapper\" instead!" << std::endl;

const std::string mapper_name = MapperSettings["mapper_type"].GetString();
const std::string mapper_path = GetPath(mapper_name);

const auto& mapper_list = GetRegisteredMappersList();
if (Registry::HasItem(mapper_path)) {

if (mapper_list.find(mapper_name) != mapper_list.end()) {
// Removing Parameters that are not needed by the Mapper
MapperSettings.RemoveValue("mapper_type");
MapperSettings.RemoveValue("interface_submodel_part_origin");
MapperSettings.RemoveValue("interface_submodel_part_destination");

// TODO check why this works, Clone currently returns a unique ptr!!!
return mapper_list.at(mapper_name)->Clone(r_interface_model_part_origin,
r_interface_model_part_destination,
MapperSettings);
return Registry::GetValue<Mapper<TSparseSpace, TDenseSpace>>(mapper_path).Clone(
r_interface_model_part_origin, r_interface_model_part_destination, MapperSettings);
}
else {
std::stringstream err_msg;
err_msg << "The requested Mapper \"" << mapper_name <<"\" is not not available!\n"
<< "The following Mappers are available:" << std::endl;

for (auto const& registered_mapper : mapper_list)
err_msg << "\t" << registered_mapper.first << "\n";
auto& r_mappers = Registry::GetItem(GetPath());
for (auto i_key = r_mappers.KeyConstBegin(); i_key != r_mappers.KeyConstEnd(); ++i_key) {
err_msg << "\t" << *i_key << "\n";
}

KRATOS_ERROR << err_msg.str() << std::endl;
}
Expand All @@ -103,25 +104,30 @@ class KRATOS_API(KRATOS_CORE) MapperFactory
static void Register(const std::string& rMapperName,
typename Mapper<TSparseSpace, TDenseSpace>::Pointer pMapperPrototype)
{
GetRegisteredMappersList().insert(
std::make_pair(rMapperName, pMapperPrototype));
using MapperType = Mapper<TSparseSpace, TDenseSpace>;
// Register mappers.all.mapper and mappers.ApplicationName.mapper (or their mpi equivalents)
// MapperFactory always uses the mappers.all path, but the other one is used when de-registering the application
Registry::AddItem<MapperType>(GetApplicationPath(Registry::GetCurrentSource(), rMapperName), pMapperPrototype);
Registry::AddItem<MapperType>(GetPath(rMapperName), pMapperPrototype);
}

static bool HasMapper(const std::string& rMapperName)
{
const auto& mapper_list = GetRegisteredMappersList();
return mapper_list.find(rMapperName) != mapper_list.end();
return Registry::HasItem(GetPath(rMapperName));
}

static std::vector<std::string> GetRegisteredMapperNames()
{
const auto& mapper_list = GetRegisteredMappersList();

std::vector<std::string> mapper_names;

mapper_names.reserve(mapper_list.size());
for (auto const& r_registered_mapper : mapper_list) {
mapper_names.push_back(r_registered_mapper.first);
if (Registry::HasItem(GetPath())) {
auto& r_mappers = Registry::GetItem(GetPath());

mapper_names.reserve(r_mappers.size());
for (auto i_key = r_mappers.KeyConstBegin(); i_key != r_mappers.KeyConstEnd(); ++i_key) {
mapper_names.push_back(*i_key);
}

}

return mapper_names;
Expand Down Expand Up @@ -157,6 +163,26 @@ class KRATOS_API(KRATOS_CORE) MapperFactory
/// Default constructor.
MapperFactory() {}

static std::string GetPath() {
if constexpr (TSparseSpace::IsDistributed()) {
return std::string("mappers.all.mpi");
}
return std::string("mappers.all");
Comment on lines +168 to +170
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those names are only internally used in the registry right? I.e. nothing the user has to deal with?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The users of MapperFactory should be able to continue interacting with it as usual. One could get the mappers directly form the registry using those paths, but this is not used at the moment.

}

static std::string GetApplicationPath(const std::string& rApplicationName, const std::string& rName)
{
if constexpr (TSparseSpace::IsDistributed()) {
return "mappers."+rApplicationName+".mpi."+rName;
}
return "mappers."+rApplicationName+"."+rName;
}

static std::string GetPath(const std::string& rName)
{
return GetPath() + "." + rName;
}

static ModelPart& GetInterfaceModelPart(ModelPart& rModelPart,
const Parameters InterfaceParameters,
const std::string& InterfaceSide)
Expand All @@ -177,9 +203,6 @@ class KRATOS_API(KRATOS_CORE) MapperFactory
}
}

static std::unordered_map<std::string, typename Mapper<TSparseSpace,
TDenseSpace>::Pointer>& GetRegisteredMappersList();

///@}

}; // Class MapperFactory
Expand Down
10 changes: 8 additions & 2 deletions kratos/includes/kratos_application.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class KRATOS_API(KRATOS_CORE) KratosApplication {
mpModelers(rOther.mpModelers) {}

/// Destructor.
virtual ~KratosApplication()
virtual ~KratosApplication()
{
// This must be commented until tests have been fixed.
DeregisterCommonComponents();
Expand All @@ -152,7 +152,7 @@ class KRATOS_API(KRATOS_CORE) KratosApplication {

/**
* @brief This method is used to unregister common components of the application.
* @details 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
Expand All @@ -169,6 +169,12 @@ class KRATOS_API(KRATOS_CORE) KratosApplication {
*/
virtual void DeregisterApplication();

/**
* @brief This method is used to unregister mappers registered by the application..
* @details This method is used to unregister mappers registered by the application..
*/
void DeregisterMappers();

///////////////////////////////////////////////////////////////////
void RegisterVariables(); // This contains the whole list of common variables in the Kratos Core
void RegisterDeprecatedVariables(); //TODO: remove, this variables should not be there
Expand Down
32 changes: 30 additions & 2 deletions kratos/sources/kratos_application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ KratosApplication::KratosApplication(const std::string& ApplicationName)
mpModelers(KratosComponents<Modeler>::pGetComponents()),
mpRegisteredObjects(&(Serializer::GetRegisteredObjects())),
mpRegisteredObjectsName(&(Serializer::GetRegisteredObjectsName())) {

Registry::SetCurrentSource(mApplicationName);

for (auto component : {"geometries", "elements", "conditions", "constraints", "modelers", "constitutive_laws"}) {
Expand Down Expand Up @@ -355,7 +355,7 @@ void KratosApplication::DeregisterComponent(std::string const & rComponentName)
}
}

void KratosApplication::DeregisterCommonComponents()
void KratosApplication::DeregisterCommonComponents()
{
KRATOS_INFO("") << "Deregistering " << mApplicationName << std::endl;

Expand All @@ -368,8 +368,36 @@ void KratosApplication::DeregisterCommonComponents()
}

void KratosApplication::DeregisterApplication() {
DeregisterMappers();
// DeregisterLinearSolvers();
// DeregisterPreconditioners();
}

void KratosApplication::DeregisterMappers() {
// Unload the mpi branch first to avoid having a special case later
const std::string mpi_path = "mappers."+mApplicationName+".mpi";
if (Registry::HasItem(mpi_path)) {
auto& r_mappers = Registry::GetItem(mpi_path);
// Iterate over items at path. For each item, remove it from the mappers.all.mpi branch too
for (auto i_key = r_mappers.KeyConstBegin(); i_key != r_mappers.KeyConstEnd(); ++i_key) {
KRATOS_INFO("") << "Deregistering mappers.all.mpi." << *i_key << std::endl;
Registry::RemoveItem("mappers.all.mpi."+*i_key);
}
KRATOS_INFO("") << "Deregistering " << mApplicationName << " MPI mappers" << std::endl;
Registry::RemoveItem(mpi_path);
}

const std::string path = "mappers."+mApplicationName;
if (Registry::HasItem(path)) {
auto& r_mappers = Registry::GetItem(path);
// Iterate over items at path. For each item, remove it from the mappers.all branch too
for (auto i_key = r_mappers.KeyConstBegin(); i_key != r_mappers.KeyConstEnd(); ++i_key) {
KRATOS_INFO("") << "Deregistering mappers.all." << *i_key << std::endl;
Registry::RemoveItem("mappers.all."+*i_key);
}
KRATOS_INFO("") << "Deregistering " << mApplicationName << " mappers" << std::endl;
Registry::RemoveItem(path);
}
}

} // namespace Kratos.
Loading