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 2bec218f authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Added more nullspace support.

parent 30aa72ea
......@@ -402,11 +402,9 @@ namespace AMDiS {
/// Adds a macro element to the mesh
void addMacroElement(MacroElement* me);
/* \brief
* Removes a set of macro elements from the mesh. This works only for the
* case, that there are no global or local refinements, i.e., all macro
* elements have no children.
*/
/// Removes a set of macro elements from the mesh. This works only for the
/// case, that there are no global or local refinements, i.e., all macro
/// elements have no children.
void removeMacroElements(std::set<MacroElement*>& macros,
vector<const FiniteElemSpace*>& feSpaces);
......@@ -484,10 +482,8 @@ namespace AMDiS {
}
/** \brief
* This function is equal to \ref getDofIndexCoords as defined above, but takes
* a DOF index instead of a DOF pointer.
*/
/// This function is equal to \ref getDofIndexCoords as defined above, but
/// takes a DOF index instead of a DOF pointer.
bool getDofIndexCoords(DegreeOfFreedom dof,
const FiniteElemSpace* feSpace,
WorldVector<double>& coords);
......
......@@ -49,11 +49,9 @@ namespace AMDiS {
};
/** \brief
* This class defines the stationary problem definition in sequential
* computations. For parallel computations, see
* \ref ParallelProblemStatBase.
*/
/// This class defines the stationary problem definition in sequential
/// computations. For parallel computations, see
/// \ref ParallelProblemStatBase.
class ProblemStatSeq : public ProblemStatBase,
public StandardProblemIteration
{
......@@ -149,11 +147,9 @@ namespace AMDiS {
void dualAssemble(AdaptInfo *adaptInfo, Flag flag,
bool asmMatrix = true, bool asmVector = true);
/** \brief
* Determines the execution order of the single adaption steps. If adapt is
* true, mesh adaption will be performed. This allows to avoid mesh adaption,
* e.g. in timestep adaption loops of timestep adaptive strategies.
*/
/// Determines the execution order of the single adaption steps. If adapt is
/// true, mesh adaption will be performed. This allows to avoid mesh adaption,
/// e.g. in timestep adaption loops of timestep adaptive strategies.
virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION);
/// Returns number of managed problems
......@@ -168,10 +164,8 @@ namespace AMDiS {
return nComponents;
}
/** \brief
* Returns the problem with the given number. If only one problem
* is managed by this master problem, the number hasn't to be given.
*/
/// Returns the problem with the given number. If only one problem
/// is managed by this master problem, the number hasn't to be given.
virtual ProblemStatBase *getProblem(int number = 0)
{
return this;
......@@ -260,10 +254,8 @@ namespace AMDiS {
addBoundaryVectorOperator(type, &op, row);
}
/** \brief
* This function assembles a DOFMatrix and a DOFVector for the case,
* the meshes from row and col FE-space are equal.
*/
/// This function assembles a DOFMatrix and a DOFVector for the case,
/// the meshes from row and col FE-space are equal.
void assembleOnOneMesh(FiniteElemSpace *feSpace,
Flag assembleFlag,
DOFMatrix *matrix, DOFVector<double> *vector);
......@@ -533,10 +525,8 @@ namespace AMDiS {
}
/** \} */
/** \brief
* Outputs the mesh of the given component, but the values are taken from the
* residual error estimator.
*/
/// Outputs the mesh of the given component, but the values are taken from
/// the residual error estimator.
void writeResidualMesh(int comp, AdaptInfo *adaptInfo, string name);
/// Function that implements the serialization procedure.
......@@ -553,10 +543,8 @@ namespace AMDiS {
}
protected:
/** \brief
* If the exact solution is known, the problem can compute the exact
* error instead of the error estimation. This is done in this function.
*/
/// If the exact solution is known, the problem can compute the exact
/// error instead of the error estimation. This is done in this function.
void computeError(AdaptInfo *adaptInfo);
protected:
......@@ -571,11 +559,9 @@ namespace AMDiS {
/// vectors, \ref solution.
vector<string> componentNames;
/** \brief
* Number of problem meshes. If all components are defined on the same mesh,
* this number is 1. Otherwise, this variable is the number of different meshes
* within the problem.
*/
/// Number of problem meshes. If all components are defined on the same mesh,
/// this number is 1. Otherwise, this variable is the number of different meshes
/// within the problem.
int nMeshes;
/// FE spaces of this problem.
......@@ -590,11 +576,9 @@ namespace AMDiS {
/// Pointer to the meshes for the different problem components
vector<Mesh*> componentMeshes;
/** \brief
* Stores information about which meshes must be traversed to assemble the
* specific components. I.e., it was implemented to make use of different
* meshes for different components.
*/
/// Stores information about which meshes must be traversed to assemble the
/// specific components. I.e., it was implemented to make use of different
/// meshes for different components.
ComponentTraverseInfo traverseInfo;
/// Responsible for element marking.
......@@ -618,21 +602,17 @@ namespace AMDiS {
/// Composed system matrix
SolverMatrix<Matrix<DOFMatrix*> > solverMatrix;
/** \brief
* Some DOFMatrices of the systemMatrix may be assembled only once (for
* example if they are independent of the time or older solutions). If
* [i][j] of this field is set to true, the corresponding DOFMatrix will
* be assembled only once. All other matrices will be assembled at every
* time step.
*/
/// Some DOFMatrices of the systemMatrix may be assembled only once (for
/// example if they are independent of the time or older solutions). If
/// [i][j] of this field is set to true, the corresponding DOFMatrix will
/// be assembled only once. All other matrices will be assembled at every
/// time step.
vector<vector<bool> > assembleMatrixOnlyOnce;
/** \brief
* If [i][j] of this field is set to true, the corresponding DOFMatrix of
* the systemMatrix has been assembled at least once. This field is used
* to determine, if assembling of a matrix can be ommitted, if it is set
* to be assembled only once.
*/
/// If [i][j] of this field is set to true, the corresponding DOFMatrix of
/// the systemMatrix has been assembled at least once. This field is used
/// to determine, if assembling of a matrix can be ommitted, if it is set
/// to be assembled only once.
vector<vector<bool> > assembledMatrix;
/// Determines whether domain boundaries should be considered at assembling.
......@@ -641,47 +621,40 @@ namespace AMDiS {
/// Writes the meshes and solution after the adaption loop.
vector<FileWriterInterface*> fileWriters;
/** \brief
* All actions of mesh refinement are performed by refinementManager.
* If new refinement algorithms should be realized, one has to override
* RefinementManager and give one instance of it to AdaptStationary.
*/
/// All actions of mesh refinement are performed by refinementManager.
/// If new refinement algorithms should be realized, one has to override
/// RefinementManager and give one instance of it to AdaptStationary.
RefinementManager *refinementManager;
/** \brief
* All actions of mesh coarsening are performed by coarseningManager.
* If new coarsening algorithms should be realized, one has to override
* CoarseningManager and give one instance of it to AdaptStationary.
*/
/// All actions of mesh coarsening are performed by coarseningManager.
/// If new coarsening algorithms should be realized, one has to override
/// CoarseningManager and give one instance of it to AdaptStationary.
CoarseningManager *coarseningManager;
/// Info level.
int info;
/// If true, the stationary problem was deserialized from some serialization file.
/// If true, the stationary problem was deserialized from some serialization
/// file.
bool deserialized;
/** \brief
* This vectors stores pointers to functions defining the exact solution of
* the problem. This may be used to compute the real error of the computed
* solution.
*/
/// This vectors stores pointers to functions defining the exact solution of
/// the problem. This may be used to compute the real error of the computed
/// solution.
vector<AbstractFunction<double, WorldVector<double> >*> exactSolutionFcts;
/** \brief
* If true, the error is not estimated but computed from the exact solution
* defined by \ref exactSolutionFcts.
*/
/// If true, the error is not estimated but computed from the exact solution
/// defined by \ref exactSolutionFcts.
bool computeExactError;
/** \brief
* If at least on boundary condition is set, this variable is true. It is used
* to ensure that no operators are added after boundary condition were set. If
* this would happen, boundary conditions could set wrong on off diagonal matrices.
*/
/// If at least on boundary condition is set, this variable is true. It is
/// used to ensure that no operators are added after boundary condition were
/// set. If this would happen, boundary conditions could set wrong on off
/// diagonal matrices.
bool boundaryConditionSet;
/// If true, AMDiS prints information about the assembling procedure to the screen.
/// If true, AMDiS prints information about the assembling procedure to
/// the screen.
bool writeAsmInfo;
map<Operator*, vector<OperatorPos> > operators;
......
......@@ -243,6 +243,7 @@ namespace AMDiS {
("Should not happen (%d)!\n", multPeriodicDof2.size());
TEST_EXIT_DBG(multPeriodicDof3.size() == 0)("Should not happen!\n");
}
if (mesh->getDim() == 3) {
TEST_EXIT_DBG(multPeriodicDof3.size() == 0 ||
multPeriodicDof3.size() == 8)
......
......@@ -295,6 +295,14 @@ namespace AMDiS {
return levelData;
}
void updateLocalGlobalNumbering();
/// Updates the local and global DOF numbering after the mesh has been
/// changed.
void updateLocalGlobalNumbering(ParallelDofMapping &dmap,
DofComm &dcom,
const FiniteElemSpace *feSpace);
protected:
void addProblemStat(ProblemStatSeq *probStat);
......@@ -308,14 +316,6 @@ namespace AMDiS {
/// partition.
void removeMacroElements();
void updateLocalGlobalNumbering();
/// Updates the local and global DOF numbering after the mesh has been
/// changed.
void updateLocalGlobalNumbering(ParallelDofMapping &dmap,
DofComm &dcom,
const FiniteElemSpace *feSpace);
/// Calls \ref createPeriodicMap(feSpace) for all FE spaces that are
/// handled by the mesh distributor.
void createPeriodicMap();
......
......@@ -37,6 +37,8 @@ namespace AMDiS {
Parameters::get("parallel->remove rhs null space", removeRhsNullspace);
Parameters::get("parallel->has constant null space", hasConstantNullspace);
Parameters::get("parallel->nullspace->const in comp",
constNullspaceComponent);
}
......
......@@ -256,6 +256,8 @@ namespace AMDiS {
bool removeRhsNullspace;
bool hasConstantNullspace;
vector<int> constNullspaceComponent;
};
......
......@@ -119,9 +119,8 @@ namespace AMDiS {
KSPSetType(kspInterior, KSPBCGS);
KSPSetOptionsPrefix(kspInterior, kspPrefix.c_str());
KSPSetFromOptions(kspInterior);
PCSetFromOptions(pcInterior);
createFieldSplit(pcInterior);
initPreconditioner(pcInterior);
// Do not delete the solution vector, use it for the initial guess.
if (!zeroStartVector)
......@@ -131,6 +130,14 @@ namespace AMDiS {
}
void PetscSolverGlobalMatrix::fillPetscMatrix(DOFMatrix *mat)
{
Matrix<DOFMatrix*> m(1, 1);
m[0][0] = mat;
fillPetscMatrix(&m);
}
void PetscSolverGlobalMatrix::fillPetscMatrixWithCoarseSpace(Matrix<DOFMatrix*> *mat)
{
FUNCNAME("PetscSolverGlobalMatrix::fillPetscMatrixWithCoarseSpace()");
......@@ -317,7 +324,6 @@ namespace AMDiS {
KSPSetOperators(kspInterior, matIntInt, matIntInt, SAME_NONZERO_PATTERN);
KSPSetOptionsPrefix(kspInterior, "interior_");
KSPSetType(kspInterior, KSPPREONLY);
PC pcInterior;
KSPGetPC(kspInterior, &pcInterior);
PCSetType(pcInterior, PCLU);
if (subdomainLevel == 0)
......@@ -393,9 +399,21 @@ namespace AMDiS {
MatNullSpace matNullspace;
Vec nullspaceBasis;
if (nullspace.size() > 0 || hasConstantNullspace) {
if (nullspace.size() > 0 ||
hasConstantNullspace ||
constNullspaceComponent.size() > 0) {
TEST_EXIT_DBG(nullspace.size() <= 1)("Not yet implemented!\n");
if (constNullspaceComponent.size() > 0) {
nullspace.clear();
SystemVector *basisVec = new SystemVector(vec);
basisVec->set(0.0);
for (unsigned int i = 0; i < constNullspaceComponent.size(); i++)
basisVec->getDOFVector(constNullspaceComponent[i])->set(1.0);
nullspace.push_back(basisVec);
}
if (nullspace.size() > 0) {
VecDuplicate(petscSolVec, &nullspaceBasis);
for (int i = 0; i < nComponents; i++)
......@@ -403,6 +421,8 @@ namespace AMDiS {
VecAssemblyBegin(nullspaceBasis);
VecAssemblyEnd(nullspaceBasis);
VecNormalize(nullspaceBasis, PETSC_NULL);
MatNullSpaceCreate(mpiCommGlobal, (hasConstantNullspace ? PETSC_TRUE : PETSC_FALSE),
1, &nullspaceBasis, &matNullspace);
......@@ -415,6 +435,7 @@ namespace AMDiS {
MatNullSpaceCreate(mpiCommGlobal, PETSC_TRUE, 0, PETSC_NULL, &matNullspace);
}
MatSetNullSpace(matIntInt, matNullspace);
KSPSetNullSpace(kspInterior, matNullspace);
// === Remove null space, if requested. ===
......@@ -455,11 +476,6 @@ namespace AMDiS {
}
VecRestoreArray(petscSolVec, &vecPointer);
// === Synchronize DOFs at common DOFs, i.e., DOFs that correspond to ===
// === more than one partition. ===
meshDistributor->synchVector(vec);
}
......@@ -517,6 +533,8 @@ namespace AMDiS {
{
FUNCNAME("PetscSolverGlobalMatrix::destroyMatrixData()");
exitPreconditioner(pcInterior);
MatDestroy(&matIntInt);
KSPDestroy(&kspInterior);
......@@ -580,6 +598,21 @@ namespace AMDiS {
}
void PetscSolverGlobalMatrix::initPreconditioner(PC pc)
{
FUNCNAME("PetscSolverGlobalMatrix::initPreconditioner()");
PCSetFromOptions(pc);
createFieldSplit(pc);
}
void PetscSolverGlobalMatrix::exitPreconditioner(PC pc)
{
FUNCNAME("PetscSolverGlobalMatrix::exitPreconditioner()");
}
void PetscSolverGlobalMatrix::setDofMatrix(DOFMatrix* mat,
int nRowMat, int nColMat)
{
......@@ -766,7 +799,6 @@ namespace AMDiS {
else
perColDof = entry[i].second;
entry.push_back(make_pair(perRowDof, perColDof));
}
}
......@@ -815,6 +847,7 @@ namespace AMDiS {
// Traverse all used DOFs in the dof vector.
DOFVector<double>::Iterator dofIt(vec, USED_DOFS);
for (dofIt.reset(); !dofIt.end(); ++dofIt) {
if (rankOnly && !(*interiorMap)[feSpace].isRankDof(dofIt.getDOFIndex()))
continue;
......@@ -836,7 +869,7 @@ namespace AMDiS {
else
index =
interiorMap->getMatIndex(nRowVec, dofIt.getDOFIndex()) + rStartInterior;
if (perMap.isPeriodic(feSpace, globalRowDof)) {
std::set<int>& perAsc = perMap.getAssociations(feSpace, globalRowDof);
double value = *dofIt / (perAsc.size() + 1.0);
......@@ -846,6 +879,7 @@ namespace AMDiS {
perIt != perAsc.end(); ++perIt) {
int mappedDof = perMap.map(feSpace, *perIt, globalRowDof);
int mappedIndex = interiorMap->getMatIndex(nRowVec, mappedDof);
VecSetValue(vecInterior, mappedIndex, value, ADD_VALUES);
}
} else {
......
......@@ -50,6 +50,10 @@ namespace AMDiS {
void fillPetscMatrix(Matrix<DOFMatrix*> *mat);
/// This function is just a small wrapper that creates a 1x1 matrix that
/// contains exactly one DOFMatrix and than calls \ref fillPetscMatrix
void fillPetscMatrix(DOFMatrix *mat);
void fillPetscMatrixWithCoarseSpace(Matrix<DOFMatrix*> *mat);
void fillPetscRhs(SystemVector *vec);
......@@ -62,9 +66,13 @@ namespace AMDiS {
void destroyVectorData();
protected:
void createFieldSplit(PC pc);
protected:
virtual void initPreconditioner(PC pc);
virtual void exitPreconditioner(PC pc);
/// Creates a new non zero pattern structure for the PETSc matrix.
void createPetscNnzStructure(Matrix<DOFMatrix*> *mat);
......
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