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.