Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 template<class Type>
00029 void Foam::fvMatrix<Type>::setComponentReference
00030 (
00031 const label patchi,
00032 const label facei,
00033 const direction cmpt,
00034 const scalar value
00035 )
00036 {
00037 if (psi_.needReference())
00038 {
00039 if (Pstream::master())
00040 {
00041 internalCoeffs_[patchi][facei].component(cmpt) +=
00042 diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]];
00043
00044 boundaryCoeffs_[patchi][facei].component(cmpt) +=
00045 diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]]
00046 *value;
00047 }
00048 }
00049 }
00050
00051
00052 template<class Type>
00053 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve
00054 (
00055 const dictionary& solverControls
00056 )
00057 {
00058 if (debug)
00059 {
00060 Info<< "fvMatrix<Type>::solve(const dictionary& solverControls) : "
00061 "solving fvMatrix<Type>"
00062 << endl;
00063 }
00064
00065 lduMatrix::solverPerformance solverPerfVec
00066 (
00067 "fvMatrix<Type>::solve",
00068 psi_.name()
00069 );
00070
00071 scalarField saveDiag = diag();
00072
00073 Field<Type> source = source_;
00074
00075
00076
00077
00078 addBoundarySource(source);
00079
00080 typename Type::labelType validComponents
00081 (
00082 pow
00083 (
00084 psi_.mesh().solutionD(),
00085 pTraits<typename powProduct<Vector<label>, Type::rank>::type>::zero
00086 )
00087 );
00088
00089 for(direction cmpt=0; cmpt<Type::nComponents; cmpt++)
00090 {
00091 if (validComponents[cmpt] == -1) continue;
00092
00093
00094
00095 scalarField psiCmpt = psi_.internalField().component(cmpt);
00096 addBoundaryDiag(diag(), cmpt);
00097
00098 scalarField sourceCmpt = source.component(cmpt);
00099
00100 FieldField<Field, scalar> bouCoeffsCmpt
00101 (
00102 boundaryCoeffs_.component(cmpt)
00103 );
00104
00105 FieldField<Field, scalar> intCoeffsCmpt
00106 (
00107 internalCoeffs_.component(cmpt)
00108 );
00109
00110 lduInterfaceFieldPtrsList interfaces =
00111 psi_.boundaryField().interfaces();
00112
00113
00114
00115
00116 initMatrixInterfaces
00117 (
00118 bouCoeffsCmpt,
00119 interfaces,
00120 psiCmpt,
00121 sourceCmpt,
00122 cmpt
00123 );
00124
00125 updateMatrixInterfaces
00126 (
00127 bouCoeffsCmpt,
00128 interfaces,
00129 psiCmpt,
00130 sourceCmpt,
00131 cmpt
00132 );
00133
00134 lduMatrix::solverPerformance solverPerf;
00135
00136
00137 solverPerf = lduMatrix::solver::New
00138 (
00139 psi_.name() + pTraits<Type>::componentNames[cmpt],
00140 *this,
00141 bouCoeffsCmpt,
00142 intCoeffsCmpt,
00143 interfaces,
00144 solverControls
00145 )->solve(psiCmpt, sourceCmpt, cmpt);
00146
00147 solverPerf.print();
00148
00149 if
00150 (
00151 solverPerf.initialResidual() > solverPerfVec.initialResidual()
00152 && !solverPerf.singular()
00153 )
00154 {
00155 solverPerfVec = solverPerf;
00156 }
00157
00158 psi_.internalField().replace(cmpt, psiCmpt);
00159 diag() = saveDiag;
00160 }
00161
00162 psi_.correctBoundaryConditions();
00163
00164 return solverPerfVec;
00165 }
00166
00167
00168 template<class Type>
00169 Foam::autoPtr<typename Foam::fvMatrix<Type>::fvSolver>
00170 Foam::fvMatrix<Type>::solver()
00171 {
00172 return solver(psi_.mesh().solverDict(psi_.name()));
00173 }
00174
00175 template<class Type>
00176 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::fvSolver::solve()
00177 {
00178 return solve(fvMat_.psi_.mesh().solverDict(fvMat_.psi_.name()));
00179 }
00180
00181
00182 template<class Type>
00183 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve()
00184 {
00185 return solve(psi_.mesh().solverDict(psi_.name()));
00186 }
00187
00188
00189 template<class Type>
00190 Foam::tmp<Foam::Field<Type> > Foam::fvMatrix<Type>::residual() const
00191 {
00192 tmp<Field<Type> > tres(source_);
00193 Field<Type>& res = tres();
00194
00195 addBoundarySource(res);
00196
00197
00198 for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
00199 {
00200 scalarField psiCmpt = psi_.internalField().component(cmpt);
00201
00202 scalarField boundaryDiagCmpt(psi_.size(), 0.0);
00203 addBoundaryDiag(boundaryDiagCmpt, cmpt);
00204
00205 FieldField<Field, scalar> bouCoeffsCmpt
00206 (
00207 boundaryCoeffs_.component(cmpt)
00208 );
00209
00210 res.replace
00211 (
00212 cmpt,
00213 lduMatrix::residual
00214 (
00215 psiCmpt,
00216 res.component(cmpt) - boundaryDiagCmpt*psiCmpt,
00217 bouCoeffsCmpt,
00218 psi_.boundaryField().interfaces(),
00219 cmpt
00220 )
00221 );
00222 }
00223
00224 return tres;
00225 }
00226
00227
00228