diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C index 3662f1c354..18b0f90269 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C @@ -24,6 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "GAMGSolver.H" +#include "GAMGInterface.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -74,20 +75,212 @@ Foam::GAMGSolver::GAMGSolver interpolateCorrection_(false), scaleCorrection_(matrix.symmetric()), directSolveCoarsest_(false), - processorAgglomerate_(false), agglomeration_(GAMGAgglomeration::New(matrix_, controlDict_)), matrixLevels_(agglomeration_.size()), interfaceLevels_(agglomeration_.size()), + primitiveInterfaceLevels_(agglomeration_.size()), interfaceLevelsBouCoeffs_(agglomeration_.size()), interfaceLevelsIntCoeffs_(agglomeration_.size()) { 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 dummyPrimMeshInterfaces + ( + fineMeshInterfaces.size() + ); + lduInterfacePtrsList dummyMeshInterfaces + ( + dummyPrimMeshInterfaces.size() + ); + forAll(fineMeshInterfaces, intI) + { + if (fineMeshInterfaces.set(intI)) + { + OStringStream os; + refCast + ( + 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& 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()) { @@ -119,117 +312,118 @@ Foam::GAMGSolver::GAMGSolver UPstream::warnComm = oldWarn; } - else if (processorAgglomerate_) + else if (agglomeration_.processorAgglomerate()) { - // Pick a level to processor agglomerate - label agglomLevel = matrixLevels_.size() - 1;//1; - - - // Get mesh and matrix at this level - const lduMatrix& levelMatrix = matrixLevels_[agglomLevel]; - const lduMesh& levelMesh = levelMatrix.mesh(); - - - label levelComm = levelMesh.comm(); - label oldWarn = UPstream::warnComm; - UPstream::warnComm = levelComm; - - Pout<< "Solve generic on mesh (level=" << agglomLevel - << ") using communicator " << levelComm << endl; - - // Processor restriction map: per processor the coarse processor - labelList procAgglomMap(UPstream::nProcs(levelComm)); - // Master processor - labelList masterProcs; - // Local processors that agglomerate. agglomProcIDs[0] is in - // masterProc. - List agglomProcIDs; - - { - procAgglomMap[0] = 0; - procAgglomMap[1] = 0; - procAgglomMap[2] = 1; - procAgglomMap[3] = 1; - - // Determine the master processors - Map