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/geometry/voxel_map.hpp>
30#include <control/domain/parti_domain_control_base.hpp>
48 template<
typename DomainLevel_>
56 using typename BaseClass::MeshType;
58 using typename BaseClass::MeshNodeType;
86 slag_level = std::make_shared<DomainLevel_>(_lvl_idx, std::move(slag_node));
95 template<
typename DomainLevel_>
103 using typename BaseClass::LevelType;
107 using typename BaseClass::MeshType;
186 this->_keep_voxel_map =
true;
223 XASSERTM(
shape_dim == 2,
"invalid dimension: this function can only be called for 2D domains!");
236 _bbox_max[0] = x_max;
238 _bbox_max[1] = y_max;
246 Index n = vtx.get_num_vertices();
247 for(
Index i(0); i < n; ++i)
249 vtx[i][0] = x_min + (x_max - x_min) * vtx[i][0];
250 vtx[i][1] = y_min + (y_max - y_min) * vtx[i][1];
256 this->_create_stage = 1;
290 XASSERTM(
shape_dim == 3,
"invalid dimension: this function can only be called for 3D domains!");
306 _bbox_max[0] = x_max;
308 _bbox_max[1] = y_max;
310 _bbox_max[2] = z_max;
318 Index n = vtx.get_num_vertices();
319 for(
Index i(0); i < n; ++i)
321 vtx[i][0] = x_min + (x_max - x_min) * vtx[i][0];
322 vtx[i][1] = y_min + (y_max - y_min) * vtx[i][1];
323 vtx[i][2] = z_min + (z_max - z_min) * vtx[i][2];
329 this->_create_stage = 1;
335 MeshNodeType& set_base_mesh(std::unique_ptr<MeshNodeType>&& mesh_node)
354 Index n = vtx.get_num_vertices();
355 for(
Index i(0); i < n; ++i)
360 _bbox_max[k] =
Math::max(_bbox_max[k], vtx[i][k]);
367 this->_create_stage = 1;
370 this->_unstructered_mesh =
true;
387 this->_voxel_map->set_out_of_bounds_value(
value);
411 XASSERTM(this->_create_stage >= 1,
"invalid creation stage; create the base-mesh first");
412 XASSERTM(this->_create_stage <= 1,
"invalid creation stage: voxel map already set");
414 this->_watch_create_voxel_map.
start();
415#ifdef FEAT_COMPILER_CLANG
418 this->_voxel_map = std::make_unique<Geometry::VoxelMap>();
421 this->_voxel_map->compute_map(this->_comm, masker,
true);
422 this->_watch_create_voxel_map.
stop();
425 this->_create_stage = 2;
449 template<
typename Lambda_>
452 XASSERTM(this->_create_stage >= 1,
"invalid creation stage; create the base-mesh first");
453 XASSERTM(this->_create_stage <= 1,
"invalid creation stage: voxel map already set");
455 this->_watch_create_voxel_map.
start();
456#ifdef FEAT_COMPILER_CLANG
459 this->_voxel_map = std::make_unique<Geometry::VoxelMap>();
463 this->_voxel_map->compute_map_from_lambda_2d(this->_comm, std::forward<Lambda_>(lambda),
true);
465 this->_voxel_map->compute_map_from_lambda_3d(this->_comm, std::forward<Lambda_>(lambda),
true);
466 this->_watch_create_voxel_map.
stop();
469 this->_create_stage = 2;
494 XASSERTM(this->_create_stage >= 1,
"invalid creation stage; create the base-mesh first");
495 XASSERTM(this->_create_stage <= 1,
"invalid creation stage: voxel map already set");
497 this->_watch_create_voxel_map.
start();
498#ifdef FEAT_COMPILER_CLANG
501 this->_voxel_map = std::make_unique<Geometry::VoxelMap>();
504 this->_voxel_map->compute_map_from_chart(this->_comm, chart, invert,
true);
505 this->_watch_create_voxel_map.
stop();
508 this->_create_stage = 2;
534 std::stringstream sstr;
564 XASSERTM(this->_create_stage >= 1,
"invalid creation stage; create the base-mesh first");
565 XASSERTM(this->_create_stage <= 1,
"invalid creation stage: voxel map already set");
570 this->_watch_create_voxel_map.
start();
572#ifdef FEAT_COMPILER_CLANG
575 this->_voxel_map = std::make_unique<Geometry::VoxelMap>();
578 this->_voxel_map->compute_map_from_off_3d(this->_comm, is, invert,
true);
580 this->_watch_create_voxel_map.
stop();
583 this->_create_stage = 2;
597 XASSERTM(this->_create_stage >= 1,
"invalid creation stage; create the base-mesh first");
598 XASSERTM(this->_create_stage <= 1,
"invalid creation stage: voxel map already set");
600 this->_watch_create_voxel_map.
start();
602#ifdef FEAT_COMPILER_CLANG
605 this->_voxel_map = std::make_unique<Geometry::VoxelMap>();
609 this->_watch_create_voxel_map.
stop();
612 this->_create_stage = 2;
628 XASSERTM(this->_voxel_map,
"voxel map not created yet");
629 return this->_voxel_map->write(filename);
640 XASSERTM(this->_create_stage >= 2,
"invalid creation stage; create the base-mesh and voxel map first");
641 XASSERTM(this->_create_stage <= 2,
"invalid creation stage: domain hierarchy already created");
643 this->_watch_create_hierarchy.
start();
647 if(this->_comm.
size() == 1)
671 this->compile_virtual_levels();
673 this->_watch_create_hierarchy.
stop();
677 this->_watch_create_voxel_map.
elapsed() + this->_watch_create_hierarchy.
elapsed();
680 this->_create_stage = 3;
684 if(!this->_keep_voxel_map)
685 this->_voxel_map.reset();
697 return this->_watch_create_voxel_map;
703 return this->_watch_create_hierarchy;
725 XASSERTM(this->_create_stage == 3,
"domain level hierarchy has to be created before the vertex mask can be computed");
726 XASSERT(level < this->size_physical());
728 const auto& vtx = this->at(level)->get_mesh().get_vertex_set();
729 const Index nv = vtx.get_num_vertices();
730 std::vector<int> mask(nv, 0);
732 for(
Index i(0); i < nv; ++i)
733 mask[i] = this->_voxel_map->check_point_nearest(vtx[i]);
753 XASSERT(level < this->size_physical());
763 for(
auto it = this->_layer_levels.begin(); it != this->_layer_levels.end(); ++it)
765 if(it != this->_layer_levels.begin())
767 for(
auto jt = it->begin(); jt != it->end(); ++jt)
769 msg +=
" " +
stringify((*jt)->get_level_index());
773 if((*jt)->slag_level)
774 ((msg +=
"<[") +=
stringify((*jt)->slag_level->get_mesh().get_num_elements()).pad_front(4)) +=
"]";
789 virtual void create(
const std::deque<String>& filenames,
String dirpath =
"")
792 ASSERTM(
false,
"Thou shall not arrive here!");
806 ASSERTM(
false,
"Thou shall not arrive here!");
815 virtual void create(std::unique_ptr<MeshNodeType>&)
818 ASSERTM(
false,
"Thou shall not arrive here!");
829 this->_voxel_map->set_bounding_box_2d(this->_bbox_min[0], this->_bbox_max[0], this->_bbox_min[1], this->_bbox_max[1]);
831 this->_voxel_map->set_bounding_box_3d(this->_bbox_min[0], this->_bbox_max[0],
832 this->_bbox_min[1], this->_bbox_max[1], this->_bbox_min[2], this->_bbox_max[2]);
835 if(resolution >
Real(0))
837 this->_voxel_map->set_resolution(resolution);
842 XABORTM(
"Required to provide resolution for voxel map");
847 Real base_res = (this->_bbox_max[0] - this->_bbox_min[0]) /
Real(this->_base_slices[0]);
849 base_res =
Math::min(base_res, this->_bbox_max[i] - this->_bbox_min[i]) /
Real(this->_base_slices[std::size_t(i)]);
871 const Index num_elems = mesh.get_num_elements();
874 std::vector<Index> masked_elems;
875 masked_elems.reserve(num_elems);
878 const auto& vtx = mesh.get_vertex_set();
879 const auto& verts_at_elem = mesh.template get_index_set<shape_dim, 0>();
885 for(
Index ielem(0); ielem < num_elems; ++ielem)
895 elbox_min = elbox_max = vtx[verts_at_elem(ielem, 0)];
896 for(
int j(1); j < verts_at_elem.num_indices; ++j)
898 const auto& v = vtx[verts_at_elem(ielem, j)];
904 if(this->_voxel_map->check_box(elbox_min, elbox_max))
905 masked_elems.push_back(ielem);
927 const Index num_elems = mesh.get_num_elements();
930 std::vector<WeightType> weights(num_elems, 0.0);
933 const auto& vtx = mesh.get_vertex_set();
934 const auto& verts_at_elem = mesh.template get_index_set<shape_dim, 0>();
940 for(
Index ielem(0); ielem < num_elems; ++ielem)
950 elbox_min = elbox_max = vtx[verts_at_elem(ielem, 0)];
951 for(
int j(1); j < verts_at_elem.num_indices; ++j)
953 const auto& v = vtx[verts_at_elem(ielem, j)];
959 weights[ielem] = this->_voxel_map->sample_box(elbox_min, elbox_max);
983 XASSERTM(mesh_node.
get_halo_map().empty(),
"This function must not be used for partitioned mesh nodes!");
1036 const std::map<int, std::unique_ptr<MeshPartType>>& base_halo_map = base_mesh_node.
get_halo_map();
1039 if(base_halo_map.empty())
1043 const std::size_t num_halos = base_halo_map.size();
1049 std::vector<int> halo_ranks;
1050 std::vector<std::size_t> halo_send_sizes;
1051 for(
auto it = base_halo_map.begin(); it != base_halo_map.end(); ++it)
1054 halo_ranks.push_back(it->first);
1057 halo_send_sizes.push_back(halo_splitter.add_halo(it->first, *it->second));
1061 std::vector<std::size_t> halo_recv_sizes(num_halos);
1062 std::vector<std::vector<Index>> halo_send_data(num_halos), halo_recv_data(num_halos);
1068 const int layer_idx = is_child ? ancestor.
layer_p : ancestor.
layer;
1071 for(std::size_t i(0); i < num_halos; ++i)
1074 if(halo_send_sizes.at(i) > std::size_t(0))
1075 halo_send_data.at(i) = halo_splitter.serialize_split_halo(halo_ranks[i], -1);
1082 const Dist::Comm& layer_comm = this->_layers.at(std::size_t(layer_idx))->comm();
1085 for(std::size_t i(0); i < num_halos; ++i)
1088 halo_recv_reqs[i] = layer_comm.
irecv(&halo_recv_sizes[i], std::size_t(1), halo_ranks[i]);
1091 halo_send_reqs[i] = layer_comm.
isend(&halo_send_sizes[i], std::size_t(1), halo_ranks[i]);
1095 halo_recv_reqs.wait_all();
1099 for(std::size_t i(0); i < num_halos; ++i)
1102 if(halo_recv_sizes[i] >
Index(0))
1105 halo_recv_data.at(i).resize(halo_recv_sizes[i]);
1106 halo_recv_reqs[i] = layer_comm.
irecv(halo_recv_data.at(i).data(), halo_recv_sizes.at(i), halo_ranks[i]);
1110 if(halo_send_sizes.at(i) >
Index(0))
1113 halo_send_reqs[i] = layer_comm.
isend(halo_send_data.at(i).data(), halo_send_sizes.at(i), halo_ranks[i]);
1118 halo_recv_reqs.wait_all();
1126 ancestor.progeny_comm.
bcast(halo_recv_sizes.data(), num_halos, 0);
1129 if(ancestor.progeny_comm.
rank() != 0)
1131 for(std::size_t i(0); i < num_halos; ++i)
1132 halo_recv_data.at(i).resize(halo_recv_sizes[i]);
1136 for(std::size_t i(0); i < num_halos; ++i)
1138 if(halo_recv_sizes[i] > std::size_t(0))
1139 ancestor.progeny_comm.
bcast(halo_recv_data[i].data(), halo_recv_sizes[i], 0);
1157 std::vector<std::array<Index, shape_dim+1>> halo_send_intsec_sizes(num_halos), halo_recv_intsec_sizes(num_halos);
1160 for(std::size_t i(0); i < num_halos; ++i)
1163 if(halo_recv_sizes.at(i) ==
Index(0))
1167 if(!halo_splitter.intersect_split_halo(halo_ranks[i], halo_recv_data.at(i), 0u))
1171 std::unique_ptr<MeshPartType> split_halo = halo_splitter.make_unique();
1175 halo_send_intsec_sizes[i][
Index(j)] = split_halo->get_num_entities(j);
1178 patch_mesh_node.
add_halo(halo_ranks[i], std::move(split_halo));
1182 if((ancestor.
layer_p >= 0) || (!is_child && (ancestor.
layer >= 0)))
1185 const LayerType& layer = *this->_layers.at(std::size_t(is_child ? ancestor.
layer_p : ancestor.
layer));
1188 for(std::size_t i(0); i < num_halos; ++i)
1190 halo_recv_reqs[i] = layer.comm().
irecv(halo_recv_intsec_sizes.at(i).data(), std::size_t(
shape_dim+1), halo_ranks[i]);
1191 halo_send_reqs[i] = layer.comm().
isend(halo_send_intsec_sizes.at(i).data(), std::size_t(
shape_dim+1), halo_ranks[i]);
1195 halo_recv_reqs.wait_all();
1199 for(std::size_t i(0); i < num_halos; ++i)
1203 if(halo_recv_intsec_sizes[i][
Index(j)] != halo_send_intsec_sizes[i][
Index(j)])
1205 String msg =
"Inconsistent deslagged halo size between process ";
1207 msg +=
" and neighbor with layer rank ";
1230 const auto& verts_at_elem = base_node.get_mesh()->template get_index_set<MeshType::shape_dim, 0>();
1239 #ifdef FEAT_DEBUG_MODE
1240 std::cout <<
"Unstructered Layering Computation not implemented yet!";
1258 XASSERT(slag_part !=
nullptr);
1259 const Geometry::TargetSet& slag_target = slag_part->template get_target_set<MeshType::shape_dim>();
1262 const Index num_colors =
Index(1) << MeshType::shape_dim;
1270 if constexpr(MeshType::shape_dim == 1)
1272 for(
Index i(0); i < num_elems; ++i)
1273 colors[i] = slag_target[i] & 1;
1275 else if constexpr(MeshType::shape_dim == 2)
1277 for(
Index i(0); i < num_elems; ++i)
1279 Index iel = slag_target[i];
1280 Index ix = iel % this->_base_slices[0];
1281 Index iy = iel / this->_base_slices[0];
1282 colors[i] = (ix & 1) | ((iy & 1) << 1);
1285 else if constexpr(MeshType::shape_dim == 3)
1287 for(
Index i(0); i < num_elems; ++i)
1289 Index iel = slag_target[i];
1290 Index ix = iel % this->_base_slices[0];
1291 Index iy = (iel / this->_base_slices[0]) % this->_base_slices[1];
1292 Index iz = iel / (this->_base_slices[0] * this->_base_slices[1]);
1293 colors[i] = (ix & 1) | ((iy & 1) << 1) | ((iz & 1) << (1 << 1));
1313 XASSERT(slag_part !=
nullptr);
1314 const Geometry::TargetSet& slag_target = slag_part->template get_target_set<MeshType::shape_dim>();
1317 const Index num_colors =
Index(1) << MeshType::shape_dim;
1325 for(
Index i(0); i < num_elems; ++i)
1326 colors[i] = slag_target[i] % num_colors;
1350 XASSERT(patch_part !=
nullptr);
1351 const Geometry::TargetSet& patch_target = patch_part->template get_target_set<MeshType::shape_dim>();
1362 for(
Index i(0); i < num_elems; ++i)
1363 colors[i] = parent_coloring[patch_target[i]];
1381 XASSERT(slag_part !=
nullptr);
1382 const Geometry::TargetSet& slag_target = slag_part->template get_target_set<MeshType::shape_dim>();
1392 denom *= this->_base_slices[
Index(j)];
1395 std::vector<Index> aux(max_layers, 0u);
1396 for(
Index i(0); i < num_elems; ++i)
1397 ++aux[slag_target[i] / denom];
1400 Index num_layers = 0u;
1401 for(
Index i(0); i < max_layers; ++i)
1403 Index k = num_layers;
1412 for(
Index i(0); i < num_elems; ++i)
1413 layers[i] = aux[slag_target[i] / denom];
1435 XASSERT(slag_part !=
nullptr);
1436 const Geometry::TargetSet& slag_target = slag_part->template get_target_set<MeshType::shape_dim>();
1444 std::vector<Index> aux(max_layers, 0u);
1445 for(
Index i(0); i < num_elems; ++i)
1448 ++aux[(coarse_layering[qux >> 1] << 1) | (qux & 1)];
1452 Index num_layers = 0u;
1453 for(
Index i(0); i < max_layers; ++i)
1455 Index k = num_layers;
1464 for(
Index i(0); i < num_elems; ++i)
1467 layers[i] = aux[(coarse_layering[qux >> 1] << 1) | (qux & 1)];
1494 XASSERT(patch_part !=
nullptr);
1495 const Geometry::TargetSet& patch_target = patch_part->template get_target_set<MeshType::shape_dim>();
1503 std::vector<Index> aux(max_layers, 0u);
1504 for(
Index i(0); i < num_elems; ++i)
1505 ++aux[parent_layering[patch_target[i]]];
1508 Index num_layers = 0u;
1509 for(
Index i(0); i < max_layers; ++i)
1511 Index k = num_layers;
1520 for(
Index i(0); i < num_elems; ++i)
1521 layers[i] = aux[parent_layering[patch_target[i]]];
1540 this->push_layer(std::make_shared<LayerType>(this->_comm.
comm_dup(), 0));
1550 std::unique_ptr<MeshNodeType> base_slag_node = std::move(base_mesh_node);
1559 for(; lvl < ancestor.desired_level_min; ++lvl)
1561 base_slag_node = base_mesh_node->refine_unique(this->
_adapt_mode);
1570 base_coloring = this->_compute_unstructered_coloring(*base_mesh_node);
1588 auto refined_node = base_mesh_node->refine_unique(this->
_adapt_mode);
1591 std::shared_ptr<LevelType> level_ptr = std::make_shared<LevelType>(lvl, std::move(base_mesh_node),
1592 std::move(base_slag_node), std::move(base_coloring), std::move(base_layering));
1593 this->push_level_front(0, level_ptr);
1596 base_slag_node = std::move(refined_node);
1606 this->push_level_front(0, std::make_shared<LevelType>(lvl, std::move(base_mesh_node),
1607 std::move(base_slag_node), std::move(base_coloring), std::move(base_layering)));
1613#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
1624 std::shared_ptr<LayerType> layer = std::make_shared<LayerType>(this->_comm.
comm_dup(), 0);
1625 this->push_layer(layer);
1634 std::unique_ptr<MeshNodeType> base_slag_node = std::move(base_mesh_node);
1646 if((lvl >= ancestor.
parti_level) && this->_apply_parti(ancestor, *base_mesh_node))
1654 base_slag_node = base_mesh_node->refine_unique(this->
_adapt_mode);
1673 std::vector<int> neighbor_ranks;
1674 std::unique_ptr<MeshNodeType> patch_mesh_node(
1675 base_mesh_node->extract_patch(neighbor_ranks, ancestor.
parti_graph, this->_comm.rank()));
1679 if(lvl == ancestor.desired_level_min)
1686 layer->set_neighbor_ranks(neighbor_ranks);
1689 std::unique_ptr<MeshNodeType> patch_slag_node;
1692 for(; lvl < ancestor.desired_level_min; ++lvl)
1695 patch_slag_node = patch_mesh_node->refine_unique(this->
_adapt_mode);
1701 if(patch_coloring.
empty())
1712 auto refined_node = patch_mesh_node->refine_unique(this->
_adapt_mode);
1715 std::shared_ptr<LevelType> level_ptr = std::make_shared<LevelType>(lvl, std::move(patch_mesh_node),
1716 std::move(patch_slag_node), std::move(patch_coloring), std::move(patch_layering));
1719 this->push_level_front(0, level_ptr);
1722 patch_slag_node = std::move(refined_node);
1732 this->push_level_front(0, std::make_shared<LevelType>(lvl, std::move(patch_mesh_node),
1733 std::move(patch_slag_node), std::move(patch_coloring), std::move(patch_layering)));
1757 std::unique_ptr<MeshNodeType> parent_slag_node;
1758 std::unique_ptr<MeshNodeType> parent_mesh_node = this->
_deslag_mesh_node(*base_mesh_node);
1764 base_mesh_node.reset();
1767 for(std::size_t slayer = this->
_ancestry.size(); slayer > std::size_t(0); )
1770 const bool is_base_layer = (slayer == this->
_ancestry.size());
1778 int parent_min_lvl = -1;
1785 this->
_check_parti(ancestor, *parent_mesh_node, is_base_layer);
1823 auto refined_node = parent_mesh_node->refine_unique(this->
_adapt_mode);
1826 std::shared_ptr<LevelType> level_ptr;
1829 if((ancestor.
layer_p >= 0) && (parent_min_lvl >= 0) && (lvl >= parent_min_lvl))
1831 level_ptr = std::make_shared<LevelType>(lvl, std::move(parent_mesh_node),
1832 std::move(parent_slag_node), std::move(parent_coloring), std::move(parent_layering));
1833 this->push_level_front(ancestor.
layer_p, level_ptr);
1837 parent_slag_node = std::move(refined_node);
1838 parent_mesh_node = this->
_deslag_mesh_node(*parent_slag_node, ancestor, !is_base_layer);
1841 level_ptr ? level_ptr->element_layering : parent_layering);
1851 std::vector<int> neighbor_ranks;
1852 std::unique_ptr<MeshNodeType> patch_mesh_node(
1853 parent_mesh_node->extract_patch(neighbor_ranks, ancestor.
parti_graph, ancestor.progeny_child));
1862 std::unique_ptr<MeshNodeType> patch_slag_node;
1867 std::map<int,int> halo_map;
1868 for(
auto& i : neighbor_ranks)
1871 halo_map.emplace(old_i, i += ancestor.progeny_group);
1873 patch_mesh_node->rename_halos(halo_map);
1880 for(
int i(1); i < ancestor.
num_parts; ++i)
1882 parent_mesh_node->create_patch_meshpart(ancestor.
parti_graph, i);
1897 XASSERTM(lvl == global_level_min,
"INTERNAL ERROR");
1925 if(ancestor.
layer >= 0)
1928 this->_layers.at(std::size_t(ancestor.
layer))->set_neighbor_ranks(neighbor_ranks);
1934 else if(parent_min_lvl < 0)
1938 this->
_chosen_levels.push_front(std::make_pair(parent_min_lvl, 0));
1943 std::shared_ptr<LevelType> level_ptr;
1948 this->push_level_front(ancestor.
layer_p, std::make_shared<LevelType>(lvl, std::move(parent_mesh_node),
1949 std::move(parent_slag_node), std::move(parent_coloring), std::move(parent_layering)));
1953 parent_slag_node = std::move(patch_slag_node);
1954 parent_mesh_node = std::move(patch_mesh_node);
1955 parent_coloring = std::move(patch_coloring);
1956 parent_layering = std::move(patch_layering);
1964 for(; lvl < desired_level_max; ++lvl)
1967 auto refined_node = parent_mesh_node->refine_unique(this->
_adapt_mode);
1970 std::shared_ptr<LevelType> level_ptr = std::make_shared<LevelType>(lvl, std::move(parent_mesh_node),
1971 std::move(parent_slag_node), std::move(parent_coloring), std::move(parent_layering));
1975 this->push_level_front(0, level_ptr);
1978 parent_slag_node = std::move(refined_node);
1988 this->push_level_front(0, std::make_shared<LevelType>(lvl, std::move(parent_mesh_node),
1989 std::move(parent_slag_node), std::move(parent_coloring), std::move(parent_layering)));
#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.
bool _keep_base_levels
keep base-mesh levels on root process?
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 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
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
int get_desired_level_max() const
Returns the desired maximum refinement level.
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.
Hierarchical partitioned Voxel Domain Control.
void create_voxel_map_from_off(std::istream &is, bool invert, Real resolution)
Creates a voxel map based on a surface triangulation stored in an OFF file.
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.
Adjacency::Coloring _compute_base_mesh_coloring(const MeshNodeType &slag_node) const
Computes the coloring for the unpartitioned base mesh.
virtual void _create_multi_layered(std::unique_ptr< MeshNodeType > base_mesh_node)
Creates a multi-layered mesh hierarchy.
std::unique_ptr< MeshNodeType > _base_mesh_node
the input base-mesh node on level 0
virtual std::unique_ptr< MeshNodeType > _deslag_mesh_node(MeshNodeType &mesh_node)
Deslags an unpartitioned mesh node including its mesh-parts.
std::vector< Index > _gather_masked_elements(const MeshType &mesh) const
Gather a vector of element indices that intersect the masked domain.
Geometry::VoxelMap::WriteResult write_voxel_map(const String &filename)
Writes the voxel map to a voxel map file.
void create_hierarchy()
Creates the domain level hierarchy.
bool _unstructered_mesh
specifies whether we use a non voxel base mesh
const StopWatch & get_watch_voxel_map() const
Returns a const reference to the StopWatch that measures the voxel-map creation phase.
Geometry::RootMeshNode< MeshType > MeshNodeType
our root mesh node type
static constexpr int shape_dim
shape dimension
void _precreate_voxel_map(Real resolution)
Pre-creates the voxel map by setting the bounding box and resolution.
Control::Domain::PartiDomainControlBase< DomainLevel_ > BaseClass
our base class
virtual void create(Geometry::MeshFileReader &)
Creates a domain control from a MeshFileReader.
const StopWatch & get_watch_hierarchy() const
Returns a const reference to the StopWatch that measures the base-mesh creation phase.
Adjacency::Coloring _compute_refined_mesh_layering(const MeshNodeType &slag_node, const Adjacency::Coloring &coarse_layering) const
Computes the layering for a refined mesh.
virtual void create(std::unique_ptr< MeshNodeType > &)
Creates a domain control from a base-mesh node.
Tiny::Vector< CoordType, shape_dim > _bbox_min
the bounding box of the structured domain
bool _keep_voxel_map
specifies whether to keep the voxel map after hierarchy creation
StopWatch _watch_create_base_mesh
a bunch of stop-watches
void create_voxel_map_from_lambda(Lambda_ &&lambda, Real resolution)
Creates a voxel map based on a lambda expression.
Adjacency::Coloring _compute_refined_mesh_coloring(const MeshNodeType &slag_node) const
Computes the coloring for a refined mesh.
MeshNodeType & create_base_mesh_2d(Index num_x, Index num_y, CoordType x_min, CoordType x_max, CoordType y_min, CoordType y_max)
Creates a 2D structured rectangle base mesh and returns its base-mesh node.
int _create_stage
creation stage to keep track what has already been initialized
void create_voxel_map(Geometry::VoxelMasker< CoordType, shape_dim > &masker, Real resolution=Real(0))
Creates a voxel map based on a VoxelMasker object.
virtual void create(const std::deque< String > &filenames, String dirpath="")
Creates a domain control from a list of filenames.
std::vector< WeightType > _gather_element_weights(const MeshType &mesh) const
Gathers the element slag weights for a given mesh.
const StopWatch & get_watch_base_mesh() const
Returns a const reference to the StopWatch that measures the base-mesh creation phase.
MeshType::CoordType CoordType
coordinate type
void set_voxel_map_out_of_bounds_balue(bool value)
Sets the out-of-bounds value for the voxel map.
std::vector< int > gather_vertex_voxel_map(Index level) const
Gathers the vertex voxel map on a given domain level.
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.
virtual void _create_single_layered(std::unique_ptr< MeshNodeType > base_mesh_node)
Creates a single-layered mesh hierarchy.
virtual ~VoxelDomainControl()
virtual destructor
std::vector< WeightType > gather_element_voxel_weights(Index level) const
Gathers the element voxel map weights on a given domain level.
std::array< Index, shape_dim > _base_slices
number of element slices on base mesh 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.
VoxelDomainControl(const Dist::Comm &comm_, bool support_multi_layered)
Constructor.
Adjacency::Coloring _compute_base_mesh_layering(const MeshNodeType &slag_node) const
Computes the element layering for the unpartitioned base mesh.
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.
void create_voxel_map_from_chart(const Geometry::Atlas::ChartBase< MeshType > &chart, bool invert, Real resolution)
Creates a voxel map based on a chart.
Geometry::VoxelMap::ReadResult read_voxel_map(const String &filename)
Reads the voxel map from a voxel map file.
virtual void _create_single_process(std::unique_ptr< MeshNodeType > base_mesh_node)
Creates a single-layered mesh hierarchy for a single process.
const Geometry::VoxelMap & get_voxel_map() const
Returns a const reference to the internal voxel map.
void keep_voxel_map()
Instructs the domain controller to keep the voxel map after hierarchy creation.
void create_voxel_map_from_off(const String &filename, bool invert, Real resolution)
Creates a voxel map based on a surface triangulation stored in an OFF file.
std::unique_ptr< Geometry::VoxelMap > _voxel_map
the voxel map
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.
String dump_slag_layer_levels() const
Debugging function: Returns a string containing encoded slag layer level information.
Wrapper class for domain levels for VoxelDomainControl.
Adjacency::Coloring element_layering
element layering (stored as coloring)
DomainLevel_ BaseClass
our base-class; the actual domain level
std::shared_ptr< DomainLevel_ > slag_level
attachable slag level
Adjacency::Coloring element_coloring
element coloring
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.
int rank() const
Returns the rank of this process in this communicator.
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.
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.
helper class for read function result
helper class for write function result
Interface for voxel masker for the VoxelMap class.
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.
@ 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.
void minimax(T_ x, T_ &a, T_ &b)
Updates the minimum and maximum.
T_ min(T_ a, T_ b)
Returns the minimum of two values.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
double Real
Real data type.
String stringify(const T_ &item)
Converts an item into a String.
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.