initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / matrices / lduMatrix / lduMatrix / lduMatrixSolver.C
blobcb17295a3ef73853e0c63fcc3481c70f883fdbca
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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 * * * * * * * * * * * * * //
32 namespace Foam
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())
54     {
55         return autoPtr<lduMatrix::solver>
56         (
57             new diagonalSolver
58             (
59                 fieldName,
60                 matrix,
61                 interfaceBouCoeffs,
62                 interfaceIntCoeffs,
63                 interfaces,
64                 solverControls
65             )
66         );
67     }
68     else if (matrix.symmetric())
69     {
70         symMatrixConstructorTable::iterator constructorIter =
71             symMatrixConstructorTablePtr_->find(name);
73         if (constructorIter == symMatrixConstructorTablePtr_->end())
74         {
75             FatalIOErrorIn
76             (
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);
82         }
84         return autoPtr<lduMatrix::solver>
85         (
86             constructorIter()
87             (
88                 fieldName,
89                 matrix,
90                 interfaceBouCoeffs,
91                 interfaceIntCoeffs,
92                 interfaces,
93                 solverControls
94             )
95         );
96     }
97     else if (matrix.asymmetric())
98     {
99         asymMatrixConstructorTable::iterator constructorIter =
100             asymMatrixConstructorTablePtr_->find(name);
102         if (constructorIter == asymMatrixConstructorTablePtr_->end())
103         {
104             FatalIOErrorIn
105             (
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);
111         }
113         return autoPtr<lduMatrix::solver>
114         (
115             constructorIter()
116             (
117                 fieldName,
118                 matrix,
119                 interfaceBouCoeffs,
120                 interfaceIntCoeffs,
121                 interfaces,
122                 solverControls
123             )
124         );
125     }
126     else
127     {
128         FatalIOErrorIn
129         (
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);
136     }
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),
153     matrix_(matrix),
154     interfaceBouCoeffs_(interfaceBouCoeffs),
155     interfaceIntCoeffs_(interfaceIntCoeffs),
156     interfaces_(interfaces),
157     controlDict_(solverControls)
159     readControls();
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;
176     readControls();
180 Foam::scalar Foam::lduMatrix::solver::normFactor
182     const scalarField& psi,
183     const scalarField& source,
184     const scalarField& Apsi,
185     scalarField& tmpField
186 ) const
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 // ************************************************************************* //