From 2385dbff25c0770ad612c8ddd57aece5c619e1c8 Mon Sep 17 00:00:00 2001 From: Henry <Henry> Date: Thu, 17 Jan 2013 09:50:03 +0000 Subject: [PATCH] GAMG: Add optional correction interpolate after prolongation --- src/OpenFOAM/Make/files | 3 +- .../lduMatrix/solvers/GAMG/GAMGSolver.C | 2 + .../lduMatrix/solvers/GAMG/GAMGSolver.H | 32 +++--- .../solvers/GAMG/GAMGSolverScalingFactor.C | 88 ----------------- .../lduMatrix/solvers/GAMG/GAMGSolverSolve.C | 99 ++++++++++--------- 5 files changed, 76 insertions(+), 148 deletions(-) delete mode 100644 src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverScalingFactor.C diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 03072a6f02c..dc8e946baaa 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -284,7 +284,8 @@ $(lduInterfaceFields)/cyclicLduInterfaceField/cyclicLduInterfaceField.C GAMG = $(lduMatrix)/solvers/GAMG $(GAMG)/GAMGSolver.C $(GAMG)/GAMGSolverAgglomerateMatrix.C -$(GAMG)/GAMGSolverScalingFactor.C +$(GAMG)/GAMGSolverInterpolate.C +$(GAMG)/GAMGSolverScale.C $(GAMG)/GAMGSolverSolve.C GAMGInterfaces = $(GAMG)/interfaces diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C index 7ae547c0bb3..a0ed11bb32b 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C @@ -71,6 +71,7 @@ Foam::GAMGSolver::GAMGSolver postSweepsLevelMultiplier_(1), maxPostSweeps_(4), nFinestSweeps_(2), + interpolateCorrection_(false), scaleCorrection_(matrix.symmetric()), directSolveCoarsest_(false), agglomeration_(GAMGAgglomeration::New(matrix_, controlDict_)), @@ -174,6 +175,7 @@ void Foam::GAMGSolver::readControls() ); controlDict_.readIfPresent("maxPostSweeps", maxPostSweeps_); controlDict_.readIfPresent("nFinestSweeps", nFinestSweeps_); + controlDict_.readIfPresent("interpolateCorrection", interpolateCorrection_); controlDict_.readIfPresent("scaleCorrection", scaleCorrection_); controlDict_.readIfPresent("directSolveCoarsest", directSolveCoarsest_); } diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H index c2aefbea16a..44e27cc9fc1 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H @@ -46,6 +46,8 @@ SourceFiles GAMGSolverCalcAgglomeration.C GAMGSolverMakeCoarseMatrix.C GAMGSolverOperations.C + GAMGSolverInterpolate.C + GAMGSolverScale.C GAMGSolverSolve.C \*---------------------------------------------------------------------------*/ @@ -97,6 +99,10 @@ class GAMGSolver //- Number of smoothing sweeps on finest mesh label nFinestSweeps_; + //- Choose if the corrections should be interpolated after injection. + // By default corrections are not interpolated. + bool interpolateCorrection_; + //- Choose if the corrections should be scaled. // By default corrections for symmetric matrices are scaled // but not for asymmetric matrices. @@ -154,32 +160,34 @@ class GAMGSolver //- Agglomerate coarse matrix void agglomerateMatrix(const label fineLevelIndex); - //- Calculate and return the scaling factor from Acf, coarseSource + //- Interpolate the correction after injected prolongation + void interpolate + ( + scalarField& psi, + scalarField& Apsi, + const lduMatrix& m, + const FieldField<Field, scalar>& interfaceBouCoeffs, + const lduInterfaceFieldPtrsList& interfaces, + const scalarField& source, + const direction cmpt + ) const; + + //- Calculate and apply the scaling factor from Acf, coarseSource // and coarseField. // At the same time do a Jacobi iteration on the coarseField using // the Acf provided after the coarseField values are used for the // scaling factor. - scalar scalingFactor + void scale ( scalarField& field, - const scalarField& source, - const scalarField& Acf, - const scalarField& D - ) const; - - //- Calculate Acf and calculate and return the scaling factor. - scalar scalingFactor - ( scalarField& Acf, const lduMatrix& A, - scalarField& field, const FieldField<Field, scalar>& interfaceLevelBouCoeffs, const lduInterfaceFieldPtrsList& interfaceLevel, const scalarField& source, const direction cmpt ) const; - //- Initialise the data structures for the V-cycle void initVcycle ( diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverScalingFactor.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverScalingFactor.C deleted file mode 100644 index 1df912f32bd..00000000000 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverScalingFactor.C +++ /dev/null @@ -1,88 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | -------------------------------------------------------------------------------- -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 <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "GAMGSolver.H" -#include "vector2D.H" - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -Foam::scalar Foam::GAMGSolver::scalingFactor -( - scalarField& field, - const scalarField& source, - const scalarField& Acf, - const scalarField& D -) const -{ - scalar scalingFactorNum = 0.0; - scalar scalingFactorDenom = 0.0; - - forAll(field, i) - { - scalingFactorNum += source[i]*field[i]; - scalingFactorDenom += Acf[i]*field[i]; - - // While the matrix-multiply done for the scaling it is - // possible to perform a point-Jacobi smoothing operation cheaply - field[i] += (source[i] - Acf[i])/D[i]; - } - - vector2D scalingVector(scalingFactorNum, scalingFactorDenom); - reduce(scalingVector, sumOp<vector2D>()); - return scalingVector.x()/stabilise(scalingVector.y(), VSMALL); -} - - -Foam::scalar Foam::GAMGSolver::scalingFactor -( - scalarField& Acf, - const lduMatrix& A, - scalarField& field, - const FieldField<Field, scalar>& interfaceLevelBouCoeffs, - const lduInterfaceFieldPtrsList& interfaceLevel, - const scalarField& source, - const direction cmpt -) const -{ - A.Amul - ( - Acf, - field, - interfaceLevelBouCoeffs, - interfaceLevel, - cmpt - ); - - return scalingFactor - ( - field, - source, - Acf, - A.diag() - ); -} - - -// ************************************************************************* // diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C index 25c8e6dbe56..ce2bf39f0cf 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C @@ -28,6 +28,7 @@ License #include "BICCG.H" #include "SubField.H" + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // Foam::solverPerformance Foam::GAMGSolver::solve @@ -173,23 +174,16 @@ void Foam::GAMGSolver::Vcycle // but not on the coarsest level because it evaluates to 1 if (scaleCorrection_ && leveli < coarsestLevel - 1) { - scalar sf = scalingFactor + scale ( + coarseCorrFields[leveli], const_cast<scalarField&>(ACf.operator const scalarField&()), matrixLevels_[leveli], - coarseCorrFields[leveli], interfaceLevelsBouCoeffs_[leveli], interfaceLevels_[leveli], coarseSources[leveli], cmpt ); - - if (debug >= 2) - { - Pout<< sf << " "; - } - - coarseCorrFields[leveli] *= sf; } // Correct the residual with the new solution @@ -246,7 +240,7 @@ void Foam::GAMGSolver::Vcycle coarseCorrFields[leveli].size() ); - // Only store the preSmoothedCoarseCorrField is pre-smoothing is used + // Only store the preSmoothedCoarseCorrField if pre-smoothing is used if (nPreSweeps_) { preSmoothedCoarseCorrField.assign(coarseCorrFields[leveli]); @@ -259,38 +253,47 @@ void Foam::GAMGSolver::Vcycle leveli + 1 ); - // Scale coarse-grid correction field - // 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 + ( + Apsi, + coarseCorrFields[leveli].size() + ); + + scalarField& ACfRef = + const_cast<scalarField&>(ACf.operator const scalarField&()); + + if (interpolateCorrection_) { - // Create A.psi for this coarse level as a sub-field of Apsi - scalarField::subField ACf + interpolate ( - Apsi, - coarseCorrFields[leveli].size() + coarseCorrFields[leveli], + ACfRef, + matrixLevels_[leveli], + interfaceLevelsBouCoeffs_[leveli], + interfaceLevels_[leveli], + coarseSources[leveli], + cmpt ); + } - scalar sf = scalingFactor + // Scale coarse-grid correction field + // but not on the coarsest level because it evaluates to 1 + if (scaleCorrection_ && leveli < coarsestLevel - 1) + { + scale ( - const_cast<scalarField&>(ACf.operator const scalarField&()), - matrixLevels_[leveli], coarseCorrFields[leveli], + ACfRef, + matrixLevels_[leveli], interfaceLevelsBouCoeffs_[leveli], interfaceLevels_[leveli], coarseSources[leveli], cmpt ); - - - if (debug >= 2) - { - Pout<< sf << " "; - } - - coarseCorrFields[leveli] *= sf; } - // Only add the preSmoothedCoarseCorrField is pre-smoothing is used + // Only add the preSmoothedCoarseCorrField if pre-smoothing is used if (nPreSweeps_) { coarseCorrFields[leveli] += preSmoothedCoarseCorrField; @@ -317,36 +320,38 @@ void Foam::GAMGSolver::Vcycle 0 ); - if (scaleCorrection_) + if (interpolateCorrection_) { - // Calculate finest level scaling factor - scalar fsf = scalingFactor + interpolate ( + finestCorrection, Apsi, matrix_, - finestCorrection, interfaceBouCoeffs_, interfaces_, finestResidual, cmpt ); + } - if (debug >= 2) - { - Pout<< fsf << endl; - } - - forAll(psi, i) - { - psi[i] += fsf*finestCorrection[i]; - } + if (scaleCorrection_) + { + // Scale the finest level correction + scale + ( + finestCorrection, + Apsi, + matrix_, + interfaceBouCoeffs_, + interfaces_, + finestResidual, + cmpt + ); } - else + + forAll(psi, i) { - forAll(psi, i) - { - psi[i] += finestCorrection[i]; - } + psi[i] += finestCorrection[i]; } smoothers[0].smooth -- GitLab