communication.hh 2.44 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1 2 3 4 5 6 7 8
#pragma once

#include <set>

#include <dune/grid/common/gridenums.hh>
#include <dune/istl/owneroverlapcopy.hh>

#include <dune/amg_error/GlobalBasisIdSet.hpp>
Praetorius, Simon's avatar
Praetorius, Simon committed
9
#include <dune/amg_error/UniqueBorderPartition.hpp>
Praetorius, Simon's avatar
Praetorius, Simon committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23

template <class Basis, class PIS>
void buildParallelIndexSet(Basis const& basis, PIS& pis)
{
  using GridView = typename Basis::GridView;
  using Grid = typename GridView::Grid;

  using Attribute = typename Dune::OwnerOverlapCopyAttributeSet::AttributeSet;
  using PType = Dune::PartitionType;
  using LI = typename PIS::LocalIndex;

  auto const& gv = basis.gridView();

  // make disjoint partition of border entities
Praetorius, Simon's avatar
Praetorius, Simon committed
24 25 26
  using DataHandle = AMDiS::UniqueBorderPartition<Grid>;
  DataHandle borderEntities(gv.comm().rank(), gv.grid().globalIdSet());
  gv.communicate(borderEntities,
Praetorius, Simon's avatar
Praetorius, Simon committed
27 28 29 30 31 32
    Dune::InterfaceType::InteriorBorder_InteriorBorder_Interface,
    Dune::CommunicationDirection::ForwardCommunication);

  auto lv = basis.localView();
  AMDiS::GlobalBasisIdSet<Basis> dofIdSet(basis);

33
  std::vector<bool> visited(basis.dimension(), false);
Praetorius, Simon's avatar
Praetorius, Simon committed
34 35 36 37 38 39 40
  pis.beginResize();
  for (auto const& e : elements(gv))
  {
    lv.bind(e);
    dofIdSet.bind(e);
    for (std::size_t i = 0; i < dofIdSet.size(); ++i)
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
41
      auto localIndex = lv.index(i);
42 43 44 45 46 47
      if (!visited[localIndex]) {
        auto globalId = dofIdSet.id(i);
        PType attribute = dofIdSet.partitionType(i);
        switch (attribute)
        {
        case PType::InteriorEntity:
Praetorius, Simon's avatar
Praetorius, Simon committed
48
          pis.add(globalId, LI(localIndex, Attribute::owner, true));
49 50 51 52 53 54 55 56
          break;
        case PType::BorderEntity:
          if (borderEntities.contains(dofIdSet.entityId(i)))
            pis.add(globalId, LI(localIndex, Attribute::owner, true));
          else
            pis.add(globalId, LI(localIndex, Attribute::overlap, true));
          break;
        case PType::OverlapEntity:
Praetorius, Simon's avatar
Praetorius, Simon committed
57
          pis.add(globalId, LI(localIndex, Attribute::overlap, true));
58 59 60 61 62 63 64 65
          break;
        case PType::FrontEntity:
        case PType::GhostEntity:
          pis.add(globalId, LI(localIndex, Attribute::copy, true));
          break;
        }

        visited[localIndex] = true;
Praetorius, Simon's avatar
Praetorius, Simon committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
      }
    }
    dofIdSet.unbind();
    lv.unbind();
  }
  pis.endResize();
}


template <class Basis, class Comm>
void buildCommunication(Basis const& basis, Comm& comm)
{
  auto& pis = comm.indexSet();
  buildParallelIndexSet(basis, pis);

  auto& ris = comm.remoteIndices();
  ris.setIndexSets(pis, pis, comm.communicator());
  ris.template rebuild<true>();
}