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 Tetrahedral Finite Element matrix basic solvers.
28 \*---------------------------------------------------------------------------*/
30 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 // * * * * * * * * * * * * * * * * Solvers * * * * * * * * * * * * * * * * * //
38 lduSolverPerformance tetFemMatrix<Type>::solve
40 const dictionary& solverControls
45 Info<< "tetFemMatrix<Type>::solve(const dictionary&) : "
46 "solving tetFemMatrix<Type>"
56 lduSolverPerformance solverPerfVec
58 "tetFemMatrix<Type>::solve",
62 // Add boundary source for gradient-type conditions
63 addBoundarySourceDiag();
65 // Store the boundary coefficients for insertion of boundary conditions
66 storeBoundaryCoeffs();
68 typename Type::labelType validComponents
72 psi_.mesh()().solutionD(),
73 pTraits<typename powProduct<Vector<label>, Type::rank>::type>::zero
77 // Make a copy of interfaces: no longer a reference
79 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces();
81 for (direction cmpt = 0; cmpt < Type::nComponents; cmpt++)
83 if (validComponents[cmpt] == -1) continue;
85 scalarField psiCmpt = psi_.internalField().component(cmpt);
86 scalarField sourceCmpt = source_.component(cmpt);
88 // Set component boundary conditions
89 setComponentBoundaryConditions(cmpt, psiCmpt, sourceCmpt);
91 // Add the coupling coefficients
94 addCouplingSource(sourceCmpt);
96 // Prepare for coupled interface update
97 FieldField<Field, scalar> coupledBouCoeffs
99 psi_.boundaryField().size()
102 FieldField<Field, scalar> coupledIntCoeffs
104 psi_.boundaryField().size()
107 forAll(psi_.boundaryField(), patchI)
109 const tetPolyPatchField<Type>& ptf = psi_.boundaryField()[patchI];
114 ptf.cutBouCoeffs(*this)
120 ptf.cutIntCoeffs(*this)
124 eliminateCouplingCoeffs();
126 scalarField res(psi_.size(), 0);
137 lduSolverPerformance solverPerf = lduSolver::New
139 psi_.name() + pTraits<Type>::componentNames[cmpt],
145 )->solve(psiCmpt, sourceCmpt, cmpt);
151 solverPerf.initialResidual() > solverPerfVec.initialResidual()
152 && !solverPerf.singular()
155 solverPerfVec = solverPerf;
158 psi_.internalField().replace(cmpt, psiCmpt);
165 Info<< "tetFemMatrix<Type>::solve : correcting boundary conditions"
169 psi_.correctBoundaryConditions();
171 return solverPerfVec;
176 lduSolverPerformance tetFemMatrix<Type>::solve()
178 return solve(psi_.mesh().solver(psi_.name()));
182 // Return the matrix residual
184 tmp<Field<Type> > tetFemMatrix<Type>::residual()
186 tmp<Field<Type> > tres(psi_.size());
188 // Store the boundary coefficients for insertion of boundary conditions
189 storeBoundaryCoeffs();
191 // Make a copy of interfaces: no longer a reference
193 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces();
195 // Loop over field components
196 for (direction cmpt = 0; cmpt < Type::nComponents; cmpt++)
198 scalarField PsiInternalCmpt = psi_.internalField().component(cmpt);
199 scalarField sourceCmpt = source_.component(cmpt);
201 setComponentBoundaryConditions(cmpt, PsiInternalCmpt, sourceCmpt);
203 // Add the coupling coefficients
205 addCouplingSource(sourceCmpt);
207 // Prepare for coupled interface update
208 FieldField<Field, scalar> coupledBouCoeffs(psi_.boundaryField().size());
210 forAll(psi_.boundaryField(), patchI)
212 const tetPolyPatchField<Type>& ptf = psi_.boundaryField()[patchI];
216 new scalarField(ptf.cutBouCoeffs(*this))
220 eliminateCouplingCoeffs();
227 psi_.internalField().component(cmpt),
242 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
244 } // End namespace Foam
246 // ************************************************************************* //