DOFSerializer.cc 4.21 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1 2 3 4 5 6 7 8 9
#include "DOFSerializer.h"

#include <algorithm>

#include "DOFVector.h"
#include "Global.h"
#include "Traverse.h"

namespace AMDiS
Praetorius, Simon's avatar
Praetorius, Simon committed
10 11 12
{

// store values of DOFVector on all macro elements to internal container
Praetorius, Simon's avatar
Praetorius, Simon committed
13 14 15 16
void DOFSerializer::gather(DOFVector<double> const* vec, std::vector<double>& values)
{
  std::fill(visited_.begin(), visited_.end(), false);
  values.clear();
Praetorius, Simon's avatar
Praetorius, Simon committed
17 18
  values.reserve(numValues_);

Praetorius, Simon's avatar
Praetorius, Simon committed
19 20
  for (auto* macroEl : mesh_->getMacroElements())
    gather(macroEl->getIndex(), vec, values, false);
Praetorius, Simon's avatar
Praetorius, Simon committed
21 22

  numValues_ = values.size();
Praetorius, Simon's avatar
Praetorius, Simon committed
23 24 25
}


Praetorius, Simon's avatar
Praetorius, Simon committed
26
// store values of DOFVector on macro element `macroIndex` to internal container
Praetorius, Simon's avatar
Praetorius, Simon committed
27 28
void DOFSerializer::gather(int macroIndex, DOFVector<double> const* vec, std::vector<double>& values, bool reset)
{
Praetorius, Simon's avatar
Praetorius, Simon committed
29 30 31
  FUNCNAME("DOFSerializer::gather()");
  TEST_EXIT(mesh_ == vec->getFeSpace()->getMesh())("Incompatible meshes!\n");

Praetorius, Simon's avatar
Praetorius, Simon committed
32 33 34 35
  if (reset) {
    std::fill(visited_.begin(), visited_.end(), false);
    values.clear();
  }
Praetorius, Simon's avatar
Praetorius, Simon committed
36

Praetorius, Simon's avatar
Praetorius, Simon committed
37 38 39 40
  TraverseStack stack;
  ElInfo *elInfo = stack.traverseFirstOneMacro(mesh_, macroIndex, -1, Mesh::CALL_EVERY_EL_PREORDER);
  while (elInfo) {
    Element *el = elInfo->getElement();
Praetorius, Simon's avatar
Praetorius, Simon committed
41

Praetorius, Simon's avatar
Praetorius, Simon committed
42 43 44 45 46 47 48 49
    if (el->isLeaf()) {
      gather(VERTEX, elInfo, vec, values);
      if (mesh_->getDim() > 1)
        gather(EDGE, elInfo, vec, values);
      if (mesh_->getDim() == 3)
        gather(FACE, elInfo, vec, values);
      gather(CENTER, elInfo, vec, values);
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
50

Praetorius, Simon's avatar
Praetorius, Simon committed
51 52 53 54 55
    elInfo = stack.traverseNext(elInfo);
  }
}


Praetorius, Simon's avatar
Praetorius, Simon committed
56
void DOFSerializer::gather(GeoIndex geo, ElInfo* elInfo, DOFVector<double> const* vec, std::vector<double>& values)
Praetorius, Simon's avatar
Praetorius, Simon committed
57
{
Praetorius, Simon's avatar
Praetorius, Simon committed
58
  FUNCNAME_DBG("DOFSerializer::gather()");
Praetorius, Simon's avatar
Praetorius, Simon committed
59 60
  int nd;
  if ((nd = admin_->getNumberOfDofs(geo)))  {
61
    int entities = mesh_->getGeo(geo);
Praetorius, Simon's avatar
Praetorius, Simon committed
62 63
    int nd0 = admin_->getNumberOfPreDofs(geo);
    int n0 = mesh_->getNode(geo);
64
    for (int n = 0; n < entities; n++) {
Praetorius, Simon's avatar
Praetorius, Simon committed
65 66
      for(int d = 0; d < nd; d++) {
        DegreeOfFreedom globalDof = elInfo->getElement()->getDof(n0 + n, nd0 + d);
Praetorius, Simon's avatar
Praetorius, Simon committed
67
        TEST_EXIT_DBG(globalDof < visited_.size())("visited container not large enough!\n");
Praetorius, Simon's avatar
Praetorius, Simon committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
        if (!visited_[globalDof]) {
          visited_[globalDof] = true;
          values.push_back((*vec)[globalDof]);
        }
      }
    }
  }
}


// assign stored values to DOFVector, for all macro elements
void DOFSerializer::scatter(std::vector<double> const& values, DOFVector<double>* vec) const
{
  std::fill(visited_.begin(), visited_.end(), false);
  counter_ = 0u;
Praetorius, Simon's avatar
Praetorius, Simon committed
83

Praetorius, Simon's avatar
Praetorius, Simon committed
84 85 86 87 88 89 90
  for (auto* macroEl : mesh_->getMacroElements())
    scatter(macroEl->getIndex(), values, vec, false);
}


// assign stored values to DOFVector, on macroElement with index `macroIndex`
void DOFSerializer::scatter(int macroIndex, std::vector<double> const& values, DOFVector<double>* vec, bool reset) const
Praetorius, Simon's avatar
Praetorius, Simon committed
91 92 93 94
{
  FUNCNAME("DOFSerializer::scatter()");
  TEST_EXIT(mesh_ == vec->getFeSpace()->getMesh())("Incompatible meshes!\n");

Praetorius, Simon's avatar
Praetorius, Simon committed
95 96 97 98
  if (reset) {
    std::fill(visited_.begin(), visited_.end(), false);
    counter_ = 0u;
  }
Praetorius, Simon's avatar
Praetorius, Simon committed
99

Praetorius, Simon's avatar
Praetorius, Simon committed
100 101 102 103
  TraverseStack stack;
  ElInfo *elInfo = stack.traverseFirstOneMacro(mesh_, macroIndex, -1, Mesh::CALL_EVERY_EL_PREORDER);
  while (elInfo) {
    Element *el = elInfo->getElement();
Praetorius, Simon's avatar
Praetorius, Simon committed
104

Praetorius, Simon's avatar
Praetorius, Simon committed
105 106 107 108 109 110 111 112
    if (el->isLeaf()) {
      scatter(VERTEX, elInfo, values, vec);
      if (mesh_->getDim() > 1)
        scatter(EDGE, elInfo, values, vec);
      if (mesh_->getDim() == 3)
        scatter(FACE, elInfo, values, vec);
      scatter(CENTER, elInfo, values, vec);
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
113

Praetorius, Simon's avatar
Praetorius, Simon committed
114 115 116 117 118 119 120
    elInfo = stack.traverseNext(elInfo);
  }
}


void DOFSerializer::scatter(GeoIndex geo, ElInfo* elInfo, std::vector<double> const& values, DOFVector<double>* vec) const
{
Praetorius, Simon's avatar
Praetorius, Simon committed
121
  FUNCNAME("DOFSerializer::scatter()");
Praetorius, Simon's avatar
Praetorius, Simon committed
122 123
  int nd;
  if ((nd = admin_->getNumberOfDofs(geo)))  {
124
    int entities = mesh_->getGeo(geo);
Praetorius, Simon's avatar
Praetorius, Simon committed
125 126
    int nd0 = admin_->getNumberOfPreDofs(geo);
    int n0 = mesh_->getNode(geo);
127
    for (int n = 0; n < entities; n++) {
Praetorius, Simon's avatar
Praetorius, Simon committed
128 129
      for(int d = 0; d < nd; d++) {
        DegreeOfFreedom globalDof = elInfo->getElement()->getDof(n0 + n, nd0 + d);
Praetorius, Simon's avatar
Praetorius, Simon committed
130
        TEST_EXIT_DBG(globalDof < visited_.size())("visited container not large enough!\n");
Praetorius, Simon's avatar
Praetorius, Simon committed
131 132
        if (!visited_[globalDof]) {
          visited_[globalDof] = true;
133
          TEST_EXIT(counter_ < values.size())("Not enough values in value-container!\n");
Praetorius, Simon's avatar
Praetorius, Simon committed
134 135 136 137 138 139 140 141 142
          (*vec)[globalDof] = values[counter_++];
        }
      }
    }
  }
}


} // end namespace AMDiS