1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "lduMatrix.H"
28 #include "diagonalSolver.H"
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 defineRunTimeSelectionTable(lduMatrix::solver, symMatrix);
35 defineRunTimeSelectionTable(lduMatrix::solver, asymMatrix);
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 Foam::autoPtr<Foam::lduMatrix::solver> Foam::lduMatrix::solver::New
43 const word& fieldName,
44 const lduMatrix& matrix,
45 const FieldField<Field, scalar>& interfaceBouCoeffs,
46 const FieldField<Field, scalar>& interfaceIntCoeffs,
47 const lduInterfaceFieldPtrsList& interfaces,
48 const dictionary& solverControls
51 word name(solverControls.lookup("solver"));
53 if (matrix.diagonal())
55 return autoPtr<lduMatrix::solver>
68 else if (matrix.symmetric())
70 symMatrixConstructorTable::iterator constructorIter =
71 symMatrixConstructorTablePtr_->find(name);
73 if (constructorIter == symMatrixConstructorTablePtr_->end())
77 "lduMatrix::solver::New", solverControls
78 ) << "Unknown symmetric matrix solver " << name << nl << nl
79 << "Valid symmetric matrix solvers are :" << endl
80 << symMatrixConstructorTablePtr_->toc()
81 << exit(FatalIOError);
84 return autoPtr<lduMatrix::solver>
97 else if (matrix.asymmetric())
99 asymMatrixConstructorTable::iterator constructorIter =
100 asymMatrixConstructorTablePtr_->find(name);
102 if (constructorIter == asymMatrixConstructorTablePtr_->end())
106 "lduMatrix::solver::New", solverControls
107 ) << "Unknown asymmetric matrix solver " << name << nl << nl
108 << "Valid asymmetric matrix solvers are :" << endl
109 << asymMatrixConstructorTablePtr_->toc()
110 << exit(FatalIOError);
113 return autoPtr<lduMatrix::solver>
130 "lduMatrix::solver::New", solverControls
131 ) << "cannot solve incomplete matrix, "
132 "no diagonal or off-diagonal coefficient"
133 << exit(FatalIOError);
135 return autoPtr<lduMatrix::solver>(NULL);
140 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
142 Foam::lduMatrix::solver::solver
144 const word& fieldName,
145 const lduMatrix& matrix,
146 const FieldField<Field, scalar>& interfaceBouCoeffs,
147 const FieldField<Field, scalar>& interfaceIntCoeffs,
148 const lduInterfaceFieldPtrsList& interfaces,
149 const dictionary& solverControls
152 fieldName_(fieldName),
154 interfaceBouCoeffs_(interfaceBouCoeffs),
155 interfaceIntCoeffs_(interfaceIntCoeffs),
156 interfaces_(interfaces),
157 controlDict_(solverControls)
163 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
165 void Foam::lduMatrix::solver::readControls()
167 maxIter_ = controlDict_.lookupOrDefault<label>("maxIter", 1000);
168 tolerance_ = controlDict_.lookupOrDefault<scalar>("tolerance", 1e-6);
169 relTol_ = controlDict_.lookupOrDefault<scalar>("relTol", 0);
173 void Foam::lduMatrix::solver::read(const dictionary& solverControls)
175 controlDict_ = solverControls;
180 Foam::scalar Foam::lduMatrix::solver::normFactor
182 const scalarField& psi,
183 const scalarField& source,
184 const scalarField& Apsi,
185 scalarField& tmpField
188 // --- Calculate A dot reference value of psi
189 matrix_.sumA(tmpField, interfaceBouCoeffs_, interfaces_);
190 tmpField *= gAverage(psi);
192 return gSum(mag(Apsi - tmpField) + mag(source - tmpField)) + matrix_.small_;
194 // At convergence this simpler method is equivalent to the above
195 // return 2*gSumMag(source) + matrix_.small_;
199 // ************************************************************************* //