mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: GAMGSolver: initial working version
This commit is contained in:
@ -24,6 +24,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "GAMGSolver.H"
|
#include "GAMGSolver.H"
|
||||||
|
#include "GAMGInterface.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -74,20 +75,212 @@ Foam::GAMGSolver::GAMGSolver
|
|||||||
interpolateCorrection_(false),
|
interpolateCorrection_(false),
|
||||||
scaleCorrection_(matrix.symmetric()),
|
scaleCorrection_(matrix.symmetric()),
|
||||||
directSolveCoarsest_(false),
|
directSolveCoarsest_(false),
|
||||||
processorAgglomerate_(false),
|
|
||||||
agglomeration_(GAMGAgglomeration::New(matrix_, controlDict_)),
|
agglomeration_(GAMGAgglomeration::New(matrix_, controlDict_)),
|
||||||
|
|
||||||
matrixLevels_(agglomeration_.size()),
|
matrixLevels_(agglomeration_.size()),
|
||||||
interfaceLevels_(agglomeration_.size()),
|
interfaceLevels_(agglomeration_.size()),
|
||||||
|
primitiveInterfaceLevels_(agglomeration_.size()),
|
||||||
interfaceLevelsBouCoeffs_(agglomeration_.size()),
|
interfaceLevelsBouCoeffs_(agglomeration_.size()),
|
||||||
interfaceLevelsIntCoeffs_(agglomeration_.size())
|
interfaceLevelsIntCoeffs_(agglomeration_.size())
|
||||||
{
|
{
|
||||||
readControls();
|
readControls();
|
||||||
|
|
||||||
forAll(agglomeration_, fineLevelIndex)
|
//if (agglomeration_.processorAgglomerate())
|
||||||
|
//{
|
||||||
|
// procMatrixLevels_.setSize(agglomeration_.size());
|
||||||
|
// procInterfaceLevels_.setSize(agglomeration_.size());
|
||||||
|
// procPrimitiveInterfaces_.setSize(agglomeration_.size());
|
||||||
|
// procInterfaceLevelsBouCoeffs_.setSize(agglomeration_.size());
|
||||||
|
// procInterfaceLevelsIntCoeffs_.setSize(agglomeration_.size());
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (agglomeration_.processorAgglomerate())
|
||||||
{
|
{
|
||||||
agglomerateMatrix(fineLevelIndex);
|
forAll(agglomeration_, fineLevelIndex)
|
||||||
|
{
|
||||||
|
if (agglomeration_.hasMeshLevel(fineLevelIndex))
|
||||||
|
{
|
||||||
|
Pout<< "Level:" << fineLevelIndex
|
||||||
|
<< " agglomerating matrix." << endl;
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
// !agglomeration_.hasMeshLevel(fineLevelIndex+1)
|
||||||
|
//|| (
|
||||||
|
// agglomeration_.nCells(fineLevelIndex)
|
||||||
|
// != agglomeration_.meshLevel(fineLevelIndex+1).
|
||||||
|
// lduAddr().size()
|
||||||
|
// )
|
||||||
|
|
||||||
|
(fineLevelIndex+1) < agglomeration_.procBoundaryMap_.size()
|
||||||
|
&& agglomeration_.procBoundaryMap_.set(fineLevelIndex+1)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Pout<< "Level:" << fineLevelIndex
|
||||||
|
<< " agglomerating onto dummy coarse mesh." << endl;
|
||||||
|
|
||||||
|
// Construct matrix without referencing the coarse mesh so
|
||||||
|
// construct a dummy mesh instead. This will get overwritten
|
||||||
|
// by the call to procAgglomerateMatrix so is only to get
|
||||||
|
// it through agglomerateMatrix
|
||||||
|
|
||||||
|
|
||||||
|
const lduInterfacePtrsList& fineMeshInterfaces =
|
||||||
|
agglomeration_.interfaceLevel(fineLevelIndex);
|
||||||
|
|
||||||
|
PtrList<GAMGInterface> dummyPrimMeshInterfaces
|
||||||
|
(
|
||||||
|
fineMeshInterfaces.size()
|
||||||
|
);
|
||||||
|
lduInterfacePtrsList dummyMeshInterfaces
|
||||||
|
(
|
||||||
|
dummyPrimMeshInterfaces.size()
|
||||||
|
);
|
||||||
|
forAll(fineMeshInterfaces, intI)
|
||||||
|
{
|
||||||
|
if (fineMeshInterfaces.set(intI))
|
||||||
|
{
|
||||||
|
OStringStream os;
|
||||||
|
refCast<const GAMGInterface>
|
||||||
|
(
|
||||||
|
fineMeshInterfaces[intI]
|
||||||
|
).write(os);
|
||||||
|
IStringStream is(os.str());
|
||||||
|
|
||||||
|
dummyPrimMeshInterfaces.set
|
||||||
|
(
|
||||||
|
intI,
|
||||||
|
GAMGInterface::New
|
||||||
|
(
|
||||||
|
fineMeshInterfaces[intI].type(),
|
||||||
|
intI,
|
||||||
|
dummyMeshInterfaces,
|
||||||
|
is
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(dummyPrimMeshInterfaces, intI)
|
||||||
|
{
|
||||||
|
if (dummyPrimMeshInterfaces.set(intI))
|
||||||
|
{
|
||||||
|
dummyMeshInterfaces.set
|
||||||
|
(
|
||||||
|
intI,
|
||||||
|
&dummyPrimMeshInterfaces[intI]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// So:
|
||||||
|
// - pass in incorrect mesh (= fine mesh instead of coarse)
|
||||||
|
// - pass in dummy interfaces
|
||||||
|
agglomerateMatrix
|
||||||
|
(
|
||||||
|
fineLevelIndex,
|
||||||
|
agglomeration_.meshLevel(fineLevelIndex),
|
||||||
|
dummyMeshInterfaces
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const labelList& procAgglomMap =
|
||||||
|
agglomeration_.procAgglomMap(fineLevelIndex+1);
|
||||||
|
const List<int>& procIDs =
|
||||||
|
agglomeration_.agglomProcIDs(fineLevelIndex+1);
|
||||||
|
|
||||||
|
Pout<< "Level:" << fineLevelIndex
|
||||||
|
<< " agglomerating onto procIDs:" << procIDs << endl;
|
||||||
|
|
||||||
|
procAgglomerateMatrix
|
||||||
|
(
|
||||||
|
procAgglomMap,
|
||||||
|
procIDs,
|
||||||
|
fineLevelIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
Pout<< "Level:" << fineLevelIndex
|
||||||
|
<< " DONE agglomerating onto procIDs:" << procIDs
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pout<< "Level:" << fineLevelIndex
|
||||||
|
<< " agglomerating onto coarse mesh at level "
|
||||||
|
<< fineLevelIndex + 1 << endl;
|
||||||
|
|
||||||
|
agglomerateMatrix
|
||||||
|
(
|
||||||
|
fineLevelIndex,
|
||||||
|
agglomeration_.meshLevel(fineLevelIndex + 1),
|
||||||
|
agglomeration_.interfaceLevel(fineLevelIndex + 1)
|
||||||
|
);
|
||||||
|
Pout<< "Level:" << fineLevelIndex
|
||||||
|
<< " DONE agglomerating onto coarse mesh at level "
|
||||||
|
<< fineLevelIndex + 1 << endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No mesh. Not involved in calculation anymore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
forAll(agglomeration_, fineLevelIndex)
|
||||||
|
{
|
||||||
|
// Agglomerate on to coarse level mesh
|
||||||
|
agglomerateMatrix
|
||||||
|
(
|
||||||
|
fineLevelIndex,
|
||||||
|
agglomeration_.meshLevel(fineLevelIndex + 1),
|
||||||
|
agglomeration_.interfaceLevel(fineLevelIndex + 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
for
|
||||||
|
(
|
||||||
|
label fineLevelIndex = 0;
|
||||||
|
fineLevelIndex <= matrixLevels_.size();
|
||||||
|
fineLevelIndex++
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (fineLevelIndex == 0 || matrixLevels_.set(fineLevelIndex-1))
|
||||||
|
{
|
||||||
|
const lduMatrix& matrix = matrixLevel(fineLevelIndex);
|
||||||
|
const lduInterfaceFieldPtrsList& interfaces =
|
||||||
|
interfaceLevel(fineLevelIndex);
|
||||||
|
|
||||||
|
Pout<< "level:" << fineLevelIndex << nl
|
||||||
|
<< " nCells:" << matrix.diag().size() << nl
|
||||||
|
<< " nFaces:" << matrix.lower().size() << nl
|
||||||
|
<< " nInterfaces:" << interfaces.size()
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
forAll(interfaces, i)
|
||||||
|
{
|
||||||
|
if (interfaces.set(i))
|
||||||
|
{
|
||||||
|
Pout<< " " << i
|
||||||
|
<< "\ttype:" << interfaces[i].type()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pout<< "level:" << fineLevelIndex << " : no matrix" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Pout<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (matrixLevels_.size())
|
if (matrixLevels_.size())
|
||||||
{
|
{
|
||||||
@ -119,117 +312,118 @@ Foam::GAMGSolver::GAMGSolver
|
|||||||
|
|
||||||
UPstream::warnComm = oldWarn;
|
UPstream::warnComm = oldWarn;
|
||||||
}
|
}
|
||||||
else if (processorAgglomerate_)
|
else if (agglomeration_.processorAgglomerate())
|
||||||
{
|
{
|
||||||
// Pick a level to processor agglomerate
|
//// Pick a level to processor agglomerate
|
||||||
label agglomLevel = matrixLevels_.size() - 1;//1;
|
//label agglomLevel = matrixLevels_.size() - 1;//1;
|
||||||
|
//
|
||||||
|
//
|
||||||
// Get mesh and matrix at this level
|
//// Get mesh and matrix at this level
|
||||||
const lduMatrix& levelMatrix = matrixLevels_[agglomLevel];
|
//const lduMatrix& levelMatrix = matrixLevels_[agglomLevel];
|
||||||
const lduMesh& levelMesh = levelMatrix.mesh();
|
//const lduMesh& levelMesh = levelMatrix.mesh();
|
||||||
|
//
|
||||||
|
//
|
||||||
label levelComm = levelMesh.comm();
|
//label levelComm = levelMesh.comm();
|
||||||
label oldWarn = UPstream::warnComm;
|
//label oldWarn = UPstream::warnComm;
|
||||||
UPstream::warnComm = levelComm;
|
//UPstream::warnComm = levelComm;
|
||||||
|
//
|
||||||
Pout<< "Solve generic on mesh (level=" << agglomLevel
|
//Pout<< "Solve generic on mesh (level=" << agglomLevel
|
||||||
<< ") using communicator " << levelComm << endl;
|
// << ") using communicator " << levelComm << endl;
|
||||||
|
//
|
||||||
// Processor restriction map: per processor the coarse processor
|
//// Processor restriction map: per processor the coarse processor
|
||||||
labelList procAgglomMap(UPstream::nProcs(levelComm));
|
//labelList procAgglomMap(UPstream::nProcs(levelComm));
|
||||||
// Master processor
|
//// Master processor
|
||||||
labelList masterProcs;
|
//labelList masterProcs;
|
||||||
// Local processors that agglomerate. agglomProcIDs[0] is in
|
//// Local processors that agglomerate. agglomProcIDs[0] is in
|
||||||
// masterProc.
|
//// masterProc.
|
||||||
List<int> agglomProcIDs;
|
//List<int> agglomProcIDs;
|
||||||
|
//
|
||||||
{
|
//{
|
||||||
procAgglomMap[0] = 0;
|
// procAgglomMap[0] = 0;
|
||||||
procAgglomMap[1] = 0;
|
// procAgglomMap[1] = 0;
|
||||||
procAgglomMap[2] = 1;
|
// procAgglomMap[2] = 1;
|
||||||
procAgglomMap[3] = 1;
|
// procAgglomMap[3] = 1;
|
||||||
|
//
|
||||||
// Determine the master processors
|
// // Determine the master processors
|
||||||
Map<label> agglomToMaster(procAgglomMap.size());
|
// Map<label> agglomToMaster(procAgglomMap.size());
|
||||||
|
//
|
||||||
forAll(procAgglomMap, procI)
|
// forAll(procAgglomMap, procI)
|
||||||
{
|
// {
|
||||||
label coarseI = procAgglomMap[procI];
|
// label coarseI = procAgglomMap[procI];
|
||||||
|
//
|
||||||
Map<label>::iterator fnd = agglomToMaster.find(coarseI);
|
// Map<label>::iterator fnd = agglomToMaster.find(coarseI);
|
||||||
if (fnd == agglomToMaster.end())
|
// if (fnd == agglomToMaster.end())
|
||||||
{
|
// {
|
||||||
agglomToMaster.insert(coarseI, procI);
|
// agglomToMaster.insert(coarseI, procI);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
fnd() = max(fnd(), procI);
|
// fnd() = max(fnd(), procI);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
masterProcs.setSize(agglomToMaster.size());
|
// masterProcs.setSize(agglomToMaster.size());
|
||||||
forAllConstIter(Map<label>, agglomToMaster, iter)
|
// forAllConstIter(Map<label>, agglomToMaster, iter)
|
||||||
{
|
// {
|
||||||
masterProcs[iter.key()] = iter();
|
// masterProcs[iter.key()] = iter();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
// Collect all the processors in my agglomeration
|
// // Collect all the processors in my agglomeration
|
||||||
label myProcID = Pstream::myProcNo(levelComm);
|
// label myProcID = Pstream::myProcNo(levelComm);
|
||||||
label myAgglom = procAgglomMap[myProcID];
|
// label myAgglom = procAgglomMap[myProcID];
|
||||||
|
//
|
||||||
// Get all processors agglomerating to the same coarse processor
|
// // Get all processors agglomerating to the same coarse
|
||||||
agglomProcIDs = findIndices(procAgglomMap, myAgglom);
|
// // processor
|
||||||
// Make sure the master is the first element.
|
// agglomProcIDs = findIndices(procAgglomMap, myAgglom);
|
||||||
label index = findIndex
|
// // Make sure the master is the first element.
|
||||||
(
|
// label index = findIndex
|
||||||
agglomProcIDs,
|
// (
|
||||||
agglomToMaster[myAgglom]
|
// agglomProcIDs,
|
||||||
);
|
// agglomToMaster[myAgglom]
|
||||||
Swap(agglomProcIDs[0], agglomProcIDs[index]);
|
// );
|
||||||
}
|
// Swap(agglomProcIDs[0], agglomProcIDs[index]);
|
||||||
|
//}
|
||||||
|
//
|
||||||
Pout<< "procAgglomMap:" << procAgglomMap << endl;
|
//
|
||||||
Pout<< "agglomProcIDs:" << agglomProcIDs << endl;
|
//Pout<< "procAgglomMap:" << procAgglomMap << endl;
|
||||||
|
//Pout<< "agglomProcIDs:" << agglomProcIDs << endl;
|
||||||
// Allocate a communicator for the processor-agglomerated matrix
|
//
|
||||||
label procAgglomComm = UPstream::allocateCommunicator
|
//// Allocate a communicator for the processor-agglomerated matrix
|
||||||
(
|
//label procAgglomComm = UPstream::allocateCommunicator
|
||||||
levelComm,
|
//(
|
||||||
masterProcs
|
// levelComm,
|
||||||
);
|
// masterProcs
|
||||||
Pout<< "** Allocated communicator " << procAgglomComm
|
//);
|
||||||
<< " for indices " << masterProcs
|
//Pout<< "** Allocated communicator " << procAgglomComm
|
||||||
<< " in processor list " << UPstream::procID(levelComm)
|
// << " for indices " << masterProcs
|
||||||
<< endl;
|
// << " in processor list " << UPstream::procID(levelComm)
|
||||||
|
// << endl;
|
||||||
|
//
|
||||||
|
//
|
||||||
// Gather matrix and mesh onto agglomProcIDs[0]
|
//
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
//// Gather matrix and mesh onto agglomProcIDs[0]
|
||||||
|
//// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
procAgglomerateMatrix
|
//
|
||||||
(
|
//procAgglomerateMatrix
|
||||||
// Agglomeration information
|
//(
|
||||||
procAgglomMap,
|
// // Agglomeration information
|
||||||
agglomProcIDs,
|
// procAgglomMap,
|
||||||
procAgglomComm,
|
// agglomProcIDs,
|
||||||
|
// procAgglomComm,
|
||||||
agglomLevel, // level (coarse, not fine level!)
|
//
|
||||||
|
// agglomLevel, // level (coarse, not fine level!)
|
||||||
// Resulting matrix
|
//
|
||||||
allMatrixPtr_,
|
// // Resulting matrix
|
||||||
allInterfaceBouCoeffs_,
|
// allMatrixPtr_,
|
||||||
allInterfaceIntCoeffs_,
|
// allInterfaceBouCoeffs_,
|
||||||
allPrimitiveInterfaces_,
|
// allInterfaceIntCoeffs_,
|
||||||
allInterfaces_
|
// allPrimitiveInterfaces_,
|
||||||
);
|
// allInterfaces_
|
||||||
|
//);
|
||||||
|
//
|
||||||
UPstream::warnComm = oldWarn;
|
//
|
||||||
|
//UPstream::warnComm = oldWarn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -258,19 +452,19 @@ Foam::GAMGSolver::GAMGSolver
|
|||||||
|
|
||||||
Foam::GAMGSolver::~GAMGSolver()
|
Foam::GAMGSolver::~GAMGSolver()
|
||||||
{
|
{
|
||||||
// Clear the the lists of pointers to the interfaces
|
// // Clear the the lists of pointers to the interfaces
|
||||||
forAll(interfaceLevels_, leveli)
|
// forAll(interfaceLevels_, leveli)
|
||||||
{
|
// {
|
||||||
lduInterfaceFieldPtrsList& curLevel = interfaceLevels_[leveli];
|
// lduInterfaceFieldPtrsList& curLevel = interfaceLevels_[leveli];
|
||||||
|
//
|
||||||
forAll(curLevel, i)
|
// forAll(curLevel, i)
|
||||||
{
|
// {
|
||||||
if (curLevel.set(i))
|
// if (curLevel.set(i))
|
||||||
{
|
// {
|
||||||
delete curLevel(i);
|
// delete curLevel(i);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!cacheAgglomeration_)
|
if (!cacheAgglomeration_)
|
||||||
{
|
{
|
||||||
@ -305,7 +499,6 @@ void Foam::GAMGSolver::readControls()
|
|||||||
controlDict_.readIfPresent("interpolateCorrection", interpolateCorrection_);
|
controlDict_.readIfPresent("interpolateCorrection", interpolateCorrection_);
|
||||||
controlDict_.readIfPresent("scaleCorrection", scaleCorrection_);
|
controlDict_.readIfPresent("scaleCorrection", scaleCorrection_);
|
||||||
controlDict_.readIfPresent("directSolveCoarsest", directSolveCoarsest_);
|
controlDict_.readIfPresent("directSolveCoarsest", directSolveCoarsest_);
|
||||||
controlDict_.readIfPresent("processorAgglomerate", processorAgglomerate_);
|
|
||||||
|
|
||||||
Pout<< "GAMGSolver settings :"
|
Pout<< "GAMGSolver settings :"
|
||||||
<< " cacheAgglomeration:" << cacheAgglomeration_
|
<< " cacheAgglomeration:" << cacheAgglomeration_
|
||||||
@ -319,7 +512,6 @@ void Foam::GAMGSolver::readControls()
|
|||||||
<< " interpolateCorrection:" << interpolateCorrection_
|
<< " interpolateCorrection:" << interpolateCorrection_
|
||||||
<< " scaleCorrection:" << scaleCorrection_
|
<< " scaleCorrection:" << scaleCorrection_
|
||||||
<< " directSolveCoarsest:" << directSolveCoarsest_
|
<< " directSolveCoarsest:" << directSolveCoarsest_
|
||||||
<< " processorAgglomerate:" << processorAgglomerate_
|
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -122,6 +122,8 @@ class GAMGSolver
|
|||||||
// Warning: Needs to be deleted explicitly.
|
// Warning: Needs to be deleted explicitly.
|
||||||
PtrList<lduInterfaceFieldPtrsList> interfaceLevels_;
|
PtrList<lduInterfaceFieldPtrsList> interfaceLevels_;
|
||||||
|
|
||||||
|
PtrList<PtrList<lduInterfaceField> > primitiveInterfaceLevels_;
|
||||||
|
|
||||||
//- Hierarchy of interface boundary coefficients
|
//- Hierarchy of interface boundary coefficients
|
||||||
PtrList<FieldField<Field, scalar> > interfaceLevelsBouCoeffs_;
|
PtrList<FieldField<Field, scalar> > interfaceLevelsBouCoeffs_;
|
||||||
|
|
||||||
@ -131,14 +133,14 @@ class GAMGSolver
|
|||||||
//- LU decompsed coarsest matrix
|
//- LU decompsed coarsest matrix
|
||||||
autoPtr<LUscalarMatrix> coarsestLUMatrixPtr_;
|
autoPtr<LUscalarMatrix> coarsestLUMatrixPtr_;
|
||||||
|
|
||||||
// Processor matrix agglomeration
|
//// Processor matrix agglomeration
|
||||||
|
|
||||||
//- Combined coarsest level matrix for all processors
|
////- Combined coarsest level matrix for all processors
|
||||||
autoPtr<lduMatrix> allMatrixPtr_;
|
//PtrList<lduMatrix> procMatrixLevels_;
|
||||||
FieldField<Field, scalar> allInterfaceBouCoeffs_;
|
//PtrList<lduInterfaceFieldPtrsList> procInterfaceLevels_;
|
||||||
FieldField<Field, scalar> allInterfaceIntCoeffs_;
|
//PtrList<PtrList<lduInterfaceField> > procPrimitiveInterfaces_;
|
||||||
PtrList<lduInterfaceField> allPrimitiveInterfaces_;
|
//PtrList<FieldField<Field, scalar> > procInterfaceLevelsBouCoeffs_;
|
||||||
lduInterfaceFieldPtrsList allInterfaces_;
|
//PtrList<FieldField<Field, scalar> > procInterfaceLevelsIntCoeffs_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
@ -167,8 +169,25 @@ class GAMGSolver
|
|||||||
const label i
|
const label i
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Agglomerate coarse matrix
|
//- Agglomerate coarse matrix. Supply mesh to use - so we can
|
||||||
void agglomerateMatrix(const label fineLevelIndex);
|
// construct temporary matrix on the fine mesh (instead of the coarse
|
||||||
|
// mesh)
|
||||||
|
void agglomerateMatrix
|
||||||
|
(
|
||||||
|
const label fineLevelIndex,
|
||||||
|
const lduMesh& coarseMesh,
|
||||||
|
const lduInterfacePtrsList& coarseMeshInterfaces
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Agglomerate coarse interface coefficients
|
||||||
|
void agglomerateInterfaceCoefficients
|
||||||
|
(
|
||||||
|
const label fineLevelIndex,
|
||||||
|
const lduInterfacePtrsList& coarseMeshInterfaces,
|
||||||
|
lduInterfaceFieldPtrsList& coarseInterfaces,
|
||||||
|
FieldField<Field, scalar>& coarseInterfaceBouCoeffs,
|
||||||
|
FieldField<Field, scalar>& coarseInterfaceIntCoeffs
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Collect matrices from other processors
|
//- Collect matrices from other processors
|
||||||
void gatherMatrices
|
void gatherMatrices
|
||||||
@ -195,7 +214,6 @@ class GAMGSolver
|
|||||||
// Agglomeration information
|
// Agglomeration information
|
||||||
const labelList& procAgglomMap,
|
const labelList& procAgglomMap,
|
||||||
const List<int>& agglomProcIDs,
|
const List<int>& agglomProcIDs,
|
||||||
label masterComm,
|
|
||||||
|
|
||||||
const label levelI,
|
const label levelI,
|
||||||
|
|
||||||
@ -205,6 +223,14 @@ class GAMGSolver
|
|||||||
FieldField<Field, scalar>& allInterfaceIntCoeffs,
|
FieldField<Field, scalar>& allInterfaceIntCoeffs,
|
||||||
PtrList<lduInterfaceField>& allPrimitiveInterfaces,
|
PtrList<lduInterfaceField>& allPrimitiveInterfaces,
|
||||||
lduInterfaceFieldPtrsList& allInterfaces
|
lduInterfaceFieldPtrsList& allInterfaces
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Agglomerate processor matrices
|
||||||
|
void procAgglomerateMatrix
|
||||||
|
(
|
||||||
|
const labelList& procAgglomMap,
|
||||||
|
const List<int>& agglomProcIDs,
|
||||||
|
const label levelI
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Interpolate the correction after injected prolongation
|
//- Interpolate the correction after injected prolongation
|
||||||
@ -229,6 +255,7 @@ class GAMGSolver
|
|||||||
scalarField& field,
|
scalarField& field,
|
||||||
scalarField& Acf,
|
scalarField& Acf,
|
||||||
const lduMatrix& A,
|
const lduMatrix& A,
|
||||||
|
const int comm,
|
||||||
const FieldField<Field, scalar>& interfaceLevelBouCoeffs,
|
const FieldField<Field, scalar>& interfaceLevelBouCoeffs,
|
||||||
const lduInterfaceFieldPtrsList& interfaceLevel,
|
const lduInterfaceFieldPtrsList& interfaceLevel,
|
||||||
const scalarField& source,
|
const scalarField& source,
|
||||||
|
|||||||
@ -30,27 +30,179 @@ License
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::GAMGSolver::agglomerateMatrix(const label fineLevelIndex)
|
void Foam::GAMGSolver::agglomerateMatrix
|
||||||
|
(
|
||||||
|
const label fineLevelIndex,
|
||||||
|
const lduMesh& coarseMesh,
|
||||||
|
const lduInterfacePtrsList& coarseMeshInterfaces
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// Get fine matrix
|
// Get fine matrix
|
||||||
const lduMatrix& fineMatrix = matrixLevel(fineLevelIndex);
|
const lduMatrix& fineMatrix = matrixLevel(fineLevelIndex);
|
||||||
|
|
||||||
// Set the coarse level matrix
|
if (UPstream::myProcNo(fineMatrix.mesh().comm()) != -1)
|
||||||
matrixLevels_.set
|
{
|
||||||
(
|
const label nCoarseFaces = agglomeration_.nFaces(fineLevelIndex);
|
||||||
fineLevelIndex,
|
const label nCoarseCells = agglomeration_.nCells(fineLevelIndex);
|
||||||
new lduMatrix(agglomeration_.meshLevel(fineLevelIndex + 1))
|
|
||||||
);
|
|
||||||
lduMatrix& coarseMatrix = matrixLevels_[fineLevelIndex];
|
|
||||||
|
|
||||||
// Get face restriction map for current level
|
|
||||||
const labelList& faceRestrictAddr =
|
|
||||||
agglomeration_.faceRestrictAddressing(fineLevelIndex);
|
|
||||||
|
|
||||||
// Coarse matrix diagonal initialised by restricting the finer mesh diagonal
|
|
||||||
scalarField& coarseDiag = coarseMatrix.diag();
|
|
||||||
agglomeration_.restrictField(coarseDiag, fineMatrix.diag(), fineLevelIndex);
|
|
||||||
|
|
||||||
|
Pout<< "agglomerateMatrix : I have fine mesh:"
|
||||||
|
<< fineMatrix.mesh().lduAddr().size()
|
||||||
|
<< " at fine level:" << fineLevelIndex
|
||||||
|
<< " constricting to coarse cells:"
|
||||||
|
<< nCoarseCells
|
||||||
|
<< " coarse nFaces:" << nCoarseFaces << endl;
|
||||||
|
|
||||||
|
// Set the coarse level matrix
|
||||||
|
matrixLevels_.set
|
||||||
|
(
|
||||||
|
fineLevelIndex,
|
||||||
|
new lduMatrix(coarseMesh)
|
||||||
|
);
|
||||||
|
lduMatrix& coarseMatrix = matrixLevels_[fineLevelIndex];
|
||||||
|
|
||||||
|
|
||||||
|
// Coarse matrix diagonal initialised by restricting the finer mesh
|
||||||
|
// diagonal. Note that we size with the cached coarse nCells and not
|
||||||
|
// the actual coarseMesh size since this might be dummy when processor
|
||||||
|
// agglomerating.
|
||||||
|
scalarField& coarseDiag = coarseMatrix.diag(nCoarseCells);
|
||||||
|
|
||||||
|
agglomeration_.restrictField
|
||||||
|
(
|
||||||
|
coarseDiag,
|
||||||
|
fineMatrix.diag(),
|
||||||
|
fineLevelIndex,
|
||||||
|
false // no processor agglomeration
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get reference to fine-level interfaces
|
||||||
|
const lduInterfaceFieldPtrsList& fineInterfaces =
|
||||||
|
interfaceLevel(fineLevelIndex);
|
||||||
|
|
||||||
|
// Create coarse-level interfaces
|
||||||
|
interfaceLevels_.set
|
||||||
|
(
|
||||||
|
fineLevelIndex,
|
||||||
|
new lduInterfaceFieldPtrsList(fineInterfaces.size())
|
||||||
|
);
|
||||||
|
|
||||||
|
lduInterfaceFieldPtrsList& coarseInterfaces =
|
||||||
|
interfaceLevels_[fineLevelIndex];
|
||||||
|
|
||||||
|
// Set coarse-level boundary coefficients
|
||||||
|
interfaceLevelsBouCoeffs_.set
|
||||||
|
(
|
||||||
|
fineLevelIndex,
|
||||||
|
new FieldField<Field, scalar>(fineInterfaces.size())
|
||||||
|
);
|
||||||
|
FieldField<Field, scalar>& coarseInterfaceBouCoeffs =
|
||||||
|
interfaceLevelsBouCoeffs_[fineLevelIndex];
|
||||||
|
|
||||||
|
// Set coarse-level internal coefficients
|
||||||
|
interfaceLevelsIntCoeffs_.set
|
||||||
|
(
|
||||||
|
fineLevelIndex,
|
||||||
|
new FieldField<Field, scalar>(fineInterfaces.size())
|
||||||
|
);
|
||||||
|
FieldField<Field, scalar>& coarseInterfaceIntCoeffs =
|
||||||
|
interfaceLevelsIntCoeffs_[fineLevelIndex];
|
||||||
|
|
||||||
|
// Add the coarse level
|
||||||
|
agglomerateInterfaceCoefficients
|
||||||
|
(
|
||||||
|
fineLevelIndex,
|
||||||
|
coarseMeshInterfaces,
|
||||||
|
coarseInterfaces,
|
||||||
|
coarseInterfaceBouCoeffs,
|
||||||
|
coarseInterfaceIntCoeffs
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Get face restriction map for current level
|
||||||
|
const labelList& faceRestrictAddr =
|
||||||
|
agglomeration_.faceRestrictAddressing(fineLevelIndex);
|
||||||
|
const boolList& faceFlipMap =
|
||||||
|
agglomeration_.faceFlipMap(fineLevelIndex);
|
||||||
|
|
||||||
|
// Check if matrix is asymetric and if so agglomerate both upper
|
||||||
|
// and lower coefficients ...
|
||||||
|
if (fineMatrix.hasLower())
|
||||||
|
{
|
||||||
|
// Get off-diagonal matrix coefficients
|
||||||
|
const scalarField& fineUpper = fineMatrix.upper();
|
||||||
|
const scalarField& fineLower = fineMatrix.lower();
|
||||||
|
|
||||||
|
// Coarse matrix upper coefficients. Note passed in size
|
||||||
|
scalarField& coarseUpper = coarseMatrix.upper(nCoarseFaces);
|
||||||
|
scalarField& coarseLower = coarseMatrix.lower(nCoarseFaces);
|
||||||
|
|
||||||
|
forAll(faceRestrictAddr, fineFacei)
|
||||||
|
{
|
||||||
|
label cFace = faceRestrictAddr[fineFacei];
|
||||||
|
|
||||||
|
if (cFace >= 0)
|
||||||
|
{
|
||||||
|
// Check the orientation of the fine-face relative to the
|
||||||
|
// coarse face it is being agglomerated into
|
||||||
|
if (!faceFlipMap[fineFacei])
|
||||||
|
{
|
||||||
|
coarseUpper[cFace] += fineUpper[fineFacei];
|
||||||
|
coarseLower[cFace] += fineLower[fineFacei];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coarseUpper[cFace] += fineLower[fineFacei];
|
||||||
|
coarseLower[cFace] += fineUpper[fineFacei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add the fine face coefficients into the diagonal.
|
||||||
|
coarseDiag[-1 - cFace] +=
|
||||||
|
fineUpper[fineFacei] + fineLower[fineFacei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // ... Otherwise it is symmetric so agglomerate just the upper
|
||||||
|
{
|
||||||
|
// Get off-diagonal matrix coefficients
|
||||||
|
const scalarField& fineUpper = fineMatrix.upper();
|
||||||
|
|
||||||
|
// Coarse matrix upper coefficients
|
||||||
|
scalarField& coarseUpper = coarseMatrix.upper(nCoarseFaces);
|
||||||
|
|
||||||
|
forAll(faceRestrictAddr, fineFacei)
|
||||||
|
{
|
||||||
|
label cFace = faceRestrictAddr[fineFacei];
|
||||||
|
|
||||||
|
if (cFace >= 0)
|
||||||
|
{
|
||||||
|
coarseUpper[cFace] += fineUpper[fineFacei];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add the fine face coefficient into the diagonal.
|
||||||
|
coarseDiag[-1 - cFace] += 2*fineUpper[fineFacei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//XXXXX
|
||||||
|
// Agglomerate only the interface coefficients.
|
||||||
|
void Foam::GAMGSolver::agglomerateInterfaceCoefficients
|
||||||
|
(
|
||||||
|
const label fineLevelIndex,
|
||||||
|
const lduInterfacePtrsList& coarseMeshInterfaces,
|
||||||
|
lduInterfaceFieldPtrsList& coarseInterfaces,
|
||||||
|
FieldField<Field, scalar>& coarseInterfaceBouCoeffs,
|
||||||
|
FieldField<Field, scalar>& coarseInterfaceIntCoeffs
|
||||||
|
) const
|
||||||
|
{
|
||||||
// Get reference to fine-level interfaces
|
// Get reference to fine-level interfaces
|
||||||
const lduInterfaceFieldPtrsList& fineInterfaces =
|
const lduInterfaceFieldPtrsList& fineInterfaces =
|
||||||
interfaceLevel(fineLevelIndex);
|
interfaceLevel(fineLevelIndex);
|
||||||
@ -63,34 +215,12 @@ void Foam::GAMGSolver::agglomerateMatrix(const label fineLevelIndex)
|
|||||||
const FieldField<Field, scalar>& fineInterfaceIntCoeffs =
|
const FieldField<Field, scalar>& fineInterfaceIntCoeffs =
|
||||||
interfaceIntCoeffsLevel(fineLevelIndex);
|
interfaceIntCoeffsLevel(fineLevelIndex);
|
||||||
|
|
||||||
|
const labelListList& patchFineToCoarse =
|
||||||
|
agglomeration_.patchFaceRestrictAddressing(fineLevelIndex);
|
||||||
|
|
||||||
// Create coarse-level interfaces
|
const labelList& nPatchFaces =
|
||||||
interfaceLevels_.set
|
agglomeration_.nPatchFaces(fineLevelIndex);
|
||||||
(
|
|
||||||
fineLevelIndex,
|
|
||||||
new lduInterfaceFieldPtrsList(fineInterfaces.size())
|
|
||||||
);
|
|
||||||
|
|
||||||
lduInterfaceFieldPtrsList& coarseInterfaces =
|
|
||||||
interfaceLevels_[fineLevelIndex];
|
|
||||||
|
|
||||||
// Set coarse-level boundary coefficients
|
|
||||||
interfaceLevelsBouCoeffs_.set
|
|
||||||
(
|
|
||||||
fineLevelIndex,
|
|
||||||
new FieldField<Field, scalar>(fineInterfaces.size())
|
|
||||||
);
|
|
||||||
FieldField<Field, scalar>& coarseInterfaceBouCoeffs =
|
|
||||||
interfaceLevelsBouCoeffs_[fineLevelIndex];
|
|
||||||
|
|
||||||
// Set coarse-level internal coefficients
|
|
||||||
interfaceLevelsIntCoeffs_.set
|
|
||||||
(
|
|
||||||
fineLevelIndex,
|
|
||||||
new FieldField<Field, scalar>(fineInterfaces.size())
|
|
||||||
);
|
|
||||||
FieldField<Field, scalar>& coarseInterfaceIntCoeffs =
|
|
||||||
interfaceLevelsIntCoeffs_[fineLevelIndex];
|
|
||||||
|
|
||||||
// Add the coarse level
|
// Add the coarse level
|
||||||
forAll(fineInterfaces, inti)
|
forAll(fineInterfaces, inti)
|
||||||
@ -100,7 +230,7 @@ void Foam::GAMGSolver::agglomerateMatrix(const label fineLevelIndex)
|
|||||||
const GAMGInterface& coarseInterface =
|
const GAMGInterface& coarseInterface =
|
||||||
refCast<const GAMGInterface>
|
refCast<const GAMGInterface>
|
||||||
(
|
(
|
||||||
agglomeration_.interfaceLevel(fineLevelIndex + 1)[inti]
|
coarseMeshInterfaces[inti]
|
||||||
);
|
);
|
||||||
|
|
||||||
coarseInterfaces.set
|
coarseInterfaces.set
|
||||||
@ -113,97 +243,31 @@ void Foam::GAMGSolver::agglomerateMatrix(const label fineLevelIndex)
|
|||||||
).ptr()
|
).ptr()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const labelList& faceRestrictAddressing = patchFineToCoarse[inti];
|
||||||
|
|
||||||
coarseInterfaceBouCoeffs.set
|
coarseInterfaceBouCoeffs.set
|
||||||
(
|
(
|
||||||
inti,
|
inti,
|
||||||
coarseInterface.agglomerateCoeffs(fineInterfaceBouCoeffs[inti])
|
new scalarField(nPatchFaces[inti], 0.0)
|
||||||
|
);
|
||||||
|
agglomeration_.restrictField
|
||||||
|
(
|
||||||
|
coarseInterfaceBouCoeffs[inti],
|
||||||
|
fineInterfaceBouCoeffs[inti],
|
||||||
|
faceRestrictAddressing
|
||||||
);
|
);
|
||||||
|
|
||||||
coarseInterfaceIntCoeffs.set
|
coarseInterfaceIntCoeffs.set
|
||||||
(
|
(
|
||||||
inti,
|
inti,
|
||||||
coarseInterface.agglomerateCoeffs(fineInterfaceIntCoeffs[inti])
|
new scalarField(nPatchFaces[inti], 0.0)
|
||||||
|
);
|
||||||
|
agglomeration_.restrictField
|
||||||
|
(
|
||||||
|
coarseInterfaceIntCoeffs[inti],
|
||||||
|
fineInterfaceIntCoeffs[inti],
|
||||||
|
faceRestrictAddressing
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Check if matrix is asymetric and if so agglomerate both upper and lower
|
|
||||||
// coefficients ...
|
|
||||||
if (fineMatrix.hasLower())
|
|
||||||
{
|
|
||||||
// Get off-diagonal matrix coefficients
|
|
||||||
const scalarField& fineUpper = fineMatrix.upper();
|
|
||||||
const scalarField& fineLower = fineMatrix.lower();
|
|
||||||
|
|
||||||
// Coarse matrix upper coefficients
|
|
||||||
scalarField& coarseUpper = coarseMatrix.upper();
|
|
||||||
scalarField& coarseLower = coarseMatrix.lower();
|
|
||||||
|
|
||||||
const labelList& restrictAddr =
|
|
||||||
agglomeration_.restrictAddressing(fineLevelIndex);
|
|
||||||
|
|
||||||
const labelUList& l = fineMatrix.lduAddr().lowerAddr();
|
|
||||||
const labelUList& cl = coarseMatrix.lduAddr().lowerAddr();
|
|
||||||
const labelUList& cu = coarseMatrix.lduAddr().upperAddr();
|
|
||||||
|
|
||||||
forAll(faceRestrictAddr, fineFacei)
|
|
||||||
{
|
|
||||||
label cFace = faceRestrictAddr[fineFacei];
|
|
||||||
|
|
||||||
if (cFace >= 0)
|
|
||||||
{
|
|
||||||
// Check the orientation of the fine-face relative to the
|
|
||||||
// coarse face it is being agglomerated into
|
|
||||||
if (cl[cFace] == restrictAddr[l[fineFacei]])
|
|
||||||
{
|
|
||||||
coarseUpper[cFace] += fineUpper[fineFacei];
|
|
||||||
coarseLower[cFace] += fineLower[fineFacei];
|
|
||||||
}
|
|
||||||
else if (cu[cFace] == restrictAddr[l[fineFacei]])
|
|
||||||
{
|
|
||||||
coarseUpper[cFace] += fineLower[fineFacei];
|
|
||||||
coarseLower[cFace] += fineUpper[fineFacei];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"GAMGSolver::agglomerateMatrix(const label)"
|
|
||||||
) << "Inconsistent addressing between "
|
|
||||||
"fine and coarse grids"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Add the fine face coefficients into the diagonal.
|
|
||||||
coarseDiag[-1 - cFace] +=
|
|
||||||
fineUpper[fineFacei] + fineLower[fineFacei];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // ... Otherwise it is symmetric so agglomerate just the upper
|
|
||||||
{
|
|
||||||
// Get off-diagonal matrix coefficients
|
|
||||||
const scalarField& fineUpper = fineMatrix.upper();
|
|
||||||
|
|
||||||
// Coarse matrix upper coefficients
|
|
||||||
scalarField& coarseUpper = coarseMatrix.upper();
|
|
||||||
|
|
||||||
forAll(faceRestrictAddr, fineFacei)
|
|
||||||
{
|
|
||||||
label cFace = faceRestrictAddr[fineFacei];
|
|
||||||
|
|
||||||
if (cFace >= 0)
|
|
||||||
{
|
|
||||||
coarseUpper[cFace] += fineUpper[fineFacei];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Add the fine face coefficient into the diagonal.
|
|
||||||
coarseDiag[-1 - cFace] += 2*fineUpper[fineFacei];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,7 +419,6 @@ void Foam::GAMGSolver::procAgglomerateMatrix
|
|||||||
// Agglomeration information
|
// Agglomeration information
|
||||||
const labelList& procAgglomMap,
|
const labelList& procAgglomMap,
|
||||||
const List<int>& agglomProcIDs,
|
const List<int>& agglomProcIDs,
|
||||||
label masterComm,
|
|
||||||
|
|
||||||
const label levelI,
|
const label levelI,
|
||||||
|
|
||||||
@ -365,7 +428,7 @@ void Foam::GAMGSolver::procAgglomerateMatrix
|
|||||||
FieldField<Field, scalar>& allInterfaceIntCoeffs,
|
FieldField<Field, scalar>& allInterfaceIntCoeffs,
|
||||||
PtrList<lduInterfaceField>& allPrimitiveInterfaces,
|
PtrList<lduInterfaceField>& allPrimitiveInterfaces,
|
||||||
lduInterfaceFieldPtrsList& allInterfaces
|
lduInterfaceFieldPtrsList& allInterfaces
|
||||||
)
|
) const
|
||||||
{
|
{
|
||||||
const lduMatrix& coarsestMatrix = matrixLevels_[levelI];
|
const lduMatrix& coarsestMatrix = matrixLevels_[levelI];
|
||||||
const lduInterfaceFieldPtrsList& coarsestInterfaces =
|
const lduInterfaceFieldPtrsList& coarsestInterfaces =
|
||||||
@ -387,15 +450,6 @@ void Foam::GAMGSolver::procAgglomerateMatrix
|
|||||||
Pout<< "procAgglomerateMatrix :" << " level:" << levelI << endl;
|
Pout<< "procAgglomerateMatrix :" << " level:" << levelI << endl;
|
||||||
|
|
||||||
|
|
||||||
agglomeration_.procAgglomerateLduAddressing
|
|
||||||
(
|
|
||||||
procAgglomMap,
|
|
||||||
agglomProcIDs,
|
|
||||||
masterComm,
|
|
||||||
levelI // coarsest level
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Gather all matrix coefficients onto agglomProcIDs[0]
|
// Gather all matrix coefficients onto agglomProcIDs[0]
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -439,12 +493,15 @@ void Foam::GAMGSolver::procAgglomerateMatrix
|
|||||||
Pout<< endl;
|
Pout<< endl;
|
||||||
|
|
||||||
|
|
||||||
const lduMesh& allMesh = agglomeration_.procMeshLevel(levelI);
|
//const lduMesh& allMesh = agglomeration_.procMeshLevel(levelI);
|
||||||
const labelList& cellOffsets = agglomeration_.cellOffsets(levelI);
|
const lduMesh& allMesh = agglomeration_.meshLevel(levelI+1);
|
||||||
const labelListList& faceMap = agglomeration_.faceMap(levelI);
|
const labelList& cellOffsets = agglomeration_.cellOffsets(levelI+1);
|
||||||
const labelListList& boundaryMap = agglomeration_.boundaryMap(levelI);
|
const labelListList& faceMap = agglomeration_.faceMap(levelI+1);
|
||||||
|
const labelListList& boundaryMap = agglomeration_.boundaryMap(levelI+1);
|
||||||
const labelListListList& boundaryFaceMap =
|
const labelListListList& boundaryFaceMap =
|
||||||
agglomeration_.boundaryFaceMap(levelI);
|
agglomeration_.boundaryFaceMap(levelI+1);
|
||||||
|
|
||||||
|
Pout<< "Agglomerating onto mesh:" << allMesh.info() << endl;
|
||||||
|
|
||||||
|
|
||||||
allMatrixPtr.reset(new lduMatrix(allMesh));
|
allMatrixPtr.reset(new lduMatrix(allMesh));
|
||||||
@ -740,4 +797,54 @@ Pout<< " from proc:" << procI << " interface:" << procIntI
|
|||||||
//XXXX
|
//XXXX
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::GAMGSolver::procAgglomerateMatrix
|
||||||
|
(
|
||||||
|
const labelList& procAgglomMap,
|
||||||
|
const List<int>& agglomProcIDs,
|
||||||
|
|
||||||
|
const label levelI
|
||||||
|
)
|
||||||
|
{
|
||||||
|
autoPtr<lduMatrix> allMatrixPtr;
|
||||||
|
autoPtr<FieldField<Field, scalar> > allInterfaceBouCoeffs
|
||||||
|
(
|
||||||
|
new FieldField<Field, scalar>(0)
|
||||||
|
);
|
||||||
|
autoPtr<FieldField<Field, scalar> > allInterfaceIntCoeffs
|
||||||
|
(
|
||||||
|
new FieldField<Field, scalar>(0)
|
||||||
|
);
|
||||||
|
autoPtr<PtrList<lduInterfaceField> > allPrimitiveInterfaces
|
||||||
|
(
|
||||||
|
new PtrList<lduInterfaceField>(0)
|
||||||
|
);
|
||||||
|
autoPtr<lduInterfaceFieldPtrsList> allInterfaces
|
||||||
|
(
|
||||||
|
new lduInterfaceFieldPtrsList(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
procAgglomerateMatrix
|
||||||
|
(
|
||||||
|
// Agglomeration information
|
||||||
|
procAgglomMap,
|
||||||
|
agglomProcIDs,
|
||||||
|
|
||||||
|
levelI,
|
||||||
|
|
||||||
|
// Resulting matrix
|
||||||
|
allMatrixPtr,
|
||||||
|
allInterfaceBouCoeffs(),
|
||||||
|
allInterfaceIntCoeffs(),
|
||||||
|
allPrimitiveInterfaces(),
|
||||||
|
allInterfaces()
|
||||||
|
);
|
||||||
|
|
||||||
|
matrixLevels_.set(levelI, allMatrixPtr);
|
||||||
|
interfaceLevelsBouCoeffs_.set(levelI, allInterfaceBouCoeffs);
|
||||||
|
interfaceLevelsIntCoeffs_.set(levelI, allInterfaceIntCoeffs);
|
||||||
|
primitiveInterfaceLevels_.set(levelI, allPrimitiveInterfaces);
|
||||||
|
interfaceLevels_.set(levelI, allInterfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -33,6 +33,7 @@ void Foam::GAMGSolver::scale
|
|||||||
scalarField& field,
|
scalarField& field,
|
||||||
scalarField& Acf,
|
scalarField& Acf,
|
||||||
const lduMatrix& A,
|
const lduMatrix& A,
|
||||||
|
const int comm,
|
||||||
const FieldField<Field, scalar>& interfaceLevelBouCoeffs,
|
const FieldField<Field, scalar>& interfaceLevelBouCoeffs,
|
||||||
const lduInterfaceFieldPtrsList& interfaceLevel,
|
const lduInterfaceFieldPtrsList& interfaceLevel,
|
||||||
const scalarField& source,
|
const scalarField& source,
|
||||||
@ -58,11 +59,13 @@ void Foam::GAMGSolver::scale
|
|||||||
}
|
}
|
||||||
|
|
||||||
vector2D scalingVector(scalingFactorNum, scalingFactorDenom);
|
vector2D scalingVector(scalingFactorNum, scalingFactorDenom);
|
||||||
matrix().mesh().reduce
|
//A.mesh().reduce
|
||||||
(
|
//(
|
||||||
scalingVector,
|
// scalingVector,
|
||||||
sumOp<vector2D>()
|
// sumOp<vector2D>()
|
||||||
);
|
//);
|
||||||
|
Foam::reduce(scalingVector, sumOp<vector2D>(), Pstream::msgType(), comm);
|
||||||
|
|
||||||
scalar sf = scalingVector.x()/stabilise(scalingVector.y(), VSMALL);
|
scalar sf = scalingVector.x()/stabilise(scalingVector.y(), VSMALL);
|
||||||
|
|
||||||
if (debug >= 2)
|
if (debug >= 2)
|
||||||
|
|||||||
@ -142,8 +142,8 @@ void Foam::GAMGSolver::Vcycle
|
|||||||
|
|
||||||
const label coarsestLevel = matrixLevels_.size() - 1;
|
const label coarsestLevel = matrixLevels_.size() - 1;
|
||||||
|
|
||||||
// Restrict finest grid residual for the next level up
|
// Restrict finest grid residual for the next level up.
|
||||||
agglomeration_.restrictField(coarseSources[0], finestResidual, 0);
|
agglomeration_.restrictField(coarseSources[0], finestResidual, 0, true);
|
||||||
|
|
||||||
if (debug >= 2 && nPreSweeps_)
|
if (debug >= 2 && nPreSweeps_)
|
||||||
{
|
{
|
||||||
@ -154,66 +154,81 @@ void Foam::GAMGSolver::Vcycle
|
|||||||
// Residual restriction (going to coarser levels)
|
// Residual restriction (going to coarser levels)
|
||||||
for (label leveli = 0; leveli < coarsestLevel; leveli++)
|
for (label leveli = 0; leveli < coarsestLevel; leveli++)
|
||||||
{
|
{
|
||||||
// If the optional pre-smoothing sweeps are selected
|
Pout<< "Restriction for level:" << leveli << endl;
|
||||||
// smooth the coarse-grid field for the restriced source
|
|
||||||
if (nPreSweeps_)
|
if (coarseSources.set(leveli + 1))
|
||||||
{
|
{
|
||||||
coarseCorrFields[leveli] = 0.0;
|
// If the optional pre-smoothing sweeps are selected
|
||||||
|
// smooth the coarse-grid field for the restriced source
|
||||||
smoothers[leveli + 1].smooth
|
if (nPreSweeps_)
|
||||||
(
|
|
||||||
coarseCorrFields[leveli],
|
|
||||||
coarseSources[leveli],
|
|
||||||
cmpt,
|
|
||||||
min
|
|
||||||
(
|
|
||||||
nPreSweeps_ + preSweepsLevelMultiplier_*leveli,
|
|
||||||
maxPreSweeps_
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
scalarField::subField ACf
|
|
||||||
(
|
|
||||||
Apsi,
|
|
||||||
coarseCorrFields[leveli].size()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Scale coarse-grid correction field
|
|
||||||
// but not on the coarsest level because it evaluates to 1
|
|
||||||
if (scaleCorrection_ && leveli < coarsestLevel - 1)
|
|
||||||
{
|
{
|
||||||
scale
|
coarseCorrFields[leveli] = 0.0;
|
||||||
|
|
||||||
|
smoothers[leveli + 1].smooth
|
||||||
(
|
(
|
||||||
coarseCorrFields[leveli],
|
coarseCorrFields[leveli],
|
||||||
const_cast<scalarField&>(ACf.operator const scalarField&()),
|
coarseSources[leveli],
|
||||||
matrixLevels_[leveli],
|
cmpt,
|
||||||
|
min
|
||||||
|
(
|
||||||
|
nPreSweeps_ + preSweepsLevelMultiplier_*leveli,
|
||||||
|
maxPreSweeps_
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
scalarField::subField ACf
|
||||||
|
(
|
||||||
|
Apsi,
|
||||||
|
coarseCorrFields[leveli].size()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Scale coarse-grid correction field
|
||||||
|
// but not on the coarsest level because it evaluates to 1
|
||||||
|
if (scaleCorrection_ && leveli < coarsestLevel - 1)
|
||||||
|
{
|
||||||
|
int comm = matrixLevels_[leveli].mesh().comm();
|
||||||
|
|
||||||
|
scale
|
||||||
|
(
|
||||||
|
coarseCorrFields[leveli],
|
||||||
|
const_cast<scalarField&>
|
||||||
|
(
|
||||||
|
ACf.operator const scalarField&()
|
||||||
|
),
|
||||||
|
matrixLevels_[leveli],
|
||||||
|
comm,
|
||||||
|
interfaceLevelsBouCoeffs_[leveli],
|
||||||
|
interfaceLevels_[leveli],
|
||||||
|
coarseSources[leveli],
|
||||||
|
cmpt
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Correct the residual with the new solution
|
||||||
|
matrixLevels_[leveli].Amul
|
||||||
|
(
|
||||||
|
const_cast<scalarField&>
|
||||||
|
(
|
||||||
|
ACf.operator const scalarField&()
|
||||||
|
),
|
||||||
|
coarseCorrFields[leveli],
|
||||||
interfaceLevelsBouCoeffs_[leveli],
|
interfaceLevelsBouCoeffs_[leveli],
|
||||||
interfaceLevels_[leveli],
|
interfaceLevels_[leveli],
|
||||||
coarseSources[leveli],
|
|
||||||
cmpt
|
cmpt
|
||||||
);
|
);
|
||||||
|
|
||||||
|
coarseSources[leveli] -= ACf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Correct the residual with the new solution
|
// Residual is equal to source
|
||||||
matrixLevels_[leveli].Amul
|
agglomeration_.restrictField
|
||||||
(
|
(
|
||||||
const_cast<scalarField&>(ACf.operator const scalarField&()),
|
coarseSources[leveli + 1],
|
||||||
coarseCorrFields[leveli],
|
coarseSources[leveli],
|
||||||
interfaceLevelsBouCoeffs_[leveli],
|
leveli + 1,
|
||||||
interfaceLevels_[leveli],
|
true
|
||||||
cmpt
|
|
||||||
);
|
);
|
||||||
|
|
||||||
coarseSources[leveli] -= ACf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Residual is equal to source
|
|
||||||
agglomeration_.restrictField
|
|
||||||
(
|
|
||||||
coarseSources[leveli + 1],
|
|
||||||
coarseSources[leveli],
|
|
||||||
leveli + 1
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug >= 2 && nPreSweeps_)
|
if (debug >= 2 && nPreSweeps_)
|
||||||
@ -223,12 +238,15 @@ void Foam::GAMGSolver::Vcycle
|
|||||||
|
|
||||||
|
|
||||||
// Solve Coarsest level with either an iterative or direct solver
|
// Solve Coarsest level with either an iterative or direct solver
|
||||||
solveCoarsestLevel
|
if (coarseCorrFields.set(coarsestLevel))
|
||||||
(
|
{
|
||||||
coarseCorrFields[coarsestLevel],
|
Pout<< "Coarsest solve for level:" << coarsestLevel << endl;
|
||||||
coarseSources[coarsestLevel]
|
solveCoarsestLevel
|
||||||
);
|
(
|
||||||
|
coarseCorrFields[coarsestLevel],
|
||||||
|
coarseSources[coarsestLevel]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (debug >= 2)
|
if (debug >= 2)
|
||||||
{
|
{
|
||||||
@ -237,99 +255,141 @@ void Foam::GAMGSolver::Vcycle
|
|||||||
|
|
||||||
// Smoothing and prolongation of the coarse correction fields
|
// Smoothing and prolongation of the coarse correction fields
|
||||||
// (going to finer levels)
|
// (going to finer levels)
|
||||||
|
|
||||||
|
scalarField dummyField(0);
|
||||||
|
|
||||||
for (label leveli = coarsestLevel - 1; leveli >= 0; leveli--)
|
for (label leveli = coarsestLevel - 1; leveli >= 0; leveli--)
|
||||||
{
|
{
|
||||||
// Create a field for the pre-smoothed correction field
|
Pout<< "Smoothing and prolongation for level:" << leveli << endl;
|
||||||
// as a sub-field of the finestCorrection which is not
|
|
||||||
// currently being used
|
|
||||||
scalarField::subField preSmoothedCoarseCorrField
|
|
||||||
(
|
|
||||||
finestCorrection,
|
|
||||||
coarseCorrFields[leveli].size()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Only store the preSmoothedCoarseCorrField if pre-smoothing is used
|
if (coarseCorrFields.set(leveli))
|
||||||
if (nPreSweeps_)
|
|
||||||
{
|
{
|
||||||
preSmoothedCoarseCorrField.assign(coarseCorrFields[leveli]);
|
Pout<< "Prolonging from " << leveli + 1 << " up to "
|
||||||
}
|
<< leveli << endl;
|
||||||
|
//// Create a field for the pre-smoothed correction field
|
||||||
|
//// as a sub-field of the finestCorrection which is not
|
||||||
|
//// currently being used
|
||||||
|
//scalarField::subField preSmoothedCoarseCorrField
|
||||||
|
//(
|
||||||
|
// finestCorrection,
|
||||||
|
// coarseCorrFields[leveli].size()
|
||||||
|
//);
|
||||||
|
scalarField preSmoothedCoarseCorrField;
|
||||||
|
|
||||||
agglomeration_.prolongField
|
// Only store the preSmoothedCoarseCorrField if pre-smoothing is
|
||||||
(
|
// used
|
||||||
coarseCorrFields[leveli],
|
if (nPreSweeps_)
|
||||||
coarseCorrFields[leveli + 1],
|
{
|
||||||
leveli + 1
|
//preSmoothedCoarseCorrField.assign(coarseCorrFields[leveli]);
|
||||||
);
|
preSmoothedCoarseCorrField = coarseCorrFields[leveli];
|
||||||
|
}
|
||||||
|
|
||||||
// Create A.psi for this coarse level as a sub-field of Apsi
|
agglomeration_.prolongField
|
||||||
scalarField::subField ACf
|
|
||||||
(
|
|
||||||
Apsi,
|
|
||||||
coarseCorrFields[leveli].size()
|
|
||||||
);
|
|
||||||
|
|
||||||
scalarField& ACfRef =
|
|
||||||
const_cast<scalarField&>(ACf.operator const scalarField&());
|
|
||||||
|
|
||||||
if (interpolateCorrection_)
|
|
||||||
{
|
|
||||||
interpolate
|
|
||||||
(
|
(
|
||||||
coarseCorrFields[leveli],
|
coarseCorrFields[leveli],
|
||||||
ACfRef,
|
(
|
||||||
matrixLevels_[leveli],
|
coarseCorrFields.set(leveli + 1)
|
||||||
interfaceLevelsBouCoeffs_[leveli],
|
? coarseCorrFields[leveli + 1]
|
||||||
interfaceLevels_[leveli],
|
: dummyField // dummy value
|
||||||
coarseSources[leveli],
|
),
|
||||||
cmpt
|
leveli + 1,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Scale coarse-grid correction field
|
Pout<< "Doing stuff at level " << leveli << endl;
|
||||||
// but not on the coarsest level because it evaluates to 1
|
|
||||||
if (scaleCorrection_ && leveli < coarsestLevel - 1)
|
//// Create A.psi for this coarse level as a sub-field of Apsi
|
||||||
{
|
//scalarField::subField ACf
|
||||||
scale
|
//(
|
||||||
|
// Apsi,
|
||||||
|
// coarseCorrFields[leveli].size()
|
||||||
|
//);
|
||||||
|
//scalarField& ACfRef =
|
||||||
|
// const_cast<scalarField&>(ACf.operator const scalarField&());
|
||||||
|
scalarField ACfRef(coarseCorrFields[leveli].size());
|
||||||
|
|
||||||
|
|
||||||
|
if (interpolateCorrection_)
|
||||||
|
{
|
||||||
|
Pout<< "doing interpolate." << endl;
|
||||||
|
interpolate
|
||||||
|
(
|
||||||
|
coarseCorrFields[leveli],
|
||||||
|
ACfRef,
|
||||||
|
matrixLevels_[leveli],
|
||||||
|
interfaceLevelsBouCoeffs_[leveli],
|
||||||
|
interfaceLevels_[leveli],
|
||||||
|
coarseSources[leveli],
|
||||||
|
cmpt
|
||||||
|
);
|
||||||
|
Pout<< "done interpolate." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale coarse-grid correction field
|
||||||
|
// but not on the coarsest level because it evaluates to 1
|
||||||
|
if (scaleCorrection_ && leveli < coarsestLevel - 1)
|
||||||
|
{
|
||||||
|
//int comm =
|
||||||
|
//(
|
||||||
|
// matrixLevels_.set(leveli+1)
|
||||||
|
// ? matrixLevels_[leveli+1].mesh().comm()
|
||||||
|
// : matrixLevels_[leveli].mesh().comm()
|
||||||
|
//);
|
||||||
|
int comm = matrixLevels_[leveli].mesh().comm();
|
||||||
|
|
||||||
|
|
||||||
|
Pout<< "doing scale with comm:" << comm << endl;
|
||||||
|
scale
|
||||||
|
(
|
||||||
|
coarseCorrFields[leveli],
|
||||||
|
ACfRef,
|
||||||
|
matrixLevels_[leveli],
|
||||||
|
comm,
|
||||||
|
interfaceLevelsBouCoeffs_[leveli],
|
||||||
|
interfaceLevels_[leveli],
|
||||||
|
coarseSources[leveli],
|
||||||
|
cmpt
|
||||||
|
);
|
||||||
|
Pout<< "done scale with comm:" << comm << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only add the preSmoothedCoarseCorrField if pre-smoothing is
|
||||||
|
// used
|
||||||
|
if (nPreSweeps_)
|
||||||
|
{
|
||||||
|
coarseCorrFields[leveli] += preSmoothedCoarseCorrField;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pout<< "doing smooth." << endl;
|
||||||
|
smoothers[leveli + 1].smooth
|
||||||
(
|
(
|
||||||
coarseCorrFields[leveli],
|
coarseCorrFields[leveli],
|
||||||
ACfRef,
|
|
||||||
matrixLevels_[leveli],
|
|
||||||
interfaceLevelsBouCoeffs_[leveli],
|
|
||||||
interfaceLevels_[leveli],
|
|
||||||
coarseSources[leveli],
|
coarseSources[leveli],
|
||||||
cmpt
|
cmpt,
|
||||||
|
min
|
||||||
|
(
|
||||||
|
nPostSweeps_ + postSweepsLevelMultiplier_*leveli,
|
||||||
|
maxPostSweeps_
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
Pout<< "done smooth." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only add the preSmoothedCoarseCorrField if pre-smoothing is used
|
|
||||||
if (nPreSweeps_)
|
|
||||||
{
|
|
||||||
coarseCorrFields[leveli] += preSmoothedCoarseCorrField;
|
|
||||||
}
|
|
||||||
|
|
||||||
smoothers[leveli + 1].smooth
|
|
||||||
(
|
|
||||||
coarseCorrFields[leveli],
|
|
||||||
coarseSources[leveli],
|
|
||||||
cmpt,
|
|
||||||
min
|
|
||||||
(
|
|
||||||
nPostSweeps_ + postSweepsLevelMultiplier_*leveli,
|
|
||||||
maxPostSweeps_
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prolong the finest level correction
|
// Prolong the finest level correction
|
||||||
|
Pout<< "Doing Prolong to finest level" << endl;
|
||||||
agglomeration_.prolongField
|
agglomeration_.prolongField
|
||||||
(
|
(
|
||||||
finestCorrection,
|
finestCorrection,
|
||||||
coarseCorrFields[0],
|
coarseCorrFields[0],
|
||||||
0
|
0,
|
||||||
|
true //false // no proc agglomeration for now
|
||||||
);
|
);
|
||||||
|
Pout<< "Done Prolong to finest level" << endl;
|
||||||
|
|
||||||
if (interpolateCorrection_)
|
if (interpolateCorrection_)
|
||||||
{
|
{
|
||||||
|
Pout<< "doing interpolate on finest level" << endl;
|
||||||
interpolate
|
interpolate
|
||||||
(
|
(
|
||||||
finestCorrection,
|
finestCorrection,
|
||||||
@ -340,21 +400,26 @@ void Foam::GAMGSolver::Vcycle
|
|||||||
finestResidual,
|
finestResidual,
|
||||||
cmpt
|
cmpt
|
||||||
);
|
);
|
||||||
|
Pout<< "done interpolate on finest level" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scaleCorrection_)
|
if (scaleCorrection_)
|
||||||
{
|
{
|
||||||
// Scale the finest level correction
|
// Scale the finest level correction
|
||||||
|
int comm = matrix_.mesh().comm();
|
||||||
|
Pout<< "doing scale on finest level with comm:" << comm << endl;
|
||||||
scale
|
scale
|
||||||
(
|
(
|
||||||
finestCorrection,
|
finestCorrection,
|
||||||
Apsi,
|
Apsi,
|
||||||
matrix_,
|
matrix_,
|
||||||
|
comm,
|
||||||
interfaceBouCoeffs_,
|
interfaceBouCoeffs_,
|
||||||
interfaces_,
|
interfaces_,
|
||||||
finestResidual,
|
finestResidual,
|
||||||
cmpt
|
cmpt
|
||||||
);
|
);
|
||||||
|
Pout<< "done scale on finest level with comm:" << comm << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
forAll(psi, i)
|
forAll(psi, i)
|
||||||
@ -362,6 +427,7 @@ void Foam::GAMGSolver::Vcycle
|
|||||||
psi[i] += finestCorrection[i];
|
psi[i] += finestCorrection[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pout<< "Doing smooth on finest level" << endl;
|
||||||
smoothers[0].smooth
|
smoothers[0].smooth
|
||||||
(
|
(
|
||||||
psi,
|
psi,
|
||||||
@ -369,6 +435,7 @@ void Foam::GAMGSolver::Vcycle
|
|||||||
cmpt,
|
cmpt,
|
||||||
nFinestSweeps_
|
nFinestSweeps_
|
||||||
);
|
);
|
||||||
|
Pout<< "Done smooth on finest level" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -400,37 +467,47 @@ void Foam::GAMGSolver::initVcycle
|
|||||||
|
|
||||||
forAll(matrixLevels_, leveli)
|
forAll(matrixLevels_, leveli)
|
||||||
{
|
{
|
||||||
coarseCorrFields.set
|
if (agglomeration_.nCells(leveli) >= 0)
|
||||||
(
|
{
|
||||||
leveli,
|
label nCoarseCells = agglomeration_.nCells(leveli);
|
||||||
new scalarField
|
|
||||||
(
|
|
||||||
agglomeration_.meshLevel(leveli + 1).lduAddr().size()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
coarseSources.set
|
Pout<< "initVCucle level:" << leveli << " nCoarseCells:"
|
||||||
(
|
<< nCoarseCells << endl;
|
||||||
leveli,
|
|
||||||
new scalarField
|
|
||||||
(
|
|
||||||
agglomeration_.meshLevel(leveli + 1).lduAddr().size()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
smoothers.set
|
coarseSources.set(leveli, new scalarField(nCoarseCells));
|
||||||
(
|
|
||||||
leveli + 1,
|
//if (!matrixLevels_.set(leveli))
|
||||||
lduMatrix::smoother::New
|
//{
|
||||||
|
// coarseCorrFields.set(leveli, new scalarField(nCoarseCells));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matrixLevels_.set(leveli))
|
||||||
|
{
|
||||||
|
const lduMatrix& mat = matrixLevels_[leveli];
|
||||||
|
|
||||||
|
label nCoarseCells = mat.diag().size();
|
||||||
|
Pout<< "initVCucle level:" << leveli << " matrix size:"
|
||||||
|
<< nCoarseCells << endl;
|
||||||
|
|
||||||
|
coarseCorrFields.set(leveli, new scalarField(nCoarseCells));
|
||||||
|
//coarseCorrFields.set(leveli, new scalarField(nCoarseCells));
|
||||||
|
//coarseSources.set(leveli, new scalarField(nCoarseCells));
|
||||||
|
|
||||||
|
smoothers.set
|
||||||
(
|
(
|
||||||
fieldName_,
|
leveli + 1,
|
||||||
matrixLevels_[leveli],
|
lduMatrix::smoother::New
|
||||||
interfaceLevelsBouCoeffs_[leveli],
|
(
|
||||||
interfaceLevelsIntCoeffs_[leveli],
|
fieldName_,
|
||||||
interfaceLevels_[leveli],
|
matrixLevels_[leveli],
|
||||||
controlDict_
|
interfaceLevelsBouCoeffs_[leveli],
|
||||||
)
|
interfaceLevelsIntCoeffs_[leveli],
|
||||||
);
|
interfaceLevels_[leveli],
|
||||||
|
controlDict_
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,106 +533,111 @@ void Foam::GAMGSolver::solveCoarsestLevel
|
|||||||
coarsestCorrField = coarsestSource;
|
coarsestCorrField = coarsestSource;
|
||||||
coarsestLUMatrixPtr_->solve(coarsestCorrField);
|
coarsestLUMatrixPtr_->solve(coarsestCorrField);
|
||||||
}
|
}
|
||||||
else if (processorAgglomerate_)
|
//else if
|
||||||
{
|
//(
|
||||||
const labelList& agglomProcIDs = agglomeration_.agglomProcIDs
|
// agglomeration_.processorAgglomerate()
|
||||||
(
|
// && procMatrixLevels_.set(coarsestLevel)
|
||||||
coarsestLevel
|
//)
|
||||||
);
|
//{
|
||||||
|
// //const labelList& agglomProcIDs = agglomeration_.agglomProcIDs
|
||||||
|
// //(
|
||||||
|
// // coarsestLevel
|
||||||
scalarField allSource;
|
// //);
|
||||||
|
// //
|
||||||
globalIndex cellOffsets;
|
// //scalarField allSource;
|
||||||
if (Pstream::myProcNo(coarseComm) == agglomProcIDs[0])
|
// //
|
||||||
{
|
// //globalIndex cellOffsets;
|
||||||
cellOffsets.offsets() = agglomeration_.cellOffsets(coarsestLevel);
|
// //if (Pstream::myProcNo(coarseComm) == agglomProcIDs[0])
|
||||||
}
|
// //{
|
||||||
|
// // cellOffsets.offsets() =
|
||||||
cellOffsets.gather
|
// // agglomeration_.cellOffsets(coarsestLevel);
|
||||||
(
|
// //}
|
||||||
coarseComm,
|
// //
|
||||||
agglomProcIDs,
|
// //cellOffsets.gather
|
||||||
coarsestSource,
|
// //(
|
||||||
allSource
|
// // coarseComm,
|
||||||
);
|
// // agglomProcIDs,
|
||||||
|
// // coarsestSource,
|
||||||
scalarField allCorrField;
|
// // allSource
|
||||||
solverPerformance coarseSolverPerf;
|
// //);
|
||||||
|
// //
|
||||||
label solveComm = agglomeration_.procCommunicator(coarsestLevel);
|
// //scalarField allCorrField;
|
||||||
label oldWarn = UPstream::warnComm;
|
// //solverPerformance coarseSolverPerf;
|
||||||
UPstream::warnComm = solveComm;
|
//
|
||||||
|
// label solveComm = agglomeration_.procCommunicator(coarsestLevel);
|
||||||
if (Pstream::myProcNo(solveComm) != -1)
|
// label oldWarn = UPstream::warnComm;
|
||||||
{
|
// UPstream::warnComm = solveComm;
|
||||||
const lduMatrix& allMatrix = allMatrixPtr_();
|
//
|
||||||
|
//
|
||||||
allCorrField.setSize(allSource.size(), 0);
|
// coarsestCorrField = 0;
|
||||||
|
// solverPerformance coarseSolverPerf;
|
||||||
{
|
//
|
||||||
Pout<< "** Master:Solving on comm:" << solveComm
|
// if (Pstream::myProcNo(solveComm) != -1)
|
||||||
<< " with procs:" << UPstream::procID(solveComm) << endl;
|
// {
|
||||||
|
// const lduMatrix& allMatrix = procMatrixLevels_[coarsestLevel];
|
||||||
if (allMatrix.asymmetric())
|
//
|
||||||
{
|
// {
|
||||||
coarseSolverPerf = BICCG
|
// Pout<< "** Master:Solving on comm:" << solveComm
|
||||||
(
|
// << " with procs:" << UPstream::procID(solveComm) << endl;
|
||||||
"coarsestLevelCorr",
|
//
|
||||||
allMatrix,
|
// if (allMatrix.asymmetric())
|
||||||
allInterfaceBouCoeffs_,
|
// {
|
||||||
allInterfaceIntCoeffs_,
|
// coarseSolverPerf = BICCG
|
||||||
allInterfaces_,
|
// (
|
||||||
tolerance_,
|
// "coarsestLevelCorr",
|
||||||
relTol_
|
// allMatrix,
|
||||||
).solve
|
// procInterfaceLevelsBouCoeffs_[coarsestLevel],
|
||||||
(
|
// procInterfaceLevelsIntCoeffs_[coarsestLevel],
|
||||||
allCorrField,
|
// procInterfaceLevels_[coarsestLevel],
|
||||||
allSource
|
// tolerance_,
|
||||||
);
|
// relTol_
|
||||||
}
|
// ).solve
|
||||||
else
|
// (
|
||||||
{
|
// coarsestCorrField,
|
||||||
coarseSolverPerf = ICCG
|
// coarsestSource
|
||||||
(
|
// );
|
||||||
"coarsestLevelCorr",
|
// }
|
||||||
allMatrix,
|
// else
|
||||||
allInterfaceBouCoeffs_,
|
// {
|
||||||
allInterfaceIntCoeffs_,
|
// coarseSolverPerf = ICCG
|
||||||
allInterfaces_,
|
// (
|
||||||
tolerance_,
|
// "coarsestLevelCorr",
|
||||||
relTol_
|
// allMatrix,
|
||||||
).solve
|
// procInterfaceLevelsBouCoeffs_[coarsestLevel],
|
||||||
(
|
// procInterfaceLevelsIntCoeffs_[coarsestLevel],
|
||||||
allCorrField,
|
// procInterfaceLevels_[coarsestLevel],
|
||||||
allSource
|
// tolerance_,
|
||||||
);
|
// relTol_
|
||||||
}
|
// ).solve
|
||||||
}
|
// (
|
||||||
}
|
// coarsestCorrField,
|
||||||
|
// coarsestSource
|
||||||
UPstream::warnComm = oldWarn;
|
// );
|
||||||
Pout<< "done master solve." << endl;
|
// }
|
||||||
|
// }
|
||||||
// Scatter to all processors
|
// }
|
||||||
coarsestCorrField.setSize(coarsestSource.size());
|
//
|
||||||
cellOffsets.scatter
|
// UPstream::warnComm = oldWarn;
|
||||||
(
|
// Pout<< "done master solve." << endl;
|
||||||
coarseComm,
|
//
|
||||||
agglomProcIDs,
|
// //// Scatter to all processors
|
||||||
allCorrField,
|
// //coarsestCorrField.setSize(coarsestSource.size());
|
||||||
coarsestCorrField
|
// //cellOffsets.scatter
|
||||||
);
|
// //(
|
||||||
|
// // coarseComm,
|
||||||
if (debug >= 2)
|
// // agglomProcIDs,
|
||||||
{
|
// // allCorrField,
|
||||||
coarseSolverPerf.print(Info(coarseComm));
|
// // coarsestCorrField
|
||||||
}
|
// //);
|
||||||
|
//
|
||||||
Pout<< "procAgglom: coarsestSource :" << coarsestSource << endl;
|
// if (debug >= 2)
|
||||||
Pout<< "procAgglom: coarsestCorrField:" << coarsestCorrField << endl;
|
// {
|
||||||
}
|
// coarseSolverPerf.print(Info(coarseComm));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Pout<< "procAgglom: coarsestSource :" << coarsestSource << endl;
|
||||||
|
// Pout<< "procAgglom: coarsestCorrField:" << coarsestCorrField << endl;
|
||||||
|
//}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
coarsestCorrField = 0;
|
coarsestCorrField = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user