/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template void Foam::fvMatrix::setComponentReference ( const label patchi, const label facei, const direction cmpt, const scalar value ) { if (psi_.needReference()) { if (Pstream::master()) { internalCoeffs_[patchi][facei].component(cmpt) += diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]]; boundaryCoeffs_[patchi][facei].component(cmpt) += diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]] *value; } } } template Foam::lduMatrix::solverPerformance Foam::fvMatrix::solve ( const dictionary& solverControls ) { if (debug) { Info<< "fvMatrix::solve(const dictionary& solverControls) : " "solving fvMatrix" << endl; } GeometricField& psi = const_cast&>(psi_); lduMatrix::solverPerformance solverPerfVec ( "fvMatrix::solve", psi.name() ); scalarField saveDiag = diag(); Field source = source_; // At this point include the boundary source from the coupled boundaries. // This is corrected for the implict part by updateMatrixInterfaces within // the component loop. addBoundarySource(source); typename Type::labelType validComponents ( pow ( psi.mesh().solutionD(), pTraits, Type::rank>::type>::zero ) ); for (direction cmpt=0; cmpt bouCoeffsCmpt ( boundaryCoeffs_.component(cmpt) ); FieldField intCoeffsCmpt ( internalCoeffs_.component(cmpt) ); lduInterfaceFieldPtrsList interfaces = psi.boundaryField().interfaces(); // Use the initMatrixInterfaces and updateMatrixInterfaces to correct // bouCoeffsCmpt for the explicit part of the coupled boundary // conditions initMatrixInterfaces ( bouCoeffsCmpt, interfaces, psiCmpt, sourceCmpt, cmpt ); updateMatrixInterfaces ( bouCoeffsCmpt, interfaces, psiCmpt, sourceCmpt, cmpt ); lduMatrix::solverPerformance solverPerf; // Solver call solverPerf = lduMatrix::solver::New ( psi.name() + pTraits::componentNames[cmpt], *this, bouCoeffsCmpt, intCoeffsCmpt, interfaces, solverControls )->solve(psiCmpt, sourceCmpt, cmpt); solverPerf.print(); solverPerfVec = max(solverPerfVec, solverPerf); solverPerfVec.solverName() = solverPerf.solverName(); psi.internalField().replace(cmpt, psiCmpt); diag() = saveDiag; } psi.correctBoundaryConditions(); psi.mesh().setSolverPerformance(psi.name(), solverPerfVec); return solverPerfVec; } template Foam::autoPtr::fvSolver> Foam::fvMatrix::solver() { return solver ( psi_.mesh().solverDict ( psi_.select ( psi_.mesh().data::lookupOrDefault("finalIteration", false) ) ) ); } template Foam::lduMatrix::solverPerformance Foam::fvMatrix::fvSolver::solve() { return solve ( psi_.mesh().solverDict ( psi_.select ( psi_.mesh().data::lookupOrDefault("finalIteration", false) ) ) ); } template Foam::lduMatrix::solverPerformance Foam::fvMatrix::solve() { return solve ( psi_.mesh().solverDict ( psi_.select ( psi_.mesh().data::lookupOrDefault("finalIteration", false) ) ) ); } template Foam::tmp > Foam::fvMatrix::residual() const { tmp > tres(source_); Field& res = tres(); addBoundarySource(res); // Loop over field components for (direction cmpt=0; cmpt bouCoeffsCmpt ( boundaryCoeffs_.component(cmpt) ); res.replace ( cmpt, lduMatrix::residual ( psiCmpt, res.component(cmpt) - boundaryDiagCmpt*psiCmpt, bouCoeffsCmpt, psi_.boundaryField().interfaces(), cmpt ) ); } return tres; } // ************************************************************************* //