Commit 89cfd659 authored by Thomas Witkowski's avatar Thomas Witkowski

First work on FETI-DP method.

parent 35720ba3
......@@ -55,8 +55,9 @@ namespace AMDiS {
using namespace boost::filesystem;
using namespace std;
const Flag MeshDistributor::BOUNDARY_SUBOBJ_SORTED = 0X01L;
const Flag MeshDistributor::BOUNDARY_EDGE_SCHUR = 0X02L;
const Flag MeshDistributor::BOUNDARY_SUBOBJ_SORTED = 0X01L;
const Flag MeshDistributor::BOUNDARY_FILL_INFO_SEND_DOFS = 0X02L;
const Flag MeshDistributor::BOUNDARY_FILL_INFO_RECV_DOFS = 0X04L;
inline bool cmpDofsByValue(const DegreeOfFreedom* dof1, const DegreeOfFreedom* dof2)
{
......@@ -648,6 +649,29 @@ namespace AMDiS {
}
void MeshDistributor::getAllBoundaryDofs(DofContainer& dofs)
{
FUNCNAME("MeshDistributor::getAllBoundaryDofs()");
DofContainerSet dofSet;
for (RankToDofContainer::iterator sendIt = sendDofs.begin();
sendIt != sendDofs.end(); ++sendIt)
for (DofContainer::iterator dofIt = sendIt->second.begin();
dofIt != sendIt->second.end(); ++dofIt)
dofSet.insert(*dofIt);
for (RankToDofContainer::iterator recvIt = recvDofs.begin();
recvIt != recvDofs.end(); ++recvIt)
for (DofContainer::iterator dofIt = recvIt->second.begin();
dofIt != recvIt->second.end(); ++dofIt)
dofSet.insert(*dofIt);
dofs.clear();
dofs.insert(dofs.begin(), dofSet.begin(), dofSet.end());
}
void MeshDistributor::setRankDofs(ProblemStatSeq *probStat)
{
int nComponents = probStat->getNumComponents();
......@@ -657,7 +681,8 @@ namespace AMDiS {
probStat->getSystemMatrix(i, j)->setRankDofs(isRankDof);
TEST_EXIT_DBG(probStat->getRhs()->getDOFVector(i))("No RHS vector!\n");
TEST_EXIT_DBG(probStat->getSolution()->getDOFVector(i))("No solution vector!\n");
TEST_EXIT_DBG(probStat->getSolution()->getDOFVector(i))
("No solution vector!\n");
probStat->getRhs()->getDOFVector(i)->setRankDofs(isRankDof);
probStat->getSolution()->getDOFVector(i)->setRankDofs(isRankDof);
......@@ -1674,16 +1699,31 @@ namespace AMDiS {
DofContainer& tmp = sendDofs[it.getRank()];
tmp.insert(tmp.end(), dofs.begin(), dofs.end());
dofSet.insert(dofs.begin(), dofs.end());
if (createBoundaryDofFlag.isSet(BOUNDARY_FILL_INFO_SEND_DOFS))
dofSet.insert(dofs.begin(), dofs.end());
}
}
}
for (int geo = FACE; geo >= VERTEX; geo--)
for (InteriorBoundary::iterator it(otherIntBoundary); !it.end(); ++it)
if (it->rankObj.subObj == geo)
it->rankObj.el->getAllDofs(feSpace, it->rankObj,
recvDofs[it.getRank()]);
for (int geo = FACE; geo >= VERTEX; geo--) {
std::set<const DegreeOfFreedom*> &dofSet =
boundaryDofInfo.geoDofs[static_cast<GeoIndex>(geo)];
dofSet.clear();
for (InteriorBoundary::iterator it(otherIntBoundary); !it.end(); ++it) {
if (it->rankObj.subObj == geo) {
dofs.clear();
it->rankObj.el->getAllDofs(feSpace, it->rankObj, dofs);
DofContainer& tmp = recvDofs[it.getRank()];
tmp.insert(tmp.end(), dofs.begin(), dofs.end());
if (createBoundaryDofFlag.isSet(BOUNDARY_FILL_INFO_RECV_DOFS))
dofSet.insert(dofs.begin(), dofs.end());
}
}
}
} else {
for (InteriorBoundary::iterator it(myIntBoundary); !it.end(); ++it)
it->rankObj.el->getAllDofs(feSpace, it->rankObj,
......
......@@ -24,11 +24,8 @@
#define AMDIS_MESHDISTRIBUTOR_H
#include <map>
#include <set>
#include <vector>
#include <mpi.h>
#include "parallel/ParallelTypes.h"
#include "parallel/MeshPartitioner.h"
#include "parallel/InteriorBoundary.h"
#include "AMDiS_fwd.h"
......@@ -54,36 +51,6 @@ namespace AMDiS {
class MeshDistributor
{
protected:
/// Defines a mapping type from DOFs to rank numbers.
typedef map<const DegreeOfFreedom*, int> DofToRank;
/// Defines a mapping type from DOFs to a set of rank numbers.
typedef map<const DegreeOfFreedom*, std::set<int> > DofToPartitions;
/// Defines a mapping type from rank numbers to sets of DOFs.
typedef map<int, DofContainer> RankToDofContainer;
/// Defines a mapping type from DOF indices to DOF indices.
typedef map<DegreeOfFreedom, DegreeOfFreedom> DofMapping;
/// Defines a mapping type from DOFs to boolean values.
typedef map<const DegreeOfFreedom*, bool> DofToBool;
/// Defines a mapping type from DOF indices to boolean values.
typedef map<DegreeOfFreedom, bool> DofIndexToBool;
/// Forward type (it maps rank numbers to the interior boundary objects).
typedef InteriorBoundary::RankToBoundMap RankToBoundMap;
typedef map<const DegreeOfFreedom*, DegreeOfFreedom> DofIndexMap;
/// Mapps a boundar type, i.e., a boundary identifier index, to a periodic
/// DOF mapping.
typedef map<BoundaryType, DofMapping> PeriodicDofMap;
typedef vector<MeshStructure> MeshCodeVec;
public:
MeshDistributor();
......@@ -310,6 +277,8 @@ namespace AMDiS {
return boundaryDofInfo;
}
void getAllBoundaryDofs(DofContainer& dofs);
protected:
/** \brief
* Determines the interior boundaries, i.e. boundaries between ranks, and stores
......@@ -622,10 +591,20 @@ namespace AMDiS {
BoundaryDofInfo boundaryDofInfo;
public:
///
/// The boundary DOFs are sorted by subobject entities, i.e., first all
/// face DOFs, edge DOFs and to the last vertex DOFs will be set to
/// communication structure vectors, \ref sendDofs and \ref recvDofs.
static const Flag BOUNDARY_SUBOBJ_SORTED;
static const Flag BOUNDARY_EDGE_SCHUR;
/// When boundary DOFs are created, \ref boundaryDofInfo is filled for
/// all DOFs that this rank will send to other ranks (thus, rank
/// owned DOFs.
static const Flag BOUNDARY_FILL_INFO_SEND_DOFS;
/// When boundary DOFs are created, \ref boundaryDofInfo is filled for
/// all DOFs that this rank will receive from other ranks (thus, DOFs
/// that are owned by another rank).
static const Flag BOUNDARY_FILL_INFO_RECV_DOFS;
friend class ParallelDebug;
};
......
......@@ -22,13 +22,14 @@
namespace AMDiS {
using namespace std;
void ParallelDebug::testInteriorBoundary(MeshDistributor &pdb)
{
FUNCNAME("ParallelDebug::testInteriorBoundary()");
typedef MeshDistributor::RankToBoundMap RankToBoundMap;
std::vector<int*> sendBuffers, recvBuffers;
vector<int*> sendBuffers, recvBuffers;
MPI::Request request[pdb.myIntBoundary.boundary.size() +
pdb.otherIntBoundary.boundary.size() +
......@@ -163,8 +164,6 @@ namespace AMDiS {
// === 2. check: All periodic DOFs must be symmetric, i.e., if A is mapped ===
// === to B, then B must be mapped to A. ===
typedef MeshDistributor::PeriodicDofMap PeriodicDofMap;
StdMpi<PeriodicDofMap> stdMpi(pdb.mpiComm, true);
if (pdb.mpiRank == 0) {
......@@ -182,7 +181,7 @@ namespace AMDiS {
if (pdb.mpiRank == 0) {
// Stores to each rank the periodic DOF mappings of this rank.
std::map<int, PeriodicDofMap> rankToMaps;
map<int, PeriodicDofMap> rankToMaps;
PeriodicDofMap dofMap = pdb.periodicDof;
rankToMaps[0] = dofMap;
......@@ -192,7 +191,7 @@ namespace AMDiS {
for (PeriodicDofMap::iterator it = otherMap.begin();
it != otherMap.end(); ++it) {
for (MeshDistributor::DofMapping::iterator dofIt = it->second.begin();
for (DofMapping::iterator dofIt = it->second.begin();
dofIt != it->second.end(); ++dofIt) {
if (dofMap.count(it->first) == 1 &&
dofMap[it->first].count(dofIt->first) == 1) {
......@@ -211,7 +210,7 @@ namespace AMDiS {
for (PeriodicDofMap::iterator it = dofMap.begin();
it != dofMap.end(); ++it) {
for (MeshDistributor::DofMapping::iterator dofIt = it->second.begin();
for (DofMapping::iterator dofIt = it->second.begin();
dofIt != it->second.end(); ++dofIt) {
if (it->second[dofIt->second] != dofIt->first) {
MSG("[DBG] For boundary type %d: DOF %d -> %d, but %d -> %d!\n",
......@@ -247,7 +246,7 @@ namespace AMDiS {
// === periodic boundaries only on rectangulars and boxes. ===
RankToCoords sendCoords;
std::map<int, std::vector<BoundaryType> > rankToDofType;
map<int, vector<BoundaryType> > rankToDofType;
for (InteriorBoundary::RankToBoundMap::iterator it = pdb.periodicBoundary.boundary.begin();
it != pdb.periodicBoundary.boundary.end(); ++it) {
......@@ -330,7 +329,7 @@ namespace AMDiS {
}
/// Defines a mapping type from rank numbers to sets of DOFs.
typedef std::map<int, DofContainer> RankToDofContainer;
typedef map<int, DofContainer> RankToDofContainer;
// Maps to each neighbour rank an array of WorldVectors. This array contains the
// coordinates of all DOFs this rank shares on the interior boundary with the
......@@ -358,9 +357,9 @@ namespace AMDiS {
dofIt != it->second.end(); ++dofIt)
recvCoords[it->first].push_back(coords[**dofIt]);
std::vector<int> sendSize(pdb.mpiSize, 0);
std::vector<int> recvSize(pdb.mpiSize, 0);
std::vector<int> recvSizeBuffer(pdb.mpiSize, 0);
vector<int> sendSize(pdb.mpiSize, 0);
vector<int> recvSize(pdb.mpiSize, 0);
vector<int> recvSizeBuffer(pdb.mpiSize, 0);
MPI::Request request[(pdb.mpiSize - 1) * 2];
int requestCounter = 0;
......@@ -426,7 +425,7 @@ namespace AMDiS {
// === Print error message if the coordinates are not the same. ===
if (printCoords) {
MSG("[DBG] i = %d\n", i);
std::stringstream oss;
stringstream oss;
oss.precision(5);
oss << "[DBG] Rank " << pdb.mpiRank << " from rank " << it->first
<< " expect coords (";
......@@ -465,7 +464,7 @@ namespace AMDiS {
DOFVector<WorldVector<double> > coords(pdb.feSpace, "tmp");
pdb.mesh->getDofIndexCoords(pdb.feSpace, coords);
typedef std::map<WorldVector<double>, int> CoordsIndexMap;
typedef map<WorldVector<double>, int> CoordsIndexMap;
CoordsIndexMap coordsToIndex;
DOFIterator<WorldVector<double> > it(&coords, USED_DOFS);
......@@ -491,7 +490,7 @@ namespace AMDiS {
coordsIt != otherCoords.end(); ++coordsIt) {
if (coordsToIndex.count(coordsIt->first) == 1 &&
coordsToIndex[coordsIt->first] != coordsIt->second) {
std::stringstream oss;
stringstream oss;
oss.precision(5);
oss << "DOF at coords ";
for (int i = 0; i < Global::getGeo(WORLD); i++)
......@@ -517,8 +516,8 @@ namespace AMDiS {
FUNCNAME("ParallelDebug::testAllElements()");
std::set<int> macroElements;
int minElementIndex = std::numeric_limits<int>::max();
int maxElementIndex = std::numeric_limits<int>::min();
int minElementIndex = numeric_limits<int>::max();
int maxElementIndex = numeric_limits<int>::min();
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(pdb.mesh, 0, Mesh::CALL_EL_LEVEL);
......@@ -559,7 +558,7 @@ namespace AMDiS {
{
FUNCNAME("ParallelDebug::testDofContainerCommunication()");
std::map<int, int> sendNumber;
map<int, int> sendNumber;
for (RankToDofContainer::iterator it = sendDofs.begin(); it != sendDofs.end(); ++it)
sendNumber[it->first] = it->second.size();
......@@ -570,7 +569,7 @@ namespace AMDiS {
stdMpi.startCommunication();
int foundError = 0;
for (std::map<int, int>::iterator it = stdMpi.getRecvData().begin();
for (map<int, int>::iterator it = stdMpi.getRecvData().begin();
it != stdMpi.getRecvData().end(); ++it) {
if (it->second != static_cast<int>(recvDofs[it->first].size())) {
ERROR("Rank expectes %d DOFs to receive from rank %d, but %d DOFs are received!\n",
......@@ -588,7 +587,7 @@ namespace AMDiS {
{
FUNCNAME("ParallelDebug::testDoubleDofs()");
std::map<WorldVector<double>, DegreeOfFreedom> cMap;
map<WorldVector<double>, DegreeOfFreedom> cMap;
int foundError = 0;
TraverseStack stack;
......@@ -619,20 +618,17 @@ namespace AMDiS {
void ParallelDebug::printMapLocalGlobal(MeshDistributor &pdb, int rank)
{
if (rank == -1 || pdb.mpiRank == rank) {
std::cout << "====== DOF MAP LOCAL -> GLOBAL ====== " << std::endl;
cout << "====== DOF MAP LOCAL -> GLOBAL ====== " << endl;
typedef std::map<DegreeOfFreedom, DegreeOfFreedom> DofMapping;
typedef std::map<int, DofContainer> RankToDofContainer;
for (DofMapping::iterator it = pdb.mapLocalGlobalDofs.begin();
it != pdb.mapLocalGlobalDofs.end(); it++) {
DegreeOfFreedom localdof = -1;
if (pdb.mapLocalDofIndex.count(it->first) > 0)
localdof = pdb.mapLocalDofIndex[it->first];
std::cout << "DOF " << it->first << " "
cout << "DOF " << it->first << " "
<< it->second << " "
<< localdof << std::endl;
<< localdof << endl;
WorldVector<double> coords;
pdb.mesh->getDofIndexCoords(it->first, pdb.feSpace, coords);
coords.print();
......@@ -642,7 +638,7 @@ namespace AMDiS {
for (DofContainer::iterator dofit = rankit->second.begin();
dofit != rankit->second.end(); ++dofit)
if (**dofit == it->first)
std::cout << "SEND DOF TO " << rankit->first << std::endl;
cout << "SEND DOF TO " << rankit->first << endl;
}
for (RankToDofContainer::iterator rankit = pdb.recvDofs.begin();
......@@ -650,10 +646,10 @@ namespace AMDiS {
for (DofContainer::iterator dofit = rankit->second.begin();
dofit != rankit->second.end(); ++dofit)
if (**dofit == it->first)
std::cout << "RECV DOF FROM " << rankit->first << std::endl;
cout << "RECV DOF FROM " << rankit->first << endl;
}
std::cout << "------" << std::endl;
cout << "------" << endl;
}
}
}
......@@ -666,19 +662,19 @@ namespace AMDiS {
ERROR_EXIT("Function must be rewritten!\n");
#if 0
typedef std::map<DegreeOfFreedom, DegreeOfFreedom> DofMapping;
typedef std::map<DegreeOfFreedom, std::set<DegreeOfFreedom> > PeriodicDofMap;
typedef map<DegreeOfFreedom, DegreeOfFreedom> DofMapping;
typedef map<DegreeOfFreedom, std::set<DegreeOfFreedom> > PeriodicDofMap;
if (rank == -1 || pdb.mpiRank == rank) {
std::cout << "====== DOF MAP PERIODIC ====== " << std::endl;
cout << "====== DOF MAP PERIODIC ====== " << endl;
for (PeriodicDofMap::iterator it = pdb.periodicDof.begin();
it != pdb.periodicDof.end(); ++it) {
std::cout << "DOF MAP " << it->first << ": ";
cout << "DOF MAP " << it->first << ": ";
for (std::set<DegreeOfFreedom>::iterator dofit = it->second.begin();
dofit != it->second.end(); ++dofit)
std::cout << *dofit << " ";
std::cout << std::endl;
cout << *dofit << " ";
cout << endl;
DegreeOfFreedom localdof = -1;
for (DofMapping::iterator dofIt = pdb.mapLocalGlobalDofs.begin();
......@@ -703,21 +699,21 @@ namespace AMDiS {
DofContainer& rankAllDofs)
{
if (rank == -1 || pdb.mpiRank == rank) {
std::cout << "====== RANK DOF INFORMATION ====== " << std::endl;
cout << "====== RANK DOF INFORMATION ====== " << endl;
std::cout << " RANK OWNED DOFS: " << std::endl;
cout << " RANK OWNED DOFS: " << endl;
for (DofContainer::iterator dofit = rankDofs.begin();
dofit != rankDofs.end(); ++dofit) {
std::cout << " " << **dofit << std::endl;
cout << " " << **dofit << endl;
WorldVector<double> coords;
pdb.mesh->getDofIndexCoords(*dofit, pdb.feSpace, coords);
coords.print();
}
std::cout << " RANK ALL DOFS: " << std::endl;
cout << " RANK ALL DOFS: " << endl;
for (DofContainer::iterator dofit = rankAllDofs.begin();
dofit != rankAllDofs.end(); ++dofit) {
std::cout << " " << **dofit << std::endl;
cout << " " << **dofit << endl;
WorldVector<double> coords;
pdb.mesh->getDofIndexCoords(*dofit, pdb.feSpace, coords);
coords.print();
......@@ -763,21 +759,21 @@ namespace AMDiS {
void ParallelDebug::writeDebugFile(MeshDistributor &pdb,
std::string prefix, std::string postfix)
string prefix, string postfix)
{
FUNCNAME("ParallelDebug::writeCoordsFile()");
std::stringstream filename;
stringstream filename;
filename << prefix << "-" << pdb.mpiRank << "." << postfix;
DOFVector<WorldVector<double> > coords(pdb.feSpace, "tmp");
pdb.mesh->getDofIndexCoords(pdb.feSpace, coords);
typedef std::map<int, std::vector<DegreeOfFreedom> > ElDofMap;
typedef map<int, vector<DegreeOfFreedom> > ElDofMap;
ElDofMap elDofMap;
TraverseStack stack;
const BasisFunction *basisFcts = pdb.feSpace->getBasisFcts();
std::vector<DegreeOfFreedom> localIndices(basisFcts->getNumber());
vector<DegreeOfFreedom> localIndices(basisFcts->getNumber());
ElInfo *elInfo = stack.traverseFirst(pdb.mesh, -1, Mesh::CALL_LEAF_EL);
while (elInfo) {
basisFcts->getLocalIndices(elInfo->getElement(),
......@@ -788,7 +784,7 @@ namespace AMDiS {
// === Write informations about all DOFs. ===
std::ofstream file;
ofstream file;
file.open(filename.str().c_str());
file << "# First line contains number of DOFs, than each line has the format\n";
file << "# Local DOF index Global DOF index Is rank DOF x-coord y-coord z-coord\n";
......@@ -839,7 +835,7 @@ namespace AMDiS {
ElementFileWriter::writeFile(vec, pdb.mesh, filename);
}
void ParallelDebug::writePartitioningFile(std::string filename,
void ParallelDebug::writePartitioningFile(string filename,
int counter,
FiniteElemSpace *feSpace)
{
......
......@@ -23,6 +23,7 @@
#ifndef AMDIS_PARALLELDEBUG_H
#define AMDIS_PARALLELDEBUG_H
#include "parallel/ParallelTypes.h"
#include "parallel/MeshDistributor.h"
namespace AMDiS {
......@@ -30,8 +31,6 @@ namespace AMDiS {
class ParallelDebug
{
protected:
typedef MeshDistributor::RankToDofContainer RankToDofContainer;
typedef std::vector<WorldVector<double> > CoordsVec;
/// Defines a mapping type from rank numbers to sets of coordinates.
......
// ============================================================================
// == ==
// == AMDiS - Adaptive multidimensional simulations ==
// == ==
// == http://www.amdis-fem.org ==
// == ==
// ============================================================================
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.
/** \file ParallelTypes.h */
#include <vector>
#include <set>
#include <map>
#include "Global.h"
#include "parallel/InteriorBoundary.h"
#ifndef AMDIS_PARALLEL_TYPES_H
#define AMDIS_PARALLEL_TYPES_H
namespace AMDiS {
using namespace std;
/// Defines a mapping type from DOFs to rank numbers.
typedef map<const DegreeOfFreedom*, int> DofToRank;
/// Defines a mapping type from DOFs to a set of rank numbers.
typedef map<const DegreeOfFreedom*, std::set<int> > DofToPartitions;
/// Defines a mapping type from rank numbers to sets of DOFs.
typedef map<int, DofContainer> RankToDofContainer;
/// Defines a mapping type from DOF indices to DOF indices.
typedef map<DegreeOfFreedom, DegreeOfFreedom> DofMapping;
/// Defines a mapping type from DOFs to boolean values.
typedef map<const DegreeOfFreedom*, bool> DofToBool;
/// Defines a mapping type from DOF indices to boolean values.
typedef map<DegreeOfFreedom, bool> DofIndexToBool;
/// Forward type (it maps rank numbers to the interior boundary objects).
typedef InteriorBoundary::RankToBoundMap RankToBoundMap;
typedef map<const DegreeOfFreedom*, DegreeOfFreedom> DofIndexMap;
/// Mapps a boundar type, i.e., a boundary identifier index, to a periodic
/// DOF mapping.
typedef map<BoundaryType, DofMapping> PeriodicDofMap;
typedef vector<MeshStructure> MeshCodeVec;
}
#endif
......@@ -20,6 +20,45 @@ namespace AMDiS {
#ifdef HAVE_PETSC_DEV
void PetscSolverFeti::updateDofData(int nComponents)
{
FUNCNAME("PetscSolverFeti::updateDofData()");
definePrimals();
}
void PetscSolverFeti::definePrimals()
{
FUNCNAME("PetscSolverFeti::definePrimals()");
TEST_EXIT_DBG(meshDistributor->getMesh()->getDim() == 2)
("Works for 2D problems only!");
primals = meshDistributor->getBoundaryDofInfo().geoDofs[VERTEX];
globalPrimalIndex.clear();
int nRankPrimals = 0;
for (DofContainerSet::iterator it = primals.begin();
it != primals.end(); ++it)
if (meshDistributor->getIsRankDof(**it)) {
globalPrimalIndex[**it] = nRankPrimals;
nRankPrimals++;
}
int nOverallPrimals = 0, rStartPrimals = 0;
mpi::getDofNumbering(meshDistributor->getMpiComm(),
nRankPrimals, rStartPrimals, nOverallPrimals);
for (DofMapping::iterator it = globalPrimalIndex.begin();
it != globalPrimalIndex.end(); ++it)
it->second += rStartPrimals;
MSG_DBG("nRankPrimals = %d nOverallPrimals = %d\n",
nRankPrimals, nOverallPrimals);
}
void PetscSolverFeti::fillPetscMatrix(Matrix<DOFMatrix*> *mat, SystemVector *vec)
{
FUNCNAME("PetscSolverFeti::fillPetscMatrix()");
......
......@@ -21,6 +21,7 @@
/** \file PetscSolverFeti.h */
#include "parallel/PetscSolver.h"
#include "parallel/ParallelTypes.h"
#ifndef AMDIS_PETSC_SOLVER_FETI_H
#define AMDIS_PETSC_SOLVER_FETI_H
......@@ -41,6 +42,23 @@ namespace AMDiS {
void fillPetscMatrix(Matrix<DOFMatrix*> *mat, SystemVector *vec);
void solvePetscMatrix(SystemVector &vec, AdaptInfo *adaptInfo);
Flag getBoundaryDofRequirement()
{
return
MeshDistributor::BOUNDARY_SUBOBJ_SORTED |
MeshDistributor::BOUNDARY_FILL_INFO_SEND_DOFS |
MeshDistributor::BOUNDARY_FILL_INFO_RECV_DOFS;
}
protected:
void updateDofData(int nComponents);
void definePrimals();
protected:
DofContainerSet primals;
DofMapping globalPrimalIndex;
};
#endif
......
......@@ -44,7 +44,9 @@ namespace AMDiS {
Flag getBoundaryDofRequirement()
{
return MeshDistributor::BOUNDARY_SUBOBJ_SORTED;
return
MeshDistributor::BOUNDARY_SUBOBJ_SORTED |
MeshDistributor::BOUNDARY_FILL_INFO_SEND_DOFS;
}
protected:
......
Markdown is supported