8#include <kernel/geometry/mesh_node.hpp>
9#include <kernel/geometry/mesh_quality_heuristic.hpp>
10#include <kernel/util/dist.hpp>
12#include <kernel/util/math.hpp>
14#include <control/domain/domain_level.hpp>
79 _comm(std::forward<Dist::Comm>(comm_)),
95 virtual ~DomainLayer()
99 void set_parent(
Dist::Comm&& sibling_comm_,
int parent_rank)
105 std::size_t bytes()
const
110 const Dist::Comm& comm()
const
115 const Dist::Comm* comm_ptr()
const
120 const Dist::Comm* sibling_comm_ptr()
const
125 bool is_child()
const
130 bool is_parent()
const
135 bool is_ghost()
const
137 return is_child() && !is_parent();
140 int get_layer_index()
const
145 int get_parent_rank()
const
150 Index child_count()
const
155 Index neighbor_count()
const
160 void push_neighbor(
int neighbor_rank_)
165 int neighbor_rank(
Index i)
const
170 void set_neighbor_ranks(
const std::vector<int>& neighbors)
175 const std::vector<int>& get_neighbor_ranks()
const
214 template<
typename DomLvl_>
219 typedef DomLvl_ LevelType;
222 std::shared_ptr<LevelType> _level;
223 std::shared_ptr<LevelType> _level_child;
224 std::shared_ptr<LevelType> _level_parent;
225 std::shared_ptr<LevelType> _level_base;
226 std::shared_ptr<LayerType> _layer;
227 std::shared_ptr<LayerType> _layer_child;
228 std::shared_ptr<LayerType> _layer_parent;
232 explicit VirtualLevel(std::shared_ptr<LevelType> level_, std::shared_ptr<LayerType> layer_) :
245 std::shared_ptr<LevelType> level_child_,
246 std::shared_ptr<LayerType> layer_child_,
247 std::shared_ptr<LevelType> level_parent_,
248 std::shared_ptr<LayerType> layer_parent_) :
249 _level(level_parent_ ? level_parent_ : level_child_),
250 _level_child(level_child_),
251 _level_parent(level_parent_),
253 _layer(layer_parent_ ? layer_parent_ : layer_child_),
254 _layer_child(layer_child_),
255 _layer_parent(layer_parent_),
260 XASSERT(_layer_child->is_child());
265 XASSERT(_layer_child->is_parent());
266 XASSERT(_level_child->get_level_index() == _level_parent->get_level_index());
280 bool is_child()
const
282 return bool(_level_child);
285 bool is_parent()
const
287 return bool(_level_parent);
290 bool is_ghost()
const
292 return is_child() && !is_parent();
295 bool has_base()
const
300 void set_base(std::shared_ptr<LevelType> level_base_)
302 _level_base = level_base_;
311 LevelType& operator*()
316 const LevelType& operator*()
const
321 LevelType* operator->()
326 const LevelType* operator->()
const
336 const LevelType& level()
const
354 return *_level_child;
357 const LevelType& level_c()
const
360 return *_level_child;
366 return *_layer_child;
372 return *_layer_child;
378 return *_level_parent;
381 const LevelType& level_p()
const
384 return *_level_parent;
390 return *_layer_parent;
396 return *_layer_parent;
405 const LevelType& level_b()
const
423 template<
typename Lambda_>
436 std::size_t bytes()
const
440 b += _level_base->bytes();
442 return b + this->_level_child->bytes() + this->_layer_parent->bytes();
444 return b + this->_level_child->bytes();
446 return b + this->_level->bytes();
455 template<
typename DomLvl_>
459 typedef DomLvl_ LevelType;
463 typedef typename LevelType::ShapeType ShapeType;
464 typedef typename LevelType::MeshType MeshType;
465 typedef typename LevelType::MeshNodeType MeshNodeType;
471 std::deque<std::shared_ptr<LayerType>> _layers;
472 std::deque<std::shared_ptr<LevelType>> _base_levels;
473 std::deque<std::deque<std::shared_ptr<LevelType>>> _layer_levels;
474 std::deque<VirtLevelType> _virt_levels;
475 std::size_t _num_global_layers;
476 std::size_t _virt_size;
484 _num_global_layers(0u),
496 return "DomainControl<"+MeshType::name()+
">";
499 virtual void print()
const
509 const auto& my_mesh = front()->get_mesh();
510 Index ncells(my_mesh.get_num_entities(MeshType::shape_dim));
513 msg =
String(
"Cells on level "+
stringify(max_level_index()).pad_back(pad_width,
'.'))
518 const Dist::Comm& comm()
const
523 std::size_t bytes()
const
525 std::size_t s = _atlas.
bytes();
526 for(
const auto& lyr : _layers)
528 for(
const auto& lyr_lvl : _layer_levels)
529 for(
const auto& lvl : lyr_lvl)
534 std::size_t num_local_layers()
const
536 return _layers.size();
539 std::size_t num_global_layers()
const
541 return _num_global_layers;
544 void push_layer(std::shared_ptr<LayerType> layer)
549 XASSERT((_layers.back()->get_layer_index()+1) == layer->get_layer_index());
551 _layers.push_back(layer);
552 _layer_levels.push_back(std::deque<std::shared_ptr<LevelType>>());
555 LayerType& front_layer()
557 return *_layers.front();
560 const LayerType& front_layer()
const
562 return *_layers.front();
565 LayerType& back_layer()
567 return *_layers.back();
570 const LayerType& back_layer()
const
572 return *_layers.back();
575 int min_level_index()
const
577 return _virt_levels.back()->get_level_index();
580 int max_level_index()
const
582 return _virt_levels.front()->get_level_index();
585 int med_level_index()
const
587 return (_layer_levels.size() < std::size_t(2) ? -1 : _layer_levels.front().back()->get_level_index());
590 void push_level_front(
int layer_index, std::shared_ptr<LevelType> level)
592 _layer_levels.at(std::size_t(layer_index)).push_front(level);
595 void push_level_back(
int layer_index, std::shared_ptr<LevelType> level)
597 _layer_levels.at(std::size_t(layer_index)).push_back(level);
603 return _virt_size < _virt_levels.size();
610 std::size_t size_virtual()
const
615 std::size_t size_physical()
const
617 if(_virt_levels.empty())
618 return std::size_t(0);
619 else if(_virt_levels.back().is_ghost())
620 return _virt_levels.size() - std::size_t(1);
622 return _virt_levels.size();
625 VirtLevelType& at(std::size_t i)
627 return _virt_levels.at(i);
630 const VirtLevelType& at(std::size_t i)
const
632 return _virt_levels.at(i);
635 VirtLevelType& front()
637 return _virt_levels.front();
640 const VirtLevelType& front()
const
642 return _virt_levels.front();
645 VirtLevelType& back()
647 return _virt_levels.back();
650 const VirtLevelType& back()
const
652 return _virt_levels.back();
655 AtlasType& get_atlas()
660 const AtlasType& get_atlas()
const
680 this->_keep_base_levels =
true;
683 void compile_virtual_levels()
686 std::size_t my_num_layers = _layers.size();
692 _virt_levels.clear();
695 _virt_levels.push_back(VirtLevelType(_layer_levels.front().front(), _layers.front()));
700 if(!_base_levels.empty())
701 _virt_levels.front().set_base(_base_levels.front());
703 _virt_levels.front().set_base();
707 for(std::size_t ilay(0); ilay < _layers.size(); ++ilay)
710 std::shared_ptr<LayerType>& layer = _layers.at(ilay);
713 std::deque<std::shared_ptr<LevelType>>& laylevs = _layer_levels.at(ilay);
716 if(laylevs.size() <= std::size_t(1))
720 for(std::size_t ilev(1); (ilev+1) < laylevs.size(); ++ilev)
722 _virt_levels.push_back(VirtLevelType(laylevs.at(ilev), layer));
727 if(!_base_levels.empty())
728 _virt_levels.back().set_base(_base_levels.at(ilev));
730 _virt_levels.back().set_base();
735 if((ilay+1) < _layers.size())
738 _virt_levels.push_back(VirtLevelType(laylevs.back(), layer, _layer_levels.at(ilay+1).front(), _layers.at(ilay+1)));
740 else if(layer->is_child())
743 _virt_levels.push_back(VirtLevelType(laylevs.back(), layer,
nullptr,
nullptr));
748 _virt_levels.push_back(VirtLevelType(laylevs.back(), layer));
754 if(!_base_levels.empty())
756 XASSERT(laylevs.size() == _base_levels.size());
757 _virt_levels.back().set_base(_base_levels.back());
760 _virt_levels.back().set_base();
765 std::size_t my_virt_size = _virt_levels.size();
771 void add_trafo_mesh_part_charts()
773 for(
auto& bl : _base_levels)
774 bl->add_trafo_mesh_part_charts();
775 for(
auto& ll : _layer_levels)
777 l->add_trafo_mesh_part_charts();
789 String dump_layers()
const
792 msg +=
"(" +
stringify(_layers.size()) +
"):";
793 for(std::size_t i(0); i < _layers.size(); ++i)
795 const auto& lyr = *_layers.at(i);
796 std::size_t np = std::size_t(
Math::ilog10(lyr.comm().size()));
797 if(i > std::size_t(0))
802 std::size_t ns = std::size_t(
Math::ilog10(lyr.comm().size()));
805 msg += lyr.is_parent() ?
"*}" :
" }";
811 String dump_layer_levels()
const
814 for(
auto it = _layer_levels.begin(); it != _layer_levels.end(); ++it)
816 if(it != _layer_levels.begin())
818 for(
auto jt = it->begin(); jt != it->end(); ++jt)
819 msg +=
" " +
stringify((*jt)->get_level_index());
824 String dump_virt_levels()
const
827 for(
auto it = _virt_levels.begin(); it != _virt_levels.end(); ++it)
829 std::size_t np = std::size_t(
Math::ilog10((*it).layer().comm().size()));
831 np = std::size_t(
Math::ilog10((*it).layer_c().comm().size()));
832 msg +=
" " +
stringify((*it)->get_level_index());
836 msg +=
" { " +
stringify((*it).layer_c().get_parent_rank());
837 if((*it).is_parent())
840 msg += String(np+1,
' ') +
"}";
#define XASSERT(expr)
Assertion macro definition.
Domain control base-class template.
void keep_base_levels()
Instructs the domain controller to keep the base-mesh levels after partitioning.
bool _keep_base_levels
keep base-mesh levels on root process?
Dist::Comm _sibling_comm
the sibling communicator
int _parent_rank
the rank of the parent in the sibling comm
int _layer_index
the layer index
std::vector< int > _neighbor_ranks
the ranks of the neighbor processes in this layer
Dist::Comm _comm
the communicator for this layer
Virtual Domain Level class template.
void apply_lambda(Lambda_ &&lambda)
Applies a lambda expression onto every level object in this virtual level.
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.
int rank() const
Returns the rank of this process in this communicator.
void print(std::ostream &os, const String &msg, int root=0) const
Prints a message line to an output stream.
Mesh Atlas class template.
std::size_t bytes() const
String class implementation.
String pad_back(size_type len, char c=' ') const
Pads the back of the string up to a desired length.
String pad_front(size_type len, char c=' ') const
Pads the front of the string up to a desired length.
VirtualLevelLambda
Virtual Level Lambda type enumeration.
@ child
indicates that the level is a child level
@ base
indicates that the level is a base level
@ parent
indicates that the level is a parent level
@ normal
indicates that the level is a normal level
const Operation op_max(MPI_MAX)
Operation wrapper for MPI_MAX.
const Operation op_sum(MPI_SUM)
Operation wrapper for MPI_SUM.
T_ ilog10(T_ x)
Computes the integral base-10 logarithm of an integer, i.e. its number of non-zero decimal digits.
String stringify(const T_ &item)
Converts an item into a String.
std::uint64_t Index
Index data type.