1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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
26 Finite-Area matrix basic solvers.
28 \*---------------------------------------------------------------------------*/
33 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
35 // Set reference level for a component of the solution
36 // on a given patch face
38 void faMatrix<Type>::setComponentReference
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;
55 lduSolverPerformance faMatrix<Type>::solve(const dictionary& solverControls)
59 Info<< "faMatrix<Type>::solve(const dictionary&) : "
60 "solving faMatrix<Type>"
64 lduSolverPerformance solverPerfVec
66 "faMatrix<Type>::solve",
70 scalarField saveDiag = diag();
72 Field<Type> source = source_;
73 addBoundarySource(source);
75 // Make a copy of interfaces: no longer a reference
77 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces();
79 for (direction cmpt = 0; cmpt < Type::nComponents; cmpt++)
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
90 boundaryCoeffs_.component(cmpt)
93 FieldField<Field, scalar> intCoeffsCmpt
95 internalCoeffs_.component(cmpt)
98 lduSolverPerformance solverPerf;
101 solverPerf = lduSolver::New
103 psi_.name() + pTraits<Type>::componentNames[cmpt],
109 )->solve(psiCmpt, sourceCmpt, cmpt);
115 solverPerf.initialResidual() > solverPerfVec.initialResidual()
116 && !solverPerf.singular()
119 solverPerfVec = solverPerf;
122 psi_.internalField().replace(cmpt, psiCmpt);
126 psi_.correctBoundaryConditions();
128 return solverPerfVec;
133 autoPtr<typename faMatrix<Type>::faSolver> faMatrix<Type>::solver()
135 return solver(psi_.mesh().solverDict(psi_.name()));
139 lduSolverPerformance faMatrix<Type>::faSolver::solve()
141 return solve(psi_.mesh().solverDict(psi_.name()));
146 lduSolverPerformance faMatrix<Type>::solve()
148 return solve(psi_.mesh().solverDict(psi_.name()));
152 // Return the matrix residual
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
163 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces();
165 // Loop over field components
166 for (direction cmpt = 0; cmpt < Type::nComponents; cmpt++)
168 scalarField psiCmpt = psi_.internalField().component(cmpt);
170 scalarField boundaryDiagCmpt(psi_.size(), 0.0);
171 addBoundaryDiag(boundaryDiagCmpt, cmpt);
173 FieldField<Field, scalar> bouCoeffsCmpt
175 boundaryCoeffs_.component(cmpt)
184 res.component(cmpt) - boundaryDiagCmpt*psiCmpt,
196 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
198 } // End namespace Foam
200 // ************************************************************************* //