9#include <kernel/util/dist.hpp>
10#include <kernel/util/dist_file_io.hpp>
11#include <kernel/util/stop_watch.hpp>
12#include <kernel/runtime.hpp>
13#include <kernel/util/simple_arg_parser.hpp>
14#include <kernel/util/property_map.hpp>
15#include <kernel/util/statistics.hpp>
16#include <kernel/geometry/mesh_node.hpp>
17#include <kernel/geometry/mesh_file_reader.hpp>
18#include <kernel/geometry/partition_set.hpp>
19#include <kernel/geometry/parti_2lvl.hpp>
20#include <kernel/geometry/parti_iterative.hpp>
21#include <kernel/geometry/parti_parmetis.hpp>
22#include <kernel/geometry/parti_zoltan.hpp>
23#include <kernel/geometry/common_factories.hpp>
24#include <kernel/geometry/patch_mesh_factory.hpp>
25#include <kernel/geometry/patch_meshpart_factory.hpp>
26#include <kernel/geometry/patch_meshpart_splitter.hpp>
27#include <kernel/geometry/cgal.hpp>
28#include <kernel/trafo/standard/mapping.hpp>
30#include <control/domain/parti_domain_control_base.hpp>
32#if defined(FEAT_HAVE_CGAL) || defined(DOXYGEN)
49 template<
typename DomainLevel_>
57 using typename BaseClass::MeshType;
59 using typename BaseClass::MeshNodeType;
82 slag_level = std::make_shared<DomainLevel_>(_lvl_idx, std::move(slag_node));
91 template<
typename DomainLevel_>
99 using typename BaseClass::LevelType;
103 using typename BaseClass::MeshType;
146 bool _cheap_weights =
true;
186 this->_keep_cgal_wrapper =
true;
192 this->_cheap_weights = option;
248 _bbox_max[0] = x_max;
250 _bbox_max[1] = y_max;
252 _bbox_max[2] = z_max;
260 Index n = vtx.get_num_vertices();
261 for(
Index i(0); i < n; ++i)
263 vtx[i][0] = x_min + (x_max - x_min) * vtx[i][0];
264 vtx[i][1] = y_min + (y_max - y_min) * vtx[i][1];
265 vtx[i][2] = z_min + (z_max - z_min) * vtx[i][2];
271 this->_create_stage = 1;
289 for(std::size_t k = 0; k < std::size_t(
shape_dim); ++k)
301 Index n = vtx.get_num_vertices();
302 for(
Index i(0); i < n; ++i)
307 _bbox_max[k] =
Math::max(_bbox_max[k], vtx[i][k]);
314 this->_create_stage = 1;
317 this->_unstructered_mesh =
true;
343 XASSERTM(this->_create_stage <= 1,
"invalid creation stage: hirarchy already created");
345 this->_watch_create_cgal_wrapper.
start();
346#ifdef FEAT_COMPILER_CLANG
349 this->_cgal_wrapper = std::make_unique<Geometry::CGALWrapper<CoordType>>(file, file_mode);
351 this->_watch_create_cgal_wrapper.
stop();
358 this->_watch_create_cgal_wrapper.
start();
359 std::stringstream cgal_input;
361 this->_watch_create_cgal_wrapper.
stop();
373 XASSERTM(this->_create_stage >= 1,
"invalid creation stage; create the base-mesh and set the cgal wrapper first");
374 XASSERTM(this->_create_stage <= 1,
"invalid creation stage: domain hierarchy already created");
376 this->_watch_create_hierarchy.
start();
380 if(this->_comm.
size() == 1)
404 this->compile_virtual_levels();
406 this->_watch_create_hierarchy.
stop();
410 this->_watch_create_cgal_wrapper.
elapsed() + this->_watch_create_hierarchy.
elapsed();
413 this->_create_stage = 2;
417 if(!this->_keep_cgal_wrapper)
418 this->_cgal_wrapper.reset();
431 return this->_cgal_wrapper.release();
437 return this->_cgal_wrapper.get();
443 return this->_cgal_wrapper.get();
448 this->_cgal_wrapper = std::move(cgal_wrapper);
451 bool cgal_wrapper_empty()
const
465 return this->_watch_create_cgal_wrapper;
471 return this->_watch_create_hierarchy;
474 const StopWatch& get_watch_weights()
const
476 return this->_watch_calc_weights;
493 XASSERT(level < this->size_physical());
503 for(
auto it = this->_layer_levels.begin(); it != this->_layer_levels.end(); ++it)
505 if(it != this->_layer_levels.begin())
507 for(
auto jt = it->begin(); jt != it->end(); ++jt)
509 msg +=
" " +
stringify((*jt)->get_level_index());
513 if((*jt)->slag_level)
514 ((msg +=
"<[") +=
stringify((*jt)->slag_level->get_mesh().get_num_elements()).pad_front(4)) +=
"]";
529 virtual void create(
const std::deque<String>& filenames,
String dirpath =
"")
532 ASSERTM(
false,
"Thou shall not arrive here!");
546 ASSERTM(
false,
"Thou shall not arrive here!");
555 virtual void create(std::unique_ptr<MeshNodeType>&)
558 ASSERTM(
false,
"Thou shall not arrive here!");
578 const Index num_elems = mesh.get_num_elements();
581 std::vector<Index> masked_elems;
582 masked_elems.reserve(num_elems);
585 const auto& vtx = mesh.get_vertex_set();
586 const auto& verts_at_elem = mesh.template get_index_set<shape_dim, 0>();
589 FEAT_PRAGMA_OMP(parallel
for)
590 for(
Index ielem = 0; ielem < num_elems; ++ielem)
592 std::array<Tiny::Vector<CoordType, shape_dim>, std::decay_t<
decltype(verts_at_elem)>::num_indices> verts;
593 for(std::size_t k = 0; k < verts.size(); ++k)
595 verts[k] = vtx[verts_at_elem(ielem,
int(k))];
598 if(this->_cgal_wrapper->intersects_polygon(verts))
599 masked_elems.push_back(ielem);
624 const Index num_elems = mesh.get_num_elements();
627 const Index elems_per_rank = num_elems/num_procs +
Index((num_elems%num_procs)>0u);
630 std::vector<Index> masked_elems;
631 masked_elems.reserve(elems_per_rank);
634 const auto& vtx = mesh.get_vertex_set();
635 const auto& verts_at_elem = mesh.template get_index_set<shape_dim, 0>();
638 for(
Index ielem = cur_rank*elems_per_rank; ielem <
Math::min((cur_rank+1u)*elems_per_rank, num_elems); ++ielem)
640 std::array<Tiny::Vector<CoordType, shape_dim>, std::decay_t<
decltype(verts_at_elem)>::num_indices> verts;
641 for(std::size_t k = 0; k < verts.size(); ++k)
643 verts[k] = vtx[verts_at_elem(ielem,
int(k))];
646 if(this->_cgal_wrapper->intersects_polygon(verts))
647 masked_elems.push_back(ielem);
651 std::vector<int> recv_sizes(num_procs);
652 recv_sizes.at(cur_rank) = int(masked_elems.size());
654 sibling_comm.
allgather(recv_sizes.data(), 1, recv_sizes.data(), 1);
657 std::vector<Index> gathered_mask(std::size_t(std::accumulate(recv_sizes.begin(), recv_sizes.end(), 0)), 0u);
660 std::vector<int> displacements;
661 displacements.reserve(recv_sizes.size());
662 std::exclusive_scan(recv_sizes.begin(), recv_sizes.end(), std::back_inserter(displacements), 0);
665 sibling_comm.
allgatherv(masked_elems.data(), masked_elems.size(), gathered_mask.data(), recv_sizes.data(), displacements.data());
668 return gathered_mask;
685 this->_watch_calc_weights.
start();
686 const Index num_elems = mesh.get_num_elements();
689 std::vector<WeightType> weights(num_elems, 0.0);
696 cub_fac.create(rule);
703 typedef typename TrafoType::template Evaluator<typename MeshType::ShapeType, CoordType>::Type TrafoEvaluator;
707 typedef typename TrafoEvaluator::template ConfigTraits<trafo_config>::EvalDataType TrafoEvalData;
709 const TrafoType trafo(
const_cast<MeshType&
>(mesh));
711 FEAT_PRAGMA_OMP(parallel)
713 TrafoEvaluator trafo_eval(trafo);
714 TrafoEvalData trafo_data;
718 for(
Index ielem = 0; ielem < num_elems; ++ielem)
720 trafo_eval.prepare(ielem);
722 for(
int k = 0; k < rule.get_num_points(); ++k)
724 const auto ref_point = rule.get_point(k);
725 trafo_eval(trafo_data, ref_point);
726 const auto&
img_point = trafo_data.img_point;
727 const CoordType weight = trafo_data.jac_det * rule.get_weight(k);
730 loc_sum /= trafo_eval.volume();
734 weights[ielem] = loc_sum;
737 this->_watch_calc_weights.
stop();
745 std::vector<WeightType> weights;
746 if(!this->_cheap_weights)
769 XASSERTM(mesh_node.
get_halo_map().empty(),
"This function must not be used for partitioned mesh nodes!");
794 const auto* prod_comm = is_child ? &ancestor.
progeny_comm :
nullptr;
825 const std::map<int, std::unique_ptr<MeshPartType>>& base_halo_map = base_mesh_node.
get_halo_map();
828 if(base_halo_map.empty())
832 const std::size_t num_halos = base_halo_map.size();
838 std::vector<int> halo_ranks;
839 std::vector<std::size_t> halo_send_sizes;
840 for(
auto it = base_halo_map.begin(); it != base_halo_map.end(); ++it)
843 halo_ranks.push_back(it->first);
846 halo_send_sizes.push_back(halo_splitter.add_halo(it->first, *it->second));
850 std::vector<std::size_t> halo_recv_sizes(num_halos);
851 std::vector<std::vector<Index>> halo_send_data(num_halos), halo_recv_data(num_halos);
857 const int layer_idx = is_child ? ancestor.
layer_p : ancestor.
layer;
860 for(std::size_t i(0); i < num_halos; ++i)
863 if(halo_send_sizes.at(i) > std::size_t(0))
864 halo_send_data.at(i) = halo_splitter.serialize_split_halo(halo_ranks[i], -1);
871 const Dist::Comm& layer_comm = this->_layers.at(std::size_t(layer_idx))->comm();
874 for(std::size_t i(0); i < num_halos; ++i)
877 halo_recv_reqs[i] = layer_comm.
irecv(&halo_recv_sizes[i], std::size_t(1), halo_ranks[i]);
880 halo_send_reqs[i] = layer_comm.
isend(&halo_send_sizes[i], std::size_t(1), halo_ranks[i]);
884 halo_recv_reqs.wait_all();
888 for(std::size_t i(0); i < num_halos; ++i)
891 if(halo_recv_sizes[i] >
Index(0))
894 halo_recv_data.at(i).resize(halo_recv_sizes[i]);
895 halo_recv_reqs[i] = layer_comm.
irecv(halo_recv_data.at(i).data(), halo_recv_sizes.at(i), halo_ranks[i]);
899 if(halo_send_sizes.at(i) >
Index(0))
902 halo_send_reqs[i] = layer_comm.
isend(halo_send_data.at(i).data(), halo_send_sizes.at(i), halo_ranks[i]);
907 halo_recv_reqs.wait_all();
920 for(std::size_t i(0); i < num_halos; ++i)
921 halo_recv_data.at(i).resize(halo_recv_sizes[i]);
925 for(std::size_t i(0); i < num_halos; ++i)
927 if(halo_recv_sizes[i] > std::size_t(0))
933 std::vector<std::array<Index, shape_dim+1>> halo_send_intsec_sizes(num_halos), halo_recv_intsec_sizes(num_halos);
936 for(std::size_t i(0); i < num_halos; ++i)
939 if(halo_recv_sizes.at(i) ==
Index(0))
943 if(!halo_splitter.intersect_split_halo(halo_ranks[i], halo_recv_data.at(i), 0u))
947 std::unique_ptr<MeshPartType> split_halo = halo_splitter.make_unique();
951 halo_send_intsec_sizes[i][
Index(j)] = split_halo->get_num_entities(j);
954 patch_mesh_node.
add_halo(halo_ranks[i], std::move(split_halo));
958 if((ancestor.
layer_p >= 0) || (!is_child && (ancestor.
layer >= 0)))
961 const LayerType& layer = *this->_layers.at(std::size_t(is_child ? ancestor.
layer_p : ancestor.
layer));
964 for(std::size_t i(0); i < num_halos; ++i)
966 halo_recv_reqs[i] = layer.comm().
irecv(halo_recv_intsec_sizes.at(i).data(), std::size_t(
shape_dim+1), halo_ranks[i]);
967 halo_send_reqs[i] = layer.comm().
isend(halo_send_intsec_sizes.at(i).data(), std::size_t(
shape_dim+1), halo_ranks[i]);
971 halo_recv_reqs.wait_all();
975 for(std::size_t i(0); i < num_halos; ++i)
979 if(halo_recv_intsec_sizes[i][
Index(j)] != halo_send_intsec_sizes[i][
Index(j)])
981 String msg =
"Inconsistent deslagged halo size between process ";
983 msg +=
" and neighbor with layer rank ";
1006 const auto& verts_at_elem = base_node.get_mesh()->template get_index_set<MeshType::shape_dim, 0>();
1025 XASSERT(slag_part !=
nullptr);
1026 const Geometry::TargetSet& slag_target = slag_part->template get_target_set<MeshType::shape_dim>();
1029 const Index num_colors =
Index(1) << MeshType::shape_dim;
1037 if constexpr(MeshType::shape_dim == 1)
1039 for(
Index i(0); i < num_elems; ++i)
1040 colors[i] = slag_target[i] & 1;
1042 else if constexpr(MeshType::shape_dim == 2)
1044 for(
Index i(0); i < num_elems; ++i)
1046 Index iel = slag_target[i];
1047 Index ix = iel % this->_base_slices[0];
1048 Index iy = iel / this->_base_slices[0];
1049 colors[i] = (ix & 1) | ((iy & 1) << 1);
1052 else if constexpr(MeshType::shape_dim == 3)
1054 for(
Index i(0); i < num_elems; ++i)
1056 Index iel = slag_target[i];
1057 Index ix = iel % this->_base_slices[0];
1058 Index iy = (iel / this->_base_slices[0]) % this->_base_slices[1];
1059 Index iz = iel / (this->_base_slices[0] * this->_base_slices[1]);
1060 colors[i] = (ix & 1) | ((iy & 1) << 1) | ((iz & 1) << (1 << 1));
1080 XASSERT(slag_part !=
nullptr);
1081 const Geometry::TargetSet& slag_target = slag_part->template get_target_set<MeshType::shape_dim>();
1084 const Index num_colors =
Index(1) << MeshType::shape_dim;
1092 for(
Index i(0); i < num_elems; ++i)
1093 colors[i] = slag_target[i] % num_colors;
1117 XASSERT(patch_part !=
nullptr);
1118 const Geometry::TargetSet& patch_target = patch_part->template get_target_set<MeshType::shape_dim>();
1129 for(
Index i(0); i < num_elems; ++i)
1130 colors[i] = parent_coloring[patch_target[i]];
1148 XASSERT(slag_part !=
nullptr);
1149 const Geometry::TargetSet& slag_target = slag_part->template get_target_set<MeshType::shape_dim>();
1159 denom *= this->_base_slices[
Index(j)];
1162 std::vector<Index> aux(max_layers, 0u);
1163 for(
Index i(0); i < num_elems; ++i)
1164 ++aux[slag_target[i] / denom];
1167 Index num_layers = 0u;
1168 for(
Index i(0); i < max_layers; ++i)
1170 Index k = num_layers;
1179 for(
Index i(0); i < num_elems; ++i)
1180 layers[i] = aux[slag_target[i] / denom];
1202 XASSERT(slag_part !=
nullptr);
1203 const Geometry::TargetSet& slag_target = slag_part->template get_target_set<MeshType::shape_dim>();
1211 std::vector<Index> aux(max_layers, 0u);
1212 for(
Index i(0); i < num_elems; ++i)
1215 ++aux[(coarse_layering[qux >> 1] << 1) | (qux & 1)];
1219 Index num_layers = 0u;
1220 for(
Index i(0); i < max_layers; ++i)
1222 Index k = num_layers;
1231 for(
Index i(0); i < num_elems; ++i)
1234 layers[i] = aux[(coarse_layering[qux >> 1] << 1) | (qux & 1)];
1261 XASSERT(patch_part !=
nullptr);
1262 const Geometry::TargetSet& patch_target = patch_part->template get_target_set<MeshType::shape_dim>();
1270 std::vector<Index> aux(max_layers, 0u);
1271 for(
Index i(0); i < num_elems; ++i)
1272 ++aux[parent_layering[patch_target[i]]];
1275 Index num_layers = 0u;
1276 for(
Index i(0); i < max_layers; ++i)
1278 Index k = num_layers;
1287 for(
Index i(0); i < num_elems; ++i)
1288 layers[i] = aux[parent_layering[patch_target[i]]];
1307 this->push_layer(std::make_shared<LayerType>(this->_comm.
comm_dup(), 0));
1317 std::unique_ptr<MeshNodeType> base_slag_node = std::move(base_mesh_node);
1323 for(; lvl < ancestor.desired_level_min; ++lvl)
1325 base_slag_node = base_mesh_node->refine_unique(this->
_adapt_mode);
1333 base_coloring = this->_compute_unstructered_coloring(*base_mesh_node);
1351 auto refined_node = base_mesh_node->refine_unique(this->
_adapt_mode);
1354 std::shared_ptr<LevelType> level_ptr = std::make_shared<LevelType>(lvl, std::move(base_mesh_node),
1355 std::move(base_slag_node), std::move(base_coloring));
1356 this->push_level_front(0, level_ptr);
1359 base_slag_node = std::move(refined_node);
1368 this->push_level_front(0, std::make_shared<LevelType>(lvl, std::move(base_mesh_node),
1369 std::move(base_slag_node), std::move(base_coloring)));
1375#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
1386 std::shared_ptr<LayerType> layer = std::make_shared<LayerType>(this->_comm.
comm_dup(), 0);
1387 this->push_layer(layer);
1396 std::unique_ptr<MeshNodeType> base_slag_node = std::move(base_mesh_node);
1407 if((lvl >= ancestor.
parti_level) && this->_apply_parti(ancestor, *base_mesh_node))
1415 base_slag_node = base_mesh_node->refine_unique(this->
_adapt_mode);
1433 std::vector<int> neighbor_ranks;
1434 std::unique_ptr<MeshNodeType> patch_mesh_node(
1435 base_mesh_node->extract_patch(neighbor_ranks, ancestor.
parti_graph, this->_comm.rank()));
1439 if(lvl == ancestor.desired_level_min)
1443 layer->set_neighbor_ranks(neighbor_ranks);
1446 std::unique_ptr<MeshNodeType> patch_slag_node;
1449 for(; lvl < ancestor.desired_level_min; ++lvl)
1452 patch_slag_node = patch_mesh_node->refine_unique(this->
_adapt_mode);
1457 if(patch_coloring.
empty())
1468 auto refined_node = patch_mesh_node->refine_unique(this->
_adapt_mode);
1471 std::shared_ptr<LevelType> level_ptr = std::make_shared<LevelType>(lvl, std::move(patch_mesh_node),
1472 std::move(patch_slag_node), std::move(patch_coloring));
1475 this->push_level_front(0, level_ptr);
1478 patch_slag_node = std::move(refined_node);
1487 this->push_level_front(0, std::make_shared<LevelType>(lvl, std::move(patch_mesh_node),
1488 std::move(patch_slag_node), std::move(patch_coloring)));
1512 std::unique_ptr<MeshNodeType> parent_slag_node;
1513 std::unique_ptr<MeshNodeType> parent_mesh_node = this->
_deslag_mesh_node(*base_mesh_node);
1518 base_mesh_node.reset();
1521 for(std::size_t slayer = this->
_ancestry.size(); slayer > std::size_t(0); )
1524 const bool is_base_layer = (slayer == this->
_ancestry.size());
1532 int parent_min_lvl = -1;
1539 this->
_check_parti(ancestor, *parent_mesh_node, is_base_layer);
1581 auto refined_node = parent_mesh_node->refine_unique(this->
_adapt_mode);
1584 std::shared_ptr<LevelType> level_ptr;
1587 if((ancestor.
layer_p >= 0) && (parent_min_lvl >= 0) && (lvl >= parent_min_lvl))
1589 level_ptr = std::make_shared<LevelType>(lvl, std::move(parent_mesh_node),
1590 std::move(parent_slag_node), std::move(parent_coloring));
1591 this->push_level_front(ancestor.
layer_p, level_ptr);
1595 parent_slag_node = std::move(refined_node);
1596 parent_mesh_node = this->
_deslag_mesh_node(*parent_slag_node, ancestor, !is_base_layer);
1607 std::vector<int> neighbor_ranks;
1608 std::unique_ptr<MeshNodeType> patch_mesh_node(
1612 std::unique_ptr<MeshNodeType> patch_slag_node;
1617 std::map<int,int> halo_map;
1618 for(
auto& i : neighbor_ranks)
1623 patch_mesh_node->rename_halos(halo_map);
1630 for(
int i(1); i < ancestor.
num_parts; ++i)
1632 parent_mesh_node->create_patch_meshpart(ancestor.
parti_graph, i);
1647 XASSERTM(lvl == global_level_min,
"INTERNAL ERROR");
1680 if(ancestor.
layer >= 0)
1683 this->_layers.at(std::size_t(ancestor.
layer))->set_neighbor_ranks(neighbor_ranks);
1689 else if(parent_min_lvl < 0)
1693 this->
_chosen_levels.push_front(std::make_pair(parent_min_lvl, 0));
1698 std::shared_ptr<LevelType> level_ptr;
1703 this->push_level_front(ancestor.
layer_p, std::make_shared<LevelType>(lvl, std::move(parent_mesh_node),
1704 std::move(parent_slag_node), std::move(parent_coloring)));
1708 parent_slag_node = std::move(patch_slag_node);
1709 parent_mesh_node = std::move(patch_mesh_node);
1710 parent_coloring = std::move(patch_coloring);
1715 int desired_level_max = this->
_ancestry.front().desired_level_max;
1716 XASSERTM(desired_level_max > lvl,
"Trying to refine larger than provided level hirarchy");
1718 for(; lvl < desired_level_max; ++lvl)
1721 auto refined_node = parent_mesh_node->refine_unique(this->
_adapt_mode);
1724 std::shared_ptr<LevelType> level_ptr = std::make_shared<LevelType>(lvl, std::move(parent_mesh_node),
1725 std::move(parent_slag_node), std::move(parent_coloring));
1729 this->push_level_front(0, level_ptr);
1732 parent_slag_node = std::move(refined_node);
1741 this->push_level_front(0, std::make_shared<LevelType>(lvl, std::move(parent_mesh_node),
1742 std::move(parent_slag_node), std::move(parent_coloring)));
#define XABORTM(msg)
Abortion macro definition with custom message.
#define ASSERTM(expr, msg)
Debug-Assertion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Coloring object implementation.
bool empty() const
Checks whether the coloring is empty.
Index * get_coloring()
Returns the coloring array.
Index get_num_colors() const
Returns the number of colors.
Adjacency Graph implementation.
Hierarchical partitioned Voxel Domain Control.
std::vector< Index > _gather_masked_elements(const MeshType &mesh) const
Gather a vector of element indices that intersect the masked domain.
virtual std::unique_ptr< MeshNodeType > _deslag_mesh_node(MeshNodeType &mesh_node)
Deslags an unpartitioned mesh node including its mesh-parts.
Adjacency::Coloring _extract_patch_coloring(const MeshNodeType &slag_node, const Adjacency::Coloring &parent_coloring, int child_rank) const
Extracts a patch coloring from the parent mesh coloring.
virtual void _create_single_process(std::unique_ptr< MeshNodeType > base_mesh_node)
Creates a single-layered mesh hierarchy for a single process.
int _create_stage
creation stage to keep track what has already been initialized
virtual void _create_single_layered(std::unique_ptr< MeshNodeType > base_mesh_node)
Creates a single-layered mesh hierarchy.
void keep_cgal_wrapper()
Instructs the domain controller to keep the voxel map after hierarchy creation.
void create_cgal_wrapper(std::istream &file, Geometry::CGALFileMode file_mode)
Creates a voxel map based on a VoxelMasker object.
StopWatch _watch_create_base_mesh
a bunch of stop-watches
Tiny::Vector< CoordType, shape_dim > _bbox_min
the bounding box of the structured domain
virtual void create(std::unique_ptr< MeshNodeType > &)
Creates a domain control from a base-mesh node.
Adjacency::Coloring _compute_refined_mesh_layering(const MeshNodeType &slag_node, const Adjacency::Coloring &coarse_layering) const
Computes the layering for a refined mesh.
bool _keep_cgal_wrapper
specifies whether to keep the voxel map after hierarchy creation
Geometry::RootMeshNode< MeshType > MeshNodeType
our root mesh node type
bool _unstructered_mesh
specifies whether we use a non voxel base mesh
void create_cgal_wrapper(const FEAT::String &file, Geometry::CGALFileMode file_mode)
has to be called from each process part of the domain hirarchy
MeshType::CoordType CoordType
coordinate type
virtual void _deslag_patch_halos(MeshNodeType &patch_mesh_node, const MeshNodeType &base_mesh_node, const Ancestor &ancestor, bool is_child)
Deslags the halos of a patch mesh node.
virtual void create(Geometry::MeshFileReader &)
Creates a domain control from a MeshFileReader.
static constexpr int shape_dim
shape dimension
CGALDomainControl(const Dist::Comm &comm_, bool support_multi_layered)
Constructor.
Adjacency::Coloring _compute_base_mesh_coloring(const MeshNodeType &slag_node) const
Computes the coloring for the unpartitioned base mesh.
std::vector< WeightType > gather_element_weights(Index level) const
Gathers the element map weights on a given domain level.
String dump_slag_layer_levels() const
Debugging function: Returns a string containing encoded slag layer level information.
virtual ~CGALDomainControl()
virtual destructor
std::array< Index, shape_dim > _base_slices
number of element slices on base mesh level 0
Adjacency::Coloring _compute_base_mesh_layering(const MeshNodeType &slag_node) const
Computes the element layering for the unpartitioned base mesh.
Adjacency::Coloring _compute_refined_mesh_coloring(const MeshNodeType &slag_node) const
Computes the coloring for a refined mesh.
std::vector< WeightType > _compute_weights(Ancestor &ancestor, const MeshNodeType &base_mesh_node) override
Computes the element partitioning weights.
const Geometry::CGALWrapper< CoordType > * get_cgal_wrapper() const
std::unique_ptr< MeshNodeType > _base_mesh_node
the input base-mesh node on level 0
Adjacency::Coloring _extract_patch_layering(const MeshNodeType &slag_node, const Adjacency::Coloring &parent_layering, int child_rank) const
Extracts a patch layering from the parent mesh layering.
virtual void create(const std::deque< String > &filenames, String dirpath="")
Creates a domain control from a list of filenames.
const StopWatch & get_watch_hierarchy() const
Returns a const reference to the StopWatch that measures the base-mesh creation phase.
virtual std::unique_ptr< MeshNodeType > _deslag_mesh_node(MeshNodeType &mesh_node, const Ancestor &ancestor, bool is_child)
Deslags a (potentially partitioned) mesh node including its mesh-parts and halos.
Control::Domain::PartiDomainControlBase< DomainLevel_ > BaseClass
our base class
std::vector< WeightType > _gather_element_weights(const MeshType &mesh) const
Gathers the element slag weights for a given mesh.
std::unique_ptr< Geometry::CGALWrapper< CoordType > > _cgal_wrapper
cgal wrapper
void create_hierarchy()
Creates the domain level hierarchy.
void cheap_weight_calculation(bool option)
set whether we use an expensive or cheap method to calculate the element weights
Geometry::CGALWrapper< CoordType > * get_cgal_wrapper()
const StopWatch & get_watch_cgal_wrapper() const
Returns a const reference to the StopWatch that measures the voxel-map creation phase.
const StopWatch & get_watch_base_mesh() const
Returns a const reference to the StopWatch that measures the base-mesh creation phase.
virtual void _create_multi_layered(std::unique_ptr< MeshNodeType > base_mesh_node)
Creates a multi-layered mesh hierarchy.
std::vector< Index > _gather_masked_elements(const MeshType &mesh, const Dist::Comm &sibling_comm) const
Gather a vector of element indices that intersect the masked domain in a copperative manner.
Geometry::CGALWrapper< CoordType > * release_cgal_wrapper()
Releases the internal cgal wrapper.
MeshNodeType & create_base_mesh_3d(Index num_x, Index num_y, Index num_z, CoordType x_min, CoordType x_max, CoordType y_min, CoordType y_max, CoordType z_min, CoordType z_max)
Creates a 3D structured cuboid base mesh and returns its base-mesh node.
MeshNodeType & set_base_mesh(std::unique_ptr< MeshNodeType > &&mesh_node)
Set another mesh as base mesh.
Wrapper class for domain levels for VoxelDomainControl.
std::shared_ptr< DomainLevel_ > slag_level
attachable slag level
DomainLevel_ BaseClass
our base-class; the actual domain level
Adjacency::Coloring element_coloring
element coloring
bool _keep_base_levels
keep base-mesh levels on root process?
Dist::Comm progeny_comm
Progeny communicator.
int desired_level_max
the desired minimum and maximum refinement levels for this layer
int parti_level
the refinement level on which the patch is to be partitioned
String parti_info
a string containing some information about the chosen partitioning
bool parti_found
specifies whether a partitioning was found
Adjacency::Graph parti_graph
this is the actual elements-at-rank partitioning graph
int progeny_group
Progeny group of this process.
int layer_p
the index of the parent layer or -1, if this process is not part of the parent layer
int layer
the index of the layer that this ancestor object belongs to
int num_parts
the number of partitions for each patch of the parent layer
int progeny_child
Which direct child this process belongs to in its progeny group.
Base-Class for Hierarchical Domain Control implementations.
std::deque< std::pair< int, int > > _desired_levels
desired level deque
std::deque< std::pair< int, int > > _chosen_levels
chosen level deque
virtual void _create_ancestry_scattered()
Creates the layers for a multi-layered domain control in a scattered fashion.
Real WeightType
weight type for partitioner element weights; always Real
std::deque< Ancestor > _ancestry
the partition ancestry deque
Geometry::RootMeshNode< MeshType > MeshNodeType
our root mesh node type
LevelType::PartType MeshPartType
our mesh-part type
virtual void _create_ancestry_single()
Creates the ancestry for a single layer (or a single process)
Geometry::AdaptMode _adapt_mode
the adapt mode for refinement
bool _was_created
specifies whether the domain control was already created
virtual bool _check_parti(Ancestor &ancestor, const MeshNodeType &mesh_node, bool is_base_layer)
Checks for an appropriate partitioning strategy.
bool _support_multi_layered
support multi-layered hierarchy?
virtual bool _apply_parti(Ancestor &ancestor, MeshNodeType &base_mesh_node)
Applies an a-posteriori partitioner.
virtual void _create_multi_layers_scattered()
Creates the layers for a multi-layered domain control in a scattered fashion.
virtual void _split_basemesh_halos(const Ancestor &ancestor, const MeshNodeType &base_mesh_node, MeshNodeType &patch_mesh_node, std::vector< int > &neighbor_ranks)
Splits the base-mesh halos and computes the inter-patch-mesh halos.
Cubature Rule class template.
void bcast(void *buffer, std::size_t count, const Datatype &datatype, int root) const
Blocking broadcast.
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.
Comm comm_dup() const
Creates a copy of this communicator.
void allgatherv(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, const int *recvcounts, const int *displs, const Datatype &recvtype) const
Blocking gather-to-all.
int rank() const
Returns the rank of this process in this communicator.
void allgather(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype) const
Blocking gather-to-all.
Communication Request vector class.
void wait_all()
Blocks until all active requests are fulfilled.
static void read_common(std::stringstream &stream, const String &filename, const Dist::Comm &comm, int root_rank=0)
Reads a common text file for all ranks.
Wrapper for the CGAL Library.
MeshType * get_mesh()
Returns the mesh of this node.
Class template for partial meshes.
Base-Mesh Patch Halo splitter.
std::unique_ptr< RootMeshNode > extract_patch(std::vector< Index > &&elements, bool split_meshparts, bool split_halos, bool split_patches)
Extracts a patch from the root mesh as a new mesh node.
const MeshPartType * get_patch(int rank) const
Returns a patch meshpart for a given child.
static std::unique_ptr< RootMeshNode > make_unique(std::unique_ptr< MeshType > mesh, MeshAtlasType *atlas=nullptr)
Creates a new RootMeshNode on the heap and returns a unique pointer to it.
const std::map< int, std::unique_ptr< MeshPartType > > & get_halo_map() const
void add_halo(int rank, std::unique_ptr< MeshPartType > halo_part)
Adds a halo mesh part to this mesh node.
Structured unit-cube mesh factory.
Index get_num_entities() const
Returns the number of entities.
Math Limits class template.
static double toe_partition
time of partitioning in seconds, needs initialization
double elapsed() const
Returns the total elapsed time in seconds.
void start()
Starts the stop-watch.
void stop()
Stops the stop-watch and increments elapsed time.
String class implementation.
String pad_front(size_type len, char c=' ') const
Pads the front of the string up to a desired length.
Tiny Vector class template.
Standard transformation mapping class template.
@ transpose
Render-Transpose mode.
@ injectify
Render-Injectified mode.
const Operation op_min(MPI_MIN)
Operation wrapper for MPI_MIN.
const Operation op_max(MPI_MAX)
Operation wrapper for MPI_MAX.
T_ min(T_ a, T_ b)
Returns the minimum of two values.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
String stringify(const T_ &item)
Converts an item into a String.
std::uint64_t Index
Index data type.
TrafoTags
Trafo configuration tags enum.
@ img_point
specifies whether the trafo should supply image point coordinates
@ dom_point
specifies whether the trafo should supply domain point coordinates
@ jac_det
specifies whether the trafo should supply jacobian determinants