Fix tutorials: typo in tutorials/viscoelastic/viscoelasticFluidFoam/S-MDCPP/constant...
[OpenFOAM-1.6-ext.git] / src / finiteArea / faMatrices / faMatrix / faMatrixSolve.C
blob1066a0dea31f1587679f2d5f9fb79439a346ce58
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
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 Description
26     Finite-Area matrix basic solvers.
28 \*---------------------------------------------------------------------------*/
30 namespace Foam
33 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
35 // Set reference level for a component of the solution
36 // on a given patch face
37 template<class Type>
38 void faMatrix<Type>::setComponentReference
40     const label patchi,
41     const label facei,
42     const direction cmpt,
43     const scalar value
46     internalCoeffs_[patchi][facei].component(cmpt) +=
47         diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]];
49     boundaryCoeffs_[patchi][facei].component(cmpt) +=
50         diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]]*value;
54 template<class Type>
55 lduSolverPerformance faMatrix<Type>::solve(const dictionary& solverControls)
57     if (debug)
58     {
59         Info<< "faMatrix<Type>::solve(const dictionary&) : "
60                "solving faMatrix<Type>"
61             << endl;
62     }
64     lduSolverPerformance solverPerfVec
65     (
66         "faMatrix<Type>::solve",
67         psi_.name()
68     );
70     scalarField saveDiag = diag();
72     Field<Type> source = source_;
73     addBoundarySource(source);
75     // Make a copy of interfaces: no longer a reference
76     // HJ, 20/Nov/2007
77     lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces();
79     for (direction cmpt = 0; cmpt < Type::nComponents; cmpt++)
80     {
81         // copy field and source
83         scalarField psiCmpt = psi_.internalField().component(cmpt);
84         addBoundaryDiag(diag(), solvingComponent);
86         scalarField sourceCmpt = source.component(cmpt);
88         FieldField<Field, scalar> bouCoeffsCmpt
89         (
90             boundaryCoeffs_.component(cmpt)
91         );
93         FieldField<Field, scalar> intCoeffsCmpt
94         (
95             internalCoeffs_.component(cmpt)
96         );
98         lduSolverPerformance solverPerf;
100         // Solver call
101         solverPerf = lduSolver::New
102         (
103             psi_.name() + pTraits<Type>::componentNames[cmpt],
104             *this,
105             bouCoeffsCmpt,
106             intCoeffsCmpt,
107             interfaces,
108             solverControls
109         )->solve(psiCmpt, sourceCmpt, cmpt);
111         solverPerf.print();
113         if
114         (
115             solverPerf.initialResidual() > solverPerfVec.initialResidual()
116          && !solverPerf.singular()
117         )
118         {
119             solverPerfVec = solverPerf;
120         }
122         psi_.internalField().replace(cmpt, psiCmpt);
123         diag() = saveDiag;
124     }
126     psi_.correctBoundaryConditions();
128     return solverPerfVec;
132 template<class Type>
133 autoPtr<typename faMatrix<Type>::faSolver> faMatrix<Type>::solver()
135     return solver(psi_.mesh().solverDict(psi_.name()));
138 template<class Type>
139 lduSolverPerformance faMatrix<Type>::faSolver::solve()
141     return solve(psi_.mesh().solverDict(psi_.name()));
145 template<class Type>
146 lduSolverPerformance faMatrix<Type>::solve()
148     return solve(psi_.mesh().solverDict(psi_.name()));
152 // Return the matrix residual
153 template<class Type>
154 tmp<Field<Type> > faMatrix<Type>::residual() const
156     tmp<Field<Type> > tres(source_);
157     Field<Type>& res = tres();
159     addBoundarySource(res);
161     // Make a copy of interfaces: no longer a reference
162     // HJ, 20/Nov/2007
163     lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces();
165     // Loop over field components
166     for (direction cmpt = 0; cmpt < Type::nComponents; cmpt++)
167     {
168         scalarField psiCmpt = psi_.internalField().component(cmpt);
170         scalarField boundaryDiagCmpt(psi_.size(), 0.0);
171         addBoundaryDiag(boundaryDiagCmpt, cmpt);
173         FieldField<Field, scalar> bouCoeffsCmpt
174         (
175             boundaryCoeffs_.component(cmpt)
176         );
178         res.replace
179         (
180             cmpt,
181             lduMatrix::residual
182             (
183                 psiCmpt,
184                 res.component(cmpt) - boundaryDiagCmpt*psiCmpt,
185                 bouCoeffsCmpt,
186                 interfaces,
187                 cmpt
188             )
189         );
190     }
192     return tres;
196 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
198 } // End namespace Foam
200 // ************************************************************************* //