1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
25 Tetrahedral Finite Element matrix basic solvers.
27 \*---------------------------------------------------------------------------*/
29 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 // * * * * * * * * * * * * * * * * Solvers * * * * * * * * * * * * * * * * * //
37 lduSolverPerformance tetFemMatrix<Type>::solve
39 const dictionary& solverControls
44 Info<< "tetFemMatrix<Type>::solve(const dictionary&) : "
45 "solving tetFemMatrix<Type>"
55 lduSolverPerformance solverPerfVec
57 "tetFemMatrix<Type>::solve",
61 // Add boundary source for gradient-type conditions
62 addBoundarySourceDiag();
64 // Store the boundary coefficients for insertion of boundary conditions
65 storeBoundaryCoeffs();
67 typename Type::labelType validComponents
71 psi_.mesh()().solutionD(),
72 pTraits<typename powProduct<Vector<label>, Type::rank>::type>::zero
76 // Make a copy of interfaces: no longer a reference
78 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces();
80 for (direction cmpt = 0; cmpt < Type::nComponents; cmpt++)
82 if (validComponents[cmpt] == -1) continue;
84 scalarField psiCmpt = psi_.internalField().component(cmpt);
85 scalarField sourceCmpt = source_.component(cmpt);
87 // Set component boundary conditions
88 setComponentBoundaryConditions(cmpt, psiCmpt, sourceCmpt);
90 // Add the coupling coefficients
93 addCouplingSource(sourceCmpt);
95 // Prepare for coupled interface update
96 FieldField<Field, scalar> coupledBouCoeffs
98 psi_.boundaryField().size()
101 FieldField<Field, scalar> coupledIntCoeffs
103 psi_.boundaryField().size()
106 forAll(psi_.boundaryField(), patchI)
108 const tetPolyPatchField<Type>& ptf = psi_.boundaryField()[patchI];
113 ptf.cutBouCoeffs(*this)
119 ptf.cutIntCoeffs(*this)
123 eliminateCouplingCoeffs();
125 scalarField res(psi_.size(), 0);
136 lduSolverPerformance solverPerf = lduSolver::New
138 psi_.name() + pTraits<Type>::componentNames[cmpt],
144 )->solve(psiCmpt, sourceCmpt, cmpt);
150 solverPerf.initialResidual() > solverPerfVec.initialResidual()
151 && !solverPerf.singular()
154 solverPerfVec = solverPerf;
157 psi_.internalField().replace(cmpt, psiCmpt);
164 Info<< "tetFemMatrix<Type>::solve : correcting boundary conditions"
168 psi_.correctBoundaryConditions();
170 return solverPerfVec;
175 lduSolverPerformance tetFemMatrix<Type>::solve()
177 return solve(psi_.mesh().solutionDict().solver(psi_.name()));
181 // Return the matrix residual
183 tmp<Field<Type> > tetFemMatrix<Type>::residual()
185 tmp<Field<Type> > tres(psi_.size());
187 // Store the boundary coefficients for insertion of boundary conditions
188 storeBoundaryCoeffs();
190 // Make a copy of interfaces: no longer a reference
192 lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces();
194 // Loop over field components
195 for (direction cmpt = 0; cmpt < Type::nComponents; cmpt++)
197 scalarField PsiInternalCmpt = psi_.internalField().component(cmpt);
198 scalarField sourceCmpt = source_.component(cmpt);
200 setComponentBoundaryConditions(cmpt, PsiInternalCmpt, sourceCmpt);
202 // Add the coupling coefficients
204 addCouplingSource(sourceCmpt);
206 // Prepare for coupled interface update
207 FieldField<Field, scalar> coupledBouCoeffs(psi_.boundaryField().size());
209 forAll(psi_.boundaryField(), patchI)
211 const tetPolyPatchField<Type>& ptf = psi_.boundaryField()[patchI];
215 new scalarField(ptf.cutBouCoeffs(*this))
219 eliminateCouplingCoeffs();
226 psi_.internalField().component(cmpt),
241 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
243 } // End namespace Foam
245 // ************************************************************************* //