/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2021-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "GAMGSolver.H" #include "GAMGInterface.H" #include "PCG.H" #include "PBiCGStab.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { defineTypeNameAndDebug(GAMGSolver, 0); lduMatrix::solver::addsymMatrixConstructorToTable addGAMGSolverMatrixConstructorToTable_; lduMatrix::solver::addasymMatrixConstructorToTable addGAMGAsymSolverMatrixConstructorToTable_; } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::GAMGSolver::GAMGSolver ( const word& fieldName, const lduMatrix& matrix, const FieldField& interfaceBouCoeffs, const FieldField& interfaceIntCoeffs, const lduInterfaceFieldPtrsList& interfaces, const dictionary& solverControls ) : lduMatrix::solver ( fieldName, matrix, interfaceBouCoeffs, interfaceIntCoeffs, interfaces, solverControls ), // Default values for all controls // which may be overridden by those in controlDict nPreSweeps_(0), preSweepsLevelMultiplier_(1), maxPreSweeps_(4), nPostSweeps_(2), postSweepsLevelMultiplier_(1), maxPostSweeps_(4), nFinestSweeps_(2), cacheAgglomeration_(true), interpolateCorrection_(false), scaleCorrection_(matrix.symmetric()), directSolveCoarsest_(false), agglomeration_(GAMGAgglomeration::New(matrix_, controlDict_)), matrixLevels_(agglomeration_.size()), primitiveInterfaceLevels_(agglomeration_.size()), interfaceLevels_(agglomeration_.size()), interfaceLevelsBouCoeffs_(agglomeration_.size()), interfaceLevelsIntCoeffs_(agglomeration_.size()) { readControls(); if (agglomeration_.processorAgglomerate()) { forAll(agglomeration_, fineLevelIndex) { if (agglomeration_.hasMeshLevel(fineLevelIndex)) { if ( (fineLevelIndex+1) < agglomeration_.size() && agglomeration_.hasProcMesh(fineLevelIndex+1) ) { // 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() ); OCharStream os(IOstreamOption::BINARY); ISpanStream is(IOstreamOption::BINARY); forAll(fineMeshInterfaces, intI) { if (fineMeshInterfaces.set(intI)) { os.rewind(); refCast ( fineMeshInterfaces[intI] ).write(os); is.reset(os.view()); 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