Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer, es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Ein Anmelden über dieses erzeugt ein neues Konto. Das alte Konto ist über den Reiter "Standard" erreichbar. Die Administratoren

Dear Gitlab user, it is now possible to log in to our service using the ZIH login/LDAP. Logging in via this will create a new account. The old account can be accessed via the "Standard" tab. The administrators

Commit 0498e5fc authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

On the way to an efficient FETI-DP implementation for mixed finite elements.

parent 7bc84046
......@@ -225,6 +225,7 @@ if(ENABLE_PARALLEL_DOMAIN)
${SOURCE_DIR}/parallel/DofComm.cc
${SOURCE_DIR}/parallel/CheckerPartitioner.cc
${SOURCE_DIR}/parallel/ElementObjectDatabase.cc
${SOURCE_DIR}/parallel/FeSpaceMapping.cc
${SOURCE_DIR}/parallel/MeshDistributor.cc
${SOURCE_DIR}/parallel/MeshManipulation.cc
${SOURCE_DIR}/parallel/MeshPartitioner.cc
......
//
// 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.
#include "parallel/FeSpaceMapping.h"
namespace AMDiS {
using namespace std;
void GlobalDofMap::clear()
{
dofMap.clear();
nRankDofs = 0;
nOverallDofs = 0;
rStartDofs = 0;
}
void GlobalDofMap::update(bool add)
{
for (DofMapping::iterator it = dofMap.begin(); it != dofMap.end(); ++it)
if (it->second == -1)
it->second = nRankDofs++;
nOverallDofs = 0;
rStartDofs = 0;
mpi::getDofNumbering(*mpiComm, nRankDofs, rStartDofs, nOverallDofs);
if (add)
addOffset(rStartDofs);
}
void GlobalDofMap::addOffset(int offset)
{
for (DofMapping::iterator it = dofMap.begin(); it != dofMap.end(); ++it)
it->second += offset;
}
}
......@@ -20,6 +20,7 @@
/** \file FeSpaceMapping.h */
#include <vector>
#include <map>
#include "parallel/MpiHelper.h"
#include "parallel/ParallelTypes.h"
......@@ -40,13 +41,7 @@ namespace AMDiS {
rStartDofs(0)
{}
void clear()
{
dofMap.clear();
nRankDofs = 0;
nOverallDofs = 0;
rStartDofs = 0;
}
void clear();
DegreeOfFreedom operator[](DegreeOfFreedom d)
{
......@@ -61,8 +56,7 @@ namespace AMDiS {
TEST_EXIT_DBG(dofMap.count(dof0) == 0)("Should not happen!\n");
dofMap[dof0] = (dof1 >= 0 ? dof1 : nRankDofs);
nRankDofs++;
dofMap[dof0] = dof1;
}
void insert(DegreeOfFreedom dof0, DegreeOfFreedom dof1)
......@@ -89,21 +83,9 @@ namespace AMDiS {
return dofMap;
}
void update(bool add = true)
{
nOverallDofs = 0;
rStartDofs = 0;
mpi::getDofNumbering(*mpiComm, nRankDofs, rStartDofs, nOverallDofs);
if (add)
addOffset(rStartDofs);
}
void update(bool add = true);
void addOffset(int offset)
{
for (DofMapping::iterator it = dofMap.begin(); it != dofMap.end(); ++it)
it->second += offset;
}
void addOffset(int offset);
private:
MPI::Intracomm* mpiComm;
......@@ -147,6 +129,39 @@ namespace AMDiS {
data.insert(make_pair(feSpace, T(mpiComm)));
}
int getRankDofs(vector<const FiniteElemSpace*> &feSpaces)
{
int result = 0;
for (unsigned int i = 0; i < feSpaces.size(); i++) {
TEST_EXIT_DBG(data.count(feSpaces[i]))("Should not happen!\n");
result += data.find(feSpaces[i])->second.nRankDofs;
}
return result;
}
int getOverallDofs(vector<const FiniteElemSpace*> &feSpaces)
{
int result = 0;
for (unsigned int i = 0; i < feSpaces.size(); i++) {
TEST_EXIT_DBG(data.count(feSpaces[i]))("Should not happen!\n");
result += data.find(feSpaces[i])->second.nOverallDofs;
}
return result;
}
int getStartDofs(vector<const FiniteElemSpace*> &feSpaces)
{
int result = 0;
for (unsigned int i = 0; i < feSpaces.size(); i++) {
TEST_EXIT_DBG(data.count(feSpaces[i]))("Should not happen!\n");
result += data.find(feSpaces[i])->second.rStartDofs;
}
return result;
}
private:
MPI::Intracomm* mpiComm;
......
......@@ -216,22 +216,21 @@ namespace AMDiS {
TEST_EXIT(meshDistributor->getFeSpace()->getBasisFcts()->getDegree() == 1)
("Works for linear basis functions only!\n");
createPrimals();
for (unsigned int i = 0; i < meshDistributor->getFeSpaces().size(); i++) {
const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(i);
createDuals();
createLagrange();
createIndexB();
createPrimals(feSpace);
createDuals(feSpace);
createLagrange(feSpace);
createIndexB(feSpace);
}
}
void PetscSolverFeti::createPrimals()
void PetscSolverFeti::createPrimals(const FiniteElemSpace *feSpace)
{
FUNCNAME("PetscSolverFeti::createPrimals()");
const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
// === Define all vertices on the interior boundaries of the macro mesh ===
// === to be primal variables. ===
......@@ -313,12 +312,10 @@ namespace AMDiS {
}
void PetscSolverFeti::createDuals()
void PetscSolverFeti::createDuals(const FiniteElemSpace *feSpace)
{
FUNCNAME("PetscSolverFeti::createDuals()");
const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
// === Create for each dual node that is owned by the rank, the set ===
// === of ranks that contain this node (denoted by W(x_j)). ===
......@@ -377,15 +374,8 @@ namespace AMDiS {
dualDofMap.addFeSpace(feSpace);
int nRankAllDofs = feSpace->getAdmin()->getUsedDofs();
nRankB = nRankAllDofs - primalDofMap[feSpace].size();
nOverallB = 0;
rStartB = 0;
mpi::getDofNumbering(meshDistributor->getMpiComm(),
nRankB, rStartB, nOverallB);
DofContainer allBoundaryDofs;
meshDistributor->getAllBoundaryDofs(feSpace, allBoundaryDofs);
int nRankInteriorDofs = nRankAllDofs - allBoundaryDofs.size();
for (DofContainer::iterator it = allBoundaryDofs.begin();
it != allBoundaryDofs.end(); ++it)
......@@ -393,24 +383,20 @@ namespace AMDiS {
dualDofMap[feSpace].insertRankDof(**it);
dualDofMap[feSpace].update(false);
dualDofMap[feSpace].addOffset(rStartB + nRankInteriorDofs);
MSG("nRankDuals = %d nOverallDuals = %d\n",
dualDofMap[feSpace].nRankDofs,
dualDofMap[feSpace].nOverallDofs);
nLocalDuals = dualDofMap[feSpace].size();
}
void PetscSolverFeti::createLagrange()
void PetscSolverFeti::createLagrange(const FiniteElemSpace *feSpace)
{
FUNCNAME("PetscSolverFeti::createLagrange()");
// === Reserve for each dual node, on the rank that owns this node, the ===
// === appropriate number of Lagrange constraints. ===
const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
lagrangeMap.addFeSpace(feSpace);
int nRankLagrange = 0;
......@@ -473,11 +459,10 @@ namespace AMDiS {
}
void PetscSolverFeti::createIndexB()
void PetscSolverFeti::createIndexB(const FiniteElemSpace *feSpace)
{
FUNCNAME("PetscSolverFeti::createIndexB()");
const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
localDofMap.addFeSpace(feSpace);
DOFAdmin* admin = feSpace->getAdmin();
......@@ -495,23 +480,28 @@ namespace AMDiS {
}
}
localDofMap[feSpace].update(false);
TEST_EXIT_DBG(nLocalInterior +
primalDofMap[feSpace].size() +
nLocalDuals ==
dualDofMap[feSpace].size() ==
static_cast<unsigned int>(admin->getUsedDofs()))
("Should not happen!\n");
// === And finally, add the global indicies of all dual nodes. ===
for (DofMapping::iterator it = dualDofMap[feSpace].getMap().begin();
it != dualDofMap[feSpace].getMap().end(); ++it)
localDofMap[feSpace].insert(it->first, it->second - rStartB);
// localDofMap[feSpace].insertRankDof(it->first);
localDofMap[feSpace].insertRankDof(it->first);
localDofMap[feSpace].update(false);
dualDofMap[feSpace].addOffset(localDofMap[feSpace].rStartDofs +
nLocalInterior);
}
void PetscSolverFeti::createMatLagrange()
void PetscSolverFeti::createMatLagrange(vector<const FiniteElemSpace*> &feSpaces)
{
FUNCNAME("PetscSolverFeti::createMatLagrange()");
......@@ -520,10 +510,11 @@ namespace AMDiS {
// === Create distributed matrix for Lagrange constraints. ===
MatCreateMPIAIJ(PETSC_COMM_WORLD,
lagrangeMap[feSpace].nRankDofs * nComponents,
nRankB * nComponents,
lagrangeMap.getRankDofs(feSpaces),
// lagrangeMap[feSpace].nRankDofs * nComponents,
localDofMap[feSpace].nRankDofs * nComponents,
lagrangeMap[feSpace].nOverallDofs * nComponents,
nOverallB * nComponents,
localDofMap[feSpace].nOverallDofs * nComponents,
2, PETSC_NULL, 2, PETSC_NULL,
&mat_lagrange);
......@@ -585,7 +576,7 @@ namespace AMDiS {
schurPrimalData.fetiSolver = this;
VecCreateMPI(PETSC_COMM_WORLD,
nRankB * nComponents, nOverallB * nComponents,
localDofMap[feSpace].nRankDofs * nComponents, localDofMap[feSpace].nOverallDofs * nComponents,
&(schurPrimalData.tmp_vec_b));
VecCreateMPI(PETSC_COMM_WORLD,
primalDofMap[feSpace].nRankDofs * nComponents, primalDofMap[feSpace].nOverallDofs * nComponents,
......@@ -612,8 +603,8 @@ namespace AMDiS {
int nRowsRankPrimal = primalDofMap[feSpace].nRankDofs * nComponents;
int nRowsOverallPrimal = primalDofMap[feSpace].nOverallDofs * nComponents;
int nRowsRankB = nRankB * nComponents;
int nRowsOverallB = nOverallB * nComponents;
int nRowsRankB = localDofMap[feSpace].nRankDofs * nComponents;
int nRowsOverallB = localDofMap[feSpace].nOverallDofs * nComponents;
Mat matBPi;
MatCreateMPIAIJ(PETSC_COMM_WORLD,
......@@ -628,8 +619,8 @@ namespace AMDiS {
map<int, vector<pair<int, double> > > mat_b_primal_cols;
for (int i = 0; i < nRankB * nComponents; i++) {
PetscInt row = rStartB * nComponents + i;
for (int i = 0; i < localDofMap[feSpace].nRankDofs * nComponents; i++) {
PetscInt row = localDofMap[feSpace].rStartDofs * nComponents + i;
MatGetRow(mat_b_primal, row, &nCols, &cols, &values);
for (int j = 0; j < nCols; j++)
......@@ -647,7 +638,7 @@ namespace AMDiS {
for (map<int, vector<pair<int, double> > >::iterator it = mat_b_primal_cols.begin();
it != mat_b_primal_cols.end(); ++it) {
Vec tmpVec;
VecCreateSeq(PETSC_COMM_SELF, nRankB * nComponents, &tmpVec);
VecCreateSeq(PETSC_COMM_SELF, localDofMap[feSpace].nRankDofs * nComponents, &tmpVec);
for (unsigned int i = 0; i < it->second.size(); i++)
VecSetValue(tmpVec,
......@@ -660,9 +651,9 @@ namespace AMDiS {
PetscScalar *tmpValues;
VecGetArray(tmpVec, &tmpValues);
for (int i = 0; i < nRankB * nComponents; i++)
for (int i = 0; i < localDofMap[feSpace].nRankDofs * nComponents; i++)
MatSetValue(matBPi,
rStartB * nComponents + i,
localDofMap[feSpace].rStartDofs * nComponents + i,
it->first,
tmpValues[i],
ADD_VALUES);
......@@ -731,7 +722,7 @@ namespace AMDiS {
fetiData.ksp_schur_primal = &ksp_schur_primal;
VecCreateMPI(PETSC_COMM_WORLD,
nRankB * nComponents, nOverallB * nComponents,
localDofMap[feSpace].nRankDofs * nComponents, localDofMap[feSpace].nOverallDofs * nComponents,
&(fetiData.tmp_vec_b));
VecCreateMPI(PETSC_COMM_WORLD,
lagrangeMap[feSpace].nRankDofs * nComponents,
......@@ -779,7 +770,7 @@ namespace AMDiS {
fetiDirichletPreconData.ksp_interior = &ksp_interior;
VecCreateMPI(PETSC_COMM_WORLD,
nRankB * nComponents, nOverallB * nComponents,
localDofMap[feSpace].nRankDofs * nComponents, localDofMap[feSpace].nOverallDofs * nComponents,
&(fetiDirichletPreconData.tmp_vec_b));
MatGetVecs(mat_duals_duals, PETSC_NULL, &(fetiDirichletPreconData.tmp_vec_duals0));
MatGetVecs(mat_duals_duals, PETSC_NULL, &(fetiDirichletPreconData.tmp_vec_duals1));
......@@ -797,7 +788,7 @@ namespace AMDiS {
fetiLumpedPreconData.mat_duals_duals = &mat_duals_duals;
VecCreateMPI(PETSC_COMM_WORLD,
nRankB * nComponents, nOverallB * nComponents,
localDofMap[feSpace].nRankDofs * nComponents, localDofMap[feSpace].nOverallDofs * nComponents,
&(fetiLumpedPreconData.tmp_vec_b));
MatGetVecs(mat_duals_duals, PETSC_NULL, &(fetiLumpedPreconData.tmp_vec_duals0));
MatGetVecs(mat_duals_duals, PETSC_NULL, &(fetiLumpedPreconData.tmp_vec_duals1));
......@@ -958,6 +949,8 @@ namespace AMDiS {
{
FUNCNAME("PetscSolverFeti::fillPetscMatrix()");
vector<const FiniteElemSpace*> feSpaces = getFeSpaces(mat);
const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
nComponents = mat->getSize();
......@@ -971,12 +964,12 @@ namespace AMDiS {
// === Create matrices for the FETI-DP method. ===
int nRowsRankB = nRankB * nComponents;
int nRowsOverallB = nOverallB * nComponents;
int nRowsRankB = localDofMap[feSpace].nRankDofs * nComponents;
int nRowsOverallB = localDofMap[feSpace].nOverallDofs * nComponents;
int nRowsRankPrimal = primalDofMap[feSpace].nRankDofs * nComponents;
int nRowsOverallPrimal = primalDofMap[feSpace].nOverallDofs * nComponents;
int nRowsInterior = nLocalInterior * nComponents;
int nRowsDual = nLocalDuals * nComponents;
int nRowsDual = dualDofMap[feSpace].size() * nComponents;
MatCreateSeqAIJ(PETSC_COMM_SELF, nRowsRankB, nRowsRankB, 30, PETSC_NULL,
&mat_b_b);
......@@ -1094,7 +1087,7 @@ namespace AMDiS {
// Column is not a primal variable.
int colIndex =
(localDofMap[feSpace][col(*icursor)] + rStartB) * nComponents + j;
(localDofMap[feSpace][col(*icursor)] + localDofMap[feSpace].rStartDofs) * nComponents + j;
if (rowPrimal) {
colsOther.push_back(colIndex);
......@@ -1157,13 +1150,13 @@ namespace AMDiS {
} else {
int localRowIndex = localDofMap[feSpace][*cursor] * nComponents + i;
for (unsigned int k = 0; k < cols.size(); k++)
cols[k] -= rStartB * nComponents;
cols[k] -= localDofMap[feSpace].rStartDofs * nComponents;
MatSetValues(mat_b_b, 1, &localRowIndex, cols.size(),
&(cols[0]), &(values[0]), ADD_VALUES);
if (colsOther.size()) {
int globalRowIndex =
(localDofMap[feSpace][*cursor] + rStartB) * nComponents + i;
(localDofMap[feSpace][*cursor] + localDofMap[feSpace].rStartDofs) * nComponents + i;
MatSetValues(mat_b_primal, 1, &globalRowIndex, colsOther.size(),
&(colsOther[0]), &(valuesOther[0]), ADD_VALUES);
}
......@@ -1258,7 +1251,7 @@ namespace AMDiS {
// === Create and fill PETSc matrix for Lagrange constraints. ===
createMatLagrange();
createMatLagrange(feSpaces);
// === Create solver for the non primal (thus local) variables. ===
......@@ -1288,8 +1281,8 @@ namespace AMDiS {
int nComponents = vec->getSize();
VecCreateMPI(PETSC_COMM_WORLD,
nRankB * nComponents,
nOverallB * nComponents, &f_b);
localDofMap[feSpace].nRankDofs * nComponents,
localDofMap[feSpace].nOverallDofs * nComponents, &f_b);
VecCreateMPI(PETSC_COMM_WORLD,
primalDofMap[feSpace].nRankDofs * nComponents,
primalDofMap[feSpace].nOverallDofs * nComponents, &f_primal);
......@@ -1303,7 +1296,7 @@ namespace AMDiS {
double value = *dofIt;
VecSetValues(f_primal, 1, &index, &value, ADD_VALUES);
} else {
index = (localDofMap[feSpace][index] + rStartB) * nComponents + i;
index = (localDofMap[feSpace][index] + localDofMap[feSpace].rStartDofs) * nComponents + i;
VecSetValue(f_b, index, *dofIt, INSERT_VALUES);
}
}
......@@ -1321,15 +1314,17 @@ namespace AMDiS {
{
FUNCNAME("PetscSolverFeti::solveLocalProblem()");
const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
Vec tmp;
VecCreateSeq(PETSC_COMM_SELF, nRankB * nComponents, &tmp);
VecCreateSeq(PETSC_COMM_SELF, localDofMap[feSpace].nRankDofs * nComponents, &tmp);
PetscScalar *tmpValues;
VecGetArray(tmp, &tmpValues);
PetscScalar *rhsValues;
VecGetArray(rhs, &rhsValues);
for (int i = 0; i < nRankB * nComponents; i++)
for (int i = 0; i < localDofMap[feSpace].nRankDofs * nComponents; i++)
tmpValues[i] = rhsValues[i];
VecRestoreArray(rhs, &rhsValues);
......@@ -1341,7 +1336,7 @@ namespace AMDiS {
PetscScalar *solValues;
VecGetArray(sol, &solValues);
for (int i = 0; i < nRankB * nComponents; i++)
for (int i = 0; i < localDofMap[feSpace].nRankDofs * nComponents; i++)
solValues[i] = tmpValues[i];
VecRestoreArray(sol, &solValues);
......@@ -1358,7 +1353,7 @@ namespace AMDiS {
const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
int nOverallNest =
(nOverallB +
(localDofMap[feSpace].nOverallDofs +
primalDofMap[feSpace].nOverallDofs +
lagrangeMap[feSpace].nOverallDofs) * nComponents;
......@@ -1377,8 +1372,8 @@ namespace AMDiS {
const PetscScalar *vals;
// === mat_b_b ===
for (int i = 0; i < nRankB * nComponents; i++) {
int rowIndex = rStartB * nComponents + i;
for (int i = 0; i < localDofMap[feSpace].nRankDofs * nComponents; i++) {
int rowIndex = localDofMap[feSpace].rStartDofs * nComponents + i;
MatGetRow(mat_b_b, i, &nCols, &cols, &vals);
MatSetValues(A_global, 1, &rowIndex, nCols, cols, vals, ADD_VALUES);
MatRestoreRow(mat_b_b, rowIndex, &nCols, &cols, &vals);
......@@ -1386,8 +1381,8 @@ namespace AMDiS {
PetscScalar *g_f_b;
VecGetArray(f_b, &g_f_b);
for (int i = 0; i < nRankB * nComponents; i++)
VecSetValue(A_global_rhs, rStartB * nComponents + i, g_f_b[i], INSERT_VALUES);
for (int i = 0; i < localDofMap[feSpace].nRankDofs * nComponents; i++)
VecSetValue(A_global_rhs, localDofMap[feSpace].rStartDofs * nComponents + i, g_f_b[i], INSERT_VALUES);
VecRestoreArray(f_b, &g_f_b);
......@@ -1398,10 +1393,10 @@ namespace AMDiS {
int rowIndex = primalDofMap[feSpace].rStartDofs * nComponents + i;
MatGetRow(mat_primal_primal, rowIndex, &nCols, &cols, &vals);
int rowIndexA = nOverallB * nComponents + rowIndex;
int rowIndexA = localDofMap[feSpace].nOverallDofs * nComponents + rowIndex;
vector<int> colsA(nCols);
for (int j = 0; j < nCols; j++)
colsA[j] = nOverallB * nComponents + cols[j];
colsA[j] = localDofMap[feSpace].nOverallDofs * nComponents + cols[j];
MatSetValues(A_global, 1, &rowIndexA, nCols, &(colsA[0]), vals, ADD_VALUES);
MatRestoreRow(mat_primal_primal, rowIndex, &nCols, &cols, &vals);
......@@ -1411,20 +1406,20 @@ namespace AMDiS {
VecGetArray(f_primal, &g_f_primal);
for (int i = 0; i < primalDofMap[feSpace].nRankDofs * nComponents; i++)
VecSetValue(A_global_rhs,
(nOverallB + primalDofMap[feSpace].rStartDofs) * nComponents + i, g_f_primal[i],
(localDofMap[feSpace].nOverallDofs + primalDofMap[feSpace].rStartDofs) * nComponents + i, g_f_primal[i],
INSERT_VALUES);
VecRestoreArray(f_primal, &g_f_primal);
// === mat_b_primal ===
for (int i = 0; i < nRankB * nComponents; i++) {
int rowIndex = rStartB * nComponents + i;
for (int i = 0; i < localDofMap[feSpace].nRankDofs * nComponents; i++) {
int rowIndex = localDofMap[feSpace].rStartDofs * nComponents + i;
MatGetRow(mat_b_primal, rowIndex, &nCols, &cols, &vals);
vector<int> colsA(nCols);
for (int j = 0; j < nCols; j++)
colsA[j] = nOverallB * nComponents + cols[j];
colsA[j] = localDofMap[feSpace].nOverallDofs * nComponents + cols[j];
MatSetValues(A_global, 1, &rowIndex, nCols, &(colsA[0]), vals, ADD_VALUES);
MatRestoreRow(mat_b_primal, rowIndex, &nCols, &cols, &vals);
......@@ -1436,7 +1431,7 @@ namespace AMDiS {
int rowIndex = primalDofMap[feSpace].rStartDofs * nComponents + i;
MatGetRow(mat_primal_b, rowIndex, &nCols, &cols, &vals);
int rowIndexA = nOverallB * nComponents + rowIndex;
int rowIndexA = localDofMap[feSpace].nOverallDofs * nComponents + rowIndex;
MatSetValues(A_global, 1, &rowIndexA, nCols, cols, vals, ADD_VALUES);
MatRestoreRow(mat_primal_b, rowIndex, &nCols, &cols, &vals);
......@@ -1448,7 +1443,7 @@ namespace AMDiS {
int rowIndex = lagrangeMap[feSpace].rStartDofs * nComponents + i;
MatGetRow(mat_lagrange, rowIndex, &nCols, &cols, &vals);
int rowIndexA = (nOverallB + primalDofMap[feSpace].nOverallDofs) * nComponents + rowIndex;
int rowIndexA = (localDofMap[feSpace].nOverallDofs + primalDofMap[feSpace].nOverallDofs) * nComponents + rowIndex;
MatSetValues(A_global, 1, &rowIndexA, nCols, cols, vals, ADD_VALUES);
MatRestoreRow(mat_lagrange, rowIndex, &nCols, &cols, &vals);
......@@ -1456,13 +1451,13 @@ namespace AMDiS {
// === mat_lagrange_transpose ===
for (int i = 0; i < nRankB * nComponents; i++) {
int rowIndex = rStartB * nComponents + i;
for (int i = 0; i < localDofMap[feSpace].nRankDofs * nComponents; i++) {
int rowIndex = localDofMap[feSpace].rStartDofs * nComponents + i;
MatGetRow(mat_lagrange_transpose, rowIndex, &nCols, &cols, &vals);
vector<int> colsA(nCols);
for (int j = 0; j < nCols; j++)
colsA[j] = (nOverallB + primalDofMap[feSpace].nOverallDofs) * nComponents + cols[j];
colsA[j] = (localDofMap[feSpace].nOverallDofs + primalDofMap[feSpace].nOverallDofs) * nComponents + cols[j];
MatSetValues(A_global, 1, &rowIndex, nCols, &(colsA[0]), vals, ADD_VALUES);
MatRestoreRow(mat_lagrange_transpose, rowIndex, &nCols, &cols, &vals);
......@@ -1488,12 +1483,12 @@ namespace AMDiS {
VecDuplicate(f_primal, &u_primal);
vector<PetscInt> localBIndex, globalBIndex;
localBIndex.reserve(nRankB * nComponents);
globalBIndex.reserve(nRankB * nComponents);
localBIndex.reserve(localDofMap[feSpace].nRankDofs * nComponents);
globalBIndex.reserve(localDofMap[feSpace].nRankDofs * nComponents);
for (int i = 0; i < nRankB * nComponents; i++) {
localBIndex.push_back(rStartB * nComponents + i);
globalBIndex.push_back(rStartB * nComponents + i);
for (int i = 0; i < localDofMap[feSpace].nRankDofs * nComponents; i++) {
localBIndex.push_back(localDofMap[feSpace].rStartDofs * nComponents + i);
globalBIndex.push_back(localDofMap[feSpace].rStartDofs * nComponents + i);
}
IS localBIs, globalBIs;
ISCreateGeneral(PETSC_COMM_SELF,