diff --git a/NumLib/DOF/LocalToGlobalIndexMap.cpp b/NumLib/DOF/LocalToGlobalIndexMap.cpp index 40034c2eb29109184704af316912eb01d828b773..d1a91bacf81e8b908e388d2a40d9daf14b5185f0 100644 --- a/NumLib/DOF/LocalToGlobalIndexMap.cpp +++ b/NumLib/DOF/LocalToGlobalIndexMap.cpp @@ -191,7 +191,8 @@ LocalToGlobalIndexMap::LocalToGlobalIndexMap( std::vector<int> const& global_component_ids, std::vector<int> const& variable_component_offsets, std::vector<MeshLib::Element*> const& elements, - NumLib::MeshComponentMap&& mesh_component_map) + NumLib::MeshComponentMap&& mesh_component_map, + LocalToGlobalIndexMap::ConstructorTag) : _mesh_subsets(std::move(mesh_subsets)), _mesh_component_map(std::move(mesh_component_map)), _variable_component_offsets(variable_component_offsets) @@ -249,7 +250,42 @@ LocalToGlobalIndexMap* LocalToGlobalIndexMap::deriveBoundaryConstrainedMap( return new LocalToGlobalIndexMap( std::move(all_mesh_subsets), global_component_ids, - _variable_component_offsets, elements, std::move(mesh_component_map)); + _variable_component_offsets, elements, std::move(mesh_component_map), + ConstructorTag{}); +} + +std::unique_ptr<LocalToGlobalIndexMap> +LocalToGlobalIndexMap::deriveBoundaryConstrainedMap( + MeshLib::MeshSubset&& new_mesh_subset) const +{ + DBUG("Construct reduced local to global index map."); + + // Create a subset of the current mesh component map. + std::vector<int> global_component_ids; + + for (int i = 0; i < getNumberOfComponents(); ++i) + { + global_component_ids.push_back(i); + } + + // Elements of the new_mesh_subset's mesh. + std::vector<MeshLib::Element*> const& elements = + new_mesh_subset.getMesh().getElements(); + + auto mesh_component_map = _mesh_component_map.getSubset( + _mesh_subsets, new_mesh_subset, global_component_ids); + + // Create copies of the new_mesh_subset for each of the global components. + // The last component is moved after the for-loop. + std::vector<MeshLib::MeshSubset> all_mesh_subsets; + for (int i = 0; i < static_cast<int>(global_component_ids.size()) - 1; ++i) + all_mesh_subsets.emplace_back(new_mesh_subset); + all_mesh_subsets.emplace_back(std::move(new_mesh_subset)); + + return std::make_unique<LocalToGlobalIndexMap>( + std::move(all_mesh_subsets), global_component_ids, + _variable_component_offsets, elements, std::move(mesh_component_map), + ConstructorTag{}); } std::size_t LocalToGlobalIndexMap::dofSizeWithGhosts() const diff --git a/NumLib/DOF/LocalToGlobalIndexMap.h b/NumLib/DOF/LocalToGlobalIndexMap.h index 41c1c02456af72fb3db23199b875237a7eb01f3c..8100ac00c155e200f072c91b1115e18e3051eede 100644 --- a/NumLib/DOF/LocalToGlobalIndexMap.h +++ b/NumLib/DOF/LocalToGlobalIndexMap.h @@ -41,6 +41,14 @@ namespace NumLib /// mesh item. class LocalToGlobalIndexMap final { + // Enables using std::make_unique with private constructors from within + // member functions of LocalToGlobalIndexMap. Cf. + // http://seanmiddleditch.com/enabling-make_unique-with-private-constructors/ + struct ConstructorTag + { + explicit ConstructorTag() = default; + }; + public: using RowColumnIndices = MathLib::RowColumnIndices<GlobalIndexType>; using LineIndex = RowColumnIndices::LineIndex; @@ -90,6 +98,13 @@ public: std::vector<int> const& component_ids, MeshLib::MeshSubset&& mesh_subset) const; + /// Derive a LocalToGlobalIndexMap constrained to the mesh subset and mesh + /// subset's elements. A new mesh component map will be constructed using + /// the passed mesh_subset for all variables and components of the current + /// LocalToGlobalIndexMap. + std::unique_ptr<LocalToGlobalIndexMap> deriveBoundaryConstrainedMap( + MeshLib::MeshSubset&& new_mesh_subset) const; + /// Returns total number of degrees of freedom including those located in /// the ghost nodes. std::size_t dofSizeWithGhosts() const; @@ -144,10 +159,14 @@ public: MeshLib::MeshSubset const& getMeshSubset( int const global_component_id) const; -private: - /// Private constructor used by internally created local-to-global index - /// maps. The mesh_component_map is passed as argument instead of being - /// created by the constructor. + /// The global component id for the specific variable (like velocity) and a + /// component (like x, or y, or z). + int getGlobalComponent(int const variable_id, int const component_id) const; + + /// Private constructor (ensured by ConstructorTag) used by internally + /// created local-to-global index maps. The mesh_component_map is passed as + /// argument instead of being created by the constructor. + /// /// \attention The passed mesh_component_map is in undefined state after /// this construtor. explicit LocalToGlobalIndexMap( @@ -155,8 +174,9 @@ private: std::vector<int> const& global_component_ids, std::vector<int> const& variable_component_offsets, std::vector<MeshLib::Element*> const& elements, - NumLib::MeshComponentMap&& mesh_component_map); + NumLib::MeshComponentMap&& mesh_component_map, ConstructorTag); +private: template <typename ElementIterator> void findGlobalIndices(ElementIterator first, ElementIterator last, std::vector<MeshLib::Node*> const& nodes, @@ -169,11 +189,6 @@ private: std::vector<MeshLib::Node*> const& nodes, std::size_t const mesh_id, const int component_id, const int comp_id_write); - /// The global component id for the specific variable (like velocity) and a - /// component (like x, or y, or z). - int getGlobalComponent(int const variable_id, int const component_id) const; - -private: /// A vector of mesh subsets for each process variables' components. std::vector<MeshLib::MeshSubset> _mesh_subsets; NumLib::MeshComponentMap _mesh_component_map;