9#include <kernel/geometry/adaptive_mesh.hpp>
10#include <kernel/geometry/adaptive_mesh_layer.hpp>
11#include <kernel/geometry/mesh_node.hpp>
12#include <kernel/geometry/mesh_permutation.hpp>
13#include <kernel/geometry/subdivision_levels.hpp>
14#include <kernel/util/dist.hpp>
16#include <kernel/geometry/boundary_factory.hpp>
17#include <kernel/geometry/common_factories.hpp>
18#include <kernel/geometry/mesh_file_reader.hpp>
20#include <control/domain/parti_domain_control.hpp>
35 template<
typename DomainLevel_,
typename TemplateSet_>
42 using typename BaseClass::MeshType;
44 using typename BaseClass::MeshNodeType;
95 template<
typename DomainLevel_,
typename TemplateSet_>
102 using typename BaseClass::LevelType;
106 using typename BaseClass::MeshType;
124 std::shared_ptr<AdaptiveMeshType> _adaptive_mesh;
138 bool support_multi_layered,
152 return *_adaptive_mesh;
166 static constexpr int dim = MeshType::ShapeType::dimension;
167 const WeightType average_elements_per_marking =
168 WeightType(TemplateSet_::template average_elements_per_marking<dim>());
170 const MeshType& mesh = *base_mesh_node.
get_mesh();
171 const auto& v_at_c = mesh.template get_index_set<dim, 0>();
174 std::vector<WeightType> weights(mesh.get_num_elements());
180 for(
Index cell(0); cell < weights.size(); cell++)
182 std::uint64_t markings(0);
183 for(
auto i = v_at_c.image_begin(cell); i != v_at_c.image_end(cell); ++i)
185 markings += sdls[*i];
215#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
249 void refine_partially()
251 const MeshNodeType& mesh_node = *this->_layer_levels.at(0).front()->get_mesh_node();
263 std::uint64_t sdl_max;
267 _adaptive_mesh = std::make_shared<AdaptiveMeshType>(*mesh_node.
get_mesh());
271 for(
Index i(1); i <= sdl_max; i++)
278 this->push_level_front(
280 std::make_shared<LevelType>(
314 auto result = std::make_unique<MeshNodeType>(std::move(cmesh));
320 const auto* mesh_part = mesh_part_node->
get_mesh();
322 std::unique_ptr<MeshPartType> new_mesh_part;
325 new_mesh_part = std::make_unique<MeshPartType>(mesh.template project_meshpart<MeshType>(l, *mesh_part));
329 new_mesh_part = std::unique_ptr<MeshPartType>(
nullptr);
331 auto new_mesh_part_node = std::make_unique<Geometry::MeshPartNode<MeshType>>(std::move(new_mesh_part));
333 result->add_mesh_part_node(
335 std::move(new_mesh_part_node),
336 mesh_part_node->find_mesh_part_chart_name(name),
337 mesh_part_node->find_mesh_part_chart(name));
341 for(
const auto& [rank, part] : root_node.
get_halo_map())
346 auto new_halo = std::make_unique<MeshPartType>(mesh.template project_meshpart<MeshType>(l, *part));
347 result->add_halo(rank, std::move(new_halo));
351 result->add_halo(rank,
nullptr);
361 auto new_patch = std::make_unique<MeshPartType>(mesh.template project_meshpart<MeshType>(l, *patch));
362 result->add_patch(rank, std::move(new_patch));
366 result->add_patch(rank,
nullptr);
371 if((adapt_mode & Geometry::AdaptMode::chart) != Geometry::AdaptMode::none)
400 std::unordered_map<int, Dist::RequestVector> sends;
401 std::unordered_map<int, Dist::RequestVector> receives;
406 for(
const auto& [rank, halo] : mesh_node.
get_halo_map())
408 const auto& vertices = halo->template get_target_set<0>();
410 for(
Index i(0); i < vertices.get_num_entities(); i++)
412 sends[rank].push_back(this->_comm.
isend(&sdls[vertices[i]], 1, rank));
413 receives[rank].push_back(this->_comm.
irecv(&received_sdls[vertices[i]], 1, rank));
418 for(
const auto& [rank, halo] : mesh_node.
get_halo_map())
420 const auto& vertices = halo->template get_target_set<0>();
421 for(
Index idx(0); receives[rank].wait_any(idx);)
423 const Index vidx = vertices[idx];
425 sdls[vidx] =
Math::max(sdls[vidx], received_sdls[vidx]);
430 for(
const auto& [rank, halo] : mesh_node.
get_halo_map())
432 sends[rank].wait_all();
#define XASSERT(expr)
Assertion macro definition.
Wrapper class for domain levels for AdaptivePartiDomainControl.
DomainLevel_ BaseClass
our base-class; the actual domain level
bool is_partial_level()
Returns true if this level belongs a potentially partial refinement.
AdaptiveLevelWrapper(int _lvl_idx, std::unique_ptr< MeshNodeType > node, AdaptiveMeshLayerType &&layer)
Constructor for partially refined levels.
AdaptiveLevelWrapper(int _lvl_idx, std::unique_ptr< MeshNodeType > node)
Contructor for fully refined levels.
std::optional< AdaptiveMeshLayerType > mesh_layer
View into adaptive mesh. If empty, this layer was created by a full refinement.
Adaptive Partitioned Domain Control.
const AdaptiveMeshType & get_adaptive_mesh() const
Accessor for underlying adaptive mesh.
void _create_single_process(std::unique_ptr< MeshNodeType > base_mesh_node) override
Creates a single-layered mesh hierarchy for a single process.
void sync_subdivision_levels(Geometry::SubdivisionLevels &sdls, const MeshNodeType &mesh_node)
Sync subdivision levels across processes by taking the maximum across processes.
void _create_multi_layered(std::unique_ptr< MeshNodeType > base_mesh_node) override
Creates a multi-layered mesh hierarchy.
AdaptivePartiDomainControl(const Dist::Comm &comm_, bool support_multi_layered, std::function< void(Geometry::SubdivisionLevels &, const MeshType &)> refinement_strategy)
Constructor.
std::function< void(Geometry::SubdivisionLevels &, const MeshType &)> _refinement_strategy
the refinement strategy for the partially refined parts of the domain
std::unique_ptr< MeshNodeType > project_mesh_node(const AdaptiveMeshType &mesh, Geometry::Layer l, const MeshNodeType &root_node, Geometry::AdaptMode adapt_mode=Geometry::AdaptMode::chart)
Project a MeshNode from a regular mesh onto a layer of an adaptive mesh.
void _create_single_layered(std::unique_ptr< MeshNodeType > base_mesh_node) override
Creates a single-layered mesh hierarchy.
void refine_partially()
Create partially refined levels on top of the current finest level.
virtual ~AdaptivePartiDomainControl()=default
virtual destructor
std::vector< WeightType > _compute_weights(Ancestor &ancestor, const MeshNodeType &base_mesh_node) override
Compute weights for a-posteriori partitioners.
std::deque< std::pair< int, int > > _chosen_levels
chosen level deque
Recursively Partitioned Domain Control.
Real WeightType
weight type for partitioner element weights; always Real
Geometry::RootMeshNode< MeshType > MeshNodeType
our root mesh node type
virtual void _create_multi_layered(std::unique_ptr< MeshNodeType > base_mesh_node)
Creates a multi-layered mesh hierarchy.
LevelType::PartType MeshPartType
our mesh-part type
bool _allow_parti_2level
allow 2-level partitioner?
virtual void _create_single_process(std::unique_ptr< MeshNodeType > base_mesh_node)
Creates a single-layered mesh hierarchy for a single process.
virtual void _create_single_layered(std::unique_ptr< MeshNodeType > base_mesh_node)
Creates a single-layered mesh hierarchy.
void allreduce(const void *sendbuf, void *recvbuf, std::size_t count, const Datatype &datatype, const Operation &op) const
Blocking All-Reduce.
int size() const
Returns the size of this communicator.
Request irecv(void *buffer, std::size_t count, const Datatype &datatype, int source, int tag=0) const
Nonblocking Receive.
Request isend(const void *buffer, std::size_t count, const Datatype &datatype, int dest, int tag=0) const
Nonblocking Send.
Dynamic mesh data structure.
FoundationMeshType to_conformal_mesh(Layer layer) const
Create a ConformalMesh from a layer.
@ All
Import all entities. Useful for exporting the complete mesh later.
ConformalMesh interface for adaptive meshes.
std::deque< String > get_mesh_part_names(bool no_internals=false) const
Returns the names of all mesh parts of this node.
MeshType * get_mesh()
Returns the mesh of this node.
MeshPartNodeType * find_mesh_part_node(const String &part_name)
Searches this container for a MeshPartNode.
const std::map< int, std::unique_ptr< MeshPartType > > & get_patch_map() const
const std::map< int, std::unique_ptr< MeshPartType > > & get_halo_map() const
Subdivision level markings for meshes.
std::uint64_t maximum_level()
Returns the maximum refinement level assigned to any vertex.
Domain control namespace.
const Operation op_max(MPI_MAX)
Operation wrapper for MPI_MAX.
AdaptMode
Adapt mode enumeration.
T_ min(T_ a, T_ b)
Returns the minimum of two values.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
std::uint64_t Index
Index data type.
Newtype wrapper for mesh layers.