1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 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 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
30 void Foam::fvMatrix<Type>::setComponentReference
38 if (psi_.needReference())
40 if (Pstream::master())
42 internalCoeffs_[patchi][facei].component(cmpt) +=
43 diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]];
45 boundaryCoeffs_[patchi][facei].component(cmpt) +=
46 diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]]
54 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve
56 Istream& solverControls
61 Info<< "fvMatrix<Type>::solve(Istream& solverControls) : "
62 "solving fvMatrix<Type>"
66 lduMatrix::solverPerformance solverPerfVec
68 "fvMatrix<Type>::solve",
72 scalarField saveDiag = diag();
74 Field<Type> source = source_;
76 // At this point include the boundary source from the coupled boundaries.
77 // This is corrected for the implict part by updateMatrixInterfaces within
78 // the component loop.
79 addBoundarySource(source);
81 typename Type::labelType validComponents
85 psi_.mesh().directions(),
86 pTraits<typename powProduct<Vector<label>, Type::rank>::type>::zero
90 for(direction cmpt=0; cmpt<Type::nComponents; cmpt++)
92 if (validComponents[cmpt] == -1) continue;
94 // copy field and source
96 scalarField psiCmpt = psi_.internalField().component(cmpt);
97 addBoundaryDiag(diag(), cmpt);
99 scalarField sourceCmpt = source.component(cmpt);
101 FieldField<Field, scalar> bouCoeffsCmpt
103 boundaryCoeffs_.component(cmpt)
106 FieldField<Field, scalar> intCoeffsCmpt
108 internalCoeffs_.component(cmpt)
111 lduInterfaceFieldPtrsList interfaces =
112 psi_.boundaryField().interfaces();
114 // Use the initMatrixInterfaces and updateMatrixInterfaces to correct
115 // bouCoeffsCmpt for the explicit part of the coupled boundary
126 updateMatrixInterfaces
135 lduMatrix::solverPerformance solverPerf;
138 solverPerf = lduMatrix::solver::New
140 psi_.name() + pTraits<Type>::componentNames[cmpt],
145 solverControls.rewind()
146 )->solve(psiCmpt, sourceCmpt, cmpt);
152 solverPerf.initialResidual() > solverPerfVec.initialResidual()
153 && !solverPerf.singular()
156 solverPerfVec = solverPerf;
159 psi_.internalField().replace(cmpt, psiCmpt);
163 psi_.correctBoundaryConditions();
165 return solverPerfVec;
170 Foam::autoPtr<typename Foam::fvMatrix<Type>::fvSolver>
171 Foam::fvMatrix<Type>::solver()
173 return solver(psi_.mesh().solver(psi_.name()));
177 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::fvSolver::solve()
179 return solve(psi_.mesh().solver(psi_.name()));
184 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve()
186 return solve(psi_.mesh().solver(psi_.name()));
191 Foam::tmp<Foam::Field<Type> > Foam::fvMatrix<Type>::residual() const
193 tmp<Field<Type> > tres(source_);
194 Field<Type>& res = tres();
196 addBoundarySource(res);
198 // Loop over field components
199 for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
201 scalarField psiCmpt = psi_.internalField().component(cmpt);
203 scalarField boundaryDiagCmpt(psi_.size(), 0.0);
204 addBoundaryDiag(boundaryDiagCmpt, cmpt);
206 FieldField<Field, scalar> bouCoeffsCmpt
208 boundaryCoeffs_.component(cmpt)
217 res.component(cmpt) - boundaryDiagCmpt*psiCmpt,
219 psi_.boundaryField().interfaces(),
229 // ************************************************************************* //