Commit 11c8bbc9 authored by Thomas Witkowski's avatar Thomas Witkowski

Work on Stokes FETI-DP

parent 297ae0f3
......@@ -256,12 +256,47 @@ namespace AMDiS {
vec[it.getDofIndex()] =
stdMpi.getRecvData(it.getRank())[it.getDofCounter()];
}
/// Works in the same way as the function above defined for DOFVectors. Due
/// to performance, this function does not call \ref synchVector for each
/// DOFVector, but instead sends all values of all DOFVectors all at once.
void synchVector(SystemVector &vec, int level = 0);
/// Works quite similar to the function \ref synchVector, but instead the
/// values of subdomain vectors are add along the boundaries.
template<typename T>
void synchAddVector(DOFVector<T> &vec)
{
StdMpi<vector<T> > stdMpi(mpiComm);
const FiniteElemSpace *fe = vec.getFeSpace();
for (DofComm::Iterator it(dofComm.getRecvDofs(), fe);
!it.end(); it.nextRank()) {
vector<T> dofs;
dofs.reserve(it.getDofs().size());
for (; !it.endDofIter(); it.nextDof())
dofs.push_back(vec[it.getDofIndex()]);
stdMpi.send(it.getRank(), dofs);
}
for (DofComm::Iterator it(dofComm.getSendDofs());
!it.end(); it.nextRank())
stdMpi.recv(it.getRank());
stdMpi.startCommunication();
for (DofComm::Iterator it(dofComm.getSendDofs(), fe);
!it.end(); it.nextRank())
for (; !it.endDofIter(); it.nextDof())
vec[it.getDofIndex()] +=
stdMpi.getRecvData(it.getRank())[it.getDofCounter()];
synchVector(vec);
}
/// In 3D, a subdomain may not be a valid AMDiS mesh if it contains two
/// parts which are only connected by an edge. In this case, the standard
/// refinement algorithm does not work correctly, as two elements connected
......
......@@ -96,6 +96,8 @@ namespace AMDiS {
Mat matTrans;
MatTranspose(mat, MAT_INITIAL_MATRIX, &matTrans);
bool isSym = true;
if (advancedTest) {
int rowStart, rowEnd;
MatGetOwnershipRange(mat, &rowStart, &rowEnd);
......@@ -105,7 +107,6 @@ namespace AMDiS {
const PetscScalar *vals, *valsTrans;
for (int i = rowStart; i < rowEnd; i++) {
bool isSym = true;
MatGetRow(mat, i, &nCols, &cols, &vals);
MatGetRow(matTrans, i, &nColsTrans, &colsTrans, &valsTrans);
......@@ -140,9 +141,6 @@ namespace AMDiS {
MatRestoreRow(mat, i, &nCols, &cols, &vals);
MatRestoreRow(matTrans, i, &nColsTrans, &colsTrans, &valsTrans);
if (!isSym)
return false;
}
}
......@@ -154,6 +152,6 @@ namespace AMDiS {
MSG("Matrix norm test: %e %e\n", norm1, norm2);
return (norm1 < 1e-10 && norm2 < 1e-10);
return (isSym && norm1 < 1e-10 && norm2 < 1e-10);
}
}
This diff is collapsed.
......@@ -232,6 +232,15 @@ namespace AMDiS {
/// For debugging only!
void debugNullSpace(SystemVector &vec);
/// For debugging only!
void createExplicitFetiMat(Mat fetiMat, Mat &explicitmat, int &nnzCounter);
/// For debugging only!
void createExplicitVec(Vec nestedVec, Vec &explicitVec);
/// For debugging only!
void debugFeti(Vec dbgRhsVec);
protected:
/// Mapping from primal DOF indices to a global index of primals.
ParallelDofMapping primalDofMap;
......
......@@ -301,75 +301,59 @@ namespace AMDiS {
VecNestGetSubVec(yvec, 0, &y_interface);
VecNestGetSubVec(yvec, 1, &y_lagrange);
#if 0
// MatMult(data->subSolver->getMatCoarse(0, 1), x_interface, data->tmp_primal);
// KSPSolve(data->ksp_primal, data->tmp_primal, data->tmp_primal);
// MatMult(data->subSolver->getMatCoarse(1, 0), data->tmp_primal, y_interface);
MatMult(data->subSolver->getMatInteriorCoarse(1), x_interface, data->tmp_vec_b0);
MatMultTranspose(*(data->mat_lagrange_scaled), x_lagrange, data->tmp_vec_b1);
VecAXPY(data->tmp_vec_b0, 1.0, data->tmp_vec_b1);
//MatMultTranspose(*(data->mat_lagrange_scaled), x_lagrange, data->tmp_vec_b0);
#else
VecCopy(x_interface, y_interface);
double scaleFactor = 1.0;
Parameters::get("scal", scaleFactor);
VecScale(y_interface, scaleFactor);
// VecPointwiseMult(y_interface, x_interface, data->h2vec);
MatMultTranspose(*(data->mat_lagrange_scaled), x_lagrange, data->tmp_vec_b0);
#endif
Parameters::get("lp->scal", scaleFactor);
bool mult = false;
Parameters::get("lp->mult", mult);
if (mult)
VecPointwiseMult(y_interface, x_interface, data->h2vec);
if (scaleFactor != 0.0)
VecScale(y_interface, scaleFactor);
MatMultTranspose(*(data->mat_lagrange_scaled), x_lagrange, data->tmp_vec_b0);
// === Restriction of the B nodes to the boundary nodes. ===
int nLocalB;
int nLocalDuals;
VecGetLocalSize(data->tmp_vec_b0, &nLocalB);
VecGetLocalSize(data->tmp_vec_duals0, &nLocalDuals);
PetscScalar *local_b, *local_duals;
VecGetArray(data->tmp_vec_b0, &local_b);
VecGetArray(data->tmp_vec_duals0, &local_duals);
for (map<int, int>::iterator it = data->localToDualMap.begin();
it != data->localToDualMap.end(); ++it)
local_duals[it->second] = local_b[it->first];
VecRestoreArray(data->tmp_vec_b0, &local_b);
VecRestoreArray(data->tmp_vec_duals0, &local_duals);
// === K_DD ===
MatMult(*(data->mat_duals_duals), data->tmp_vec_duals0, data->tmp_vec_duals1);
// === Prolongation from local dual nodes to B nodes.
VecGetArray(data->tmp_vec_b0, &local_b);
VecGetArray(data->tmp_vec_duals1, &local_duals);
for (map<int, int>::iterator it = data->localToDualMap.begin();
it != data->localToDualMap.end(); ++it)
local_b[it->first] = local_duals[it->second];
VecRestoreArray(data->tmp_vec_b0, &local_b);
VecRestoreArray(data->tmp_vec_duals0, &local_duals);
// Multiply with scaled Lagrange constraint matrix.
MatMult(*(data->mat_lagrange_scaled), data->tmp_vec_b0, y_lagrange);
#if 0
// Vec tmp_interface;
// VecDuplicate(y_interface, &tmp_interface);
MatMult(data->subSolver->getMatCoarseInterior(1), data->tmp_vec_b0, y_interface);
// VecAXPY(y_interface, 1.0, tmp_interface);
#endif
return 0;
}
}
......@@ -125,6 +125,10 @@ namespace AMDiS {
KSP ksp_primal;
Vec tmp_primal;
KSP ksp_feti_ex;
Mat mat_feti_ex;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment