1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "volFields.H"
27 #include "surfaceFields.H"
28 #include "calculatedFvPatchFields.H"
29 #include "zeroGradientFvPatchFields.H"
30 #include "coupledFvPatchFields.H"
31 #include "UIndirectList.H"
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 void Foam::fvMatrix<Type>::addToInternalField
39 const labelUList& addr,
40 const Field<Type2>& pf,
44 if (addr.size() != pf.size())
48 "fvMatrix<Type>::addToInternalField(const labelUList&, "
49 "const Field&, Field&)"
50 ) << "sizes of addressing and field are different"
56 intf[addr[faceI]] += pf[faceI];
63 void Foam::fvMatrix<Type>::addToInternalField
65 const labelUList& addr,
66 const tmp<Field<Type2> >& tpf,
70 addToInternalField(addr, tpf(), intf);
77 void Foam::fvMatrix<Type>::subtractFromInternalField
79 const labelUList& addr,
80 const Field<Type2>& pf,
84 if (addr.size() != pf.size())
88 "fvMatrix<Type>::addToInternalField(const labelUList&, "
89 "const Field&, Field&)"
90 ) << "sizes of addressing and field are different"
96 intf[addr[faceI]] -= pf[faceI];
102 template<class Type2>
103 void Foam::fvMatrix<Type>::subtractFromInternalField
105 const labelUList& addr,
106 const tmp<Field<Type2> >& tpf,
110 subtractFromInternalField(addr, tpf(), intf);
116 void Foam::fvMatrix<Type>::addBoundaryDiag
119 const direction solveCmpt
122 forAll(internalCoeffs_, patchI)
126 lduAddr().patchAddr(patchI),
127 internalCoeffs_[patchI].component(solveCmpt),
135 void Foam::fvMatrix<Type>::addCmptAvBoundaryDiag(scalarField& diag) const
137 forAll(internalCoeffs_, patchI)
141 lduAddr().patchAddr(patchI),
142 cmptAv(internalCoeffs_[patchI]),
150 void Foam::fvMatrix<Type>::addBoundarySource
156 forAll(psi_.boundaryField(), patchI)
158 const fvPatchField<Type>& ptf = psi_.boundaryField()[patchI];
159 const Field<Type>& pbc = boundaryCoeffs_[patchI];
163 addToInternalField(lduAddr().patchAddr(patchI), pbc, source);
167 tmp<Field<Type> > tpnf = ptf.patchNeighbourField();
168 const Field<Type>& pnf = tpnf();
170 const labelUList& addr = lduAddr().patchAddr(patchI);
174 source[addr[facei]] += cmptMultiply(pbc[facei], pnf[facei]);
182 template<template<class> class ListType>
183 void Foam::fvMatrix<Type>::setValuesFromList
185 const labelUList& cellLabels,
186 const ListType<Type>& values
189 const fvMesh& mesh = psi_.mesh();
191 const cellList& cells = mesh.cells();
192 const labelUList& own = mesh.owner();
193 const labelUList& nei = mesh.neighbour();
195 scalarField& Diag = diag();
199 GeometricField<Type, fvPatchField, volMesh>&
200 >(psi_).internalField();
202 forAll(cellLabels, i)
204 const label celli = cellLabels[i];
205 const Type& value = values[i];
208 source_[celli] = value*Diag[celli];
210 if (symmetric() || asymmetric())
212 const cell& c = cells[celli];
216 const label facei = c[j];
218 if (mesh.isInternalFace(facei))
222 if (celli == own[facei])
224 source_[nei[facei]] -= upper()[facei]*value;
228 source_[own[facei]] -= upper()[facei]*value;
231 upper()[facei] = 0.0;
235 if (celli == own[facei])
237 source_[nei[facei]] -= lower()[facei]*value;
241 source_[own[facei]] -= upper()[facei]*value;
244 upper()[facei] = 0.0;
245 lower()[facei] = 0.0;
250 label patchi = mesh.boundaryMesh().whichPatch(facei);
252 if (internalCoeffs_[patchi].size())
255 mesh.boundaryMesh()[patchi].whichFace(facei);
257 internalCoeffs_[patchi][patchFacei] =
260 boundaryCoeffs_[patchi][patchFacei] =
270 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
273 Foam::fvMatrix<Type>::fvMatrix
275 const GeometricField<Type, fvPatchField, volMesh>& psi,
276 const dimensionSet& ds
279 lduMatrix(psi.mesh()),
282 source_(psi.size(), pTraits<Type>::zero),
283 internalCoeffs_(psi.mesh().boundary().size()),
284 boundaryCoeffs_(psi.mesh().boundary().size()),
285 faceFluxCorrectionPtr_(NULL)
289 Info<< "fvMatrix<Type>(GeometricField<Type, fvPatchField, volMesh>&,"
290 " const dimensionSet&) : "
291 "constructing fvMatrix<Type> for field " << psi_.name()
295 // Initialise coupling coefficients
296 forAll(psi.mesh().boundary(), patchI)
303 psi.mesh().boundary()[patchI].size(),
313 psi.mesh().boundary()[patchI].size(),
319 // Update the boundary coefficients of psi without changing its event No.
320 GeometricField<Type, fvPatchField, volMesh>& psiRef =
321 const_cast<GeometricField<Type, fvPatchField, volMesh>&>(psi_);
323 label currentStatePsi = psiRef.eventNo();
324 psiRef.boundaryField().updateCoeffs();
325 psiRef.eventNo() = currentStatePsi;
330 Foam::fvMatrix<Type>::fvMatrix(const fvMatrix<Type>& fvm)
335 dimensions_(fvm.dimensions_),
336 source_(fvm.source_),
337 internalCoeffs_(fvm.internalCoeffs_),
338 boundaryCoeffs_(fvm.boundaryCoeffs_),
339 faceFluxCorrectionPtr_(NULL)
343 Info<< "fvMatrix<Type>::fvMatrix(const fvMatrix<Type>&) : "
344 << "copying fvMatrix<Type> for field " << psi_.name()
348 if (fvm.faceFluxCorrectionPtr_)
350 faceFluxCorrectionPtr_ = new
351 GeometricField<Type, fvsPatchField, surfaceMesh>
353 *(fvm.faceFluxCorrectionPtr_)
359 #ifdef ConstructFromTmp
361 Foam::fvMatrix<Type>::fvMatrix(const tmp<fvMatrix<Type> >& tfvm)
366 const_cast<fvMatrix<Type>&>(tfvm()),
370 dimensions_(tfvm().dimensions_),
373 const_cast<fvMatrix<Type>&>(tfvm()).source_,
378 const_cast<fvMatrix<Type>&>(tfvm()).internalCoeffs_,
383 const_cast<fvMatrix<Type>&>(tfvm()).boundaryCoeffs_,
386 faceFluxCorrectionPtr_(NULL)
390 Info<< "fvMatrix<Type>::fvMatrix(const tmp<fvMatrix<Type> >&) : "
391 << "copying fvMatrix<Type> for field " << psi_.name()
395 if (tfvm().faceFluxCorrectionPtr_)
399 faceFluxCorrectionPtr_ = tfvm().faceFluxCorrectionPtr_;
400 tfvm().faceFluxCorrectionPtr_ = NULL;
404 faceFluxCorrectionPtr_ = new
405 GeometricField<Type, fvsPatchField, surfaceMesh>
407 *(tfvm().faceFluxCorrectionPtr_)
418 Foam::fvMatrix<Type>::fvMatrix
420 const GeometricField<Type, fvPatchField, volMesh>& psi,
424 lduMatrix(psi.mesh()),
428 internalCoeffs_(psi.mesh().boundary().size()),
429 boundaryCoeffs_(psi.mesh().boundary().size()),
430 faceFluxCorrectionPtr_(NULL)
434 Info<< "fvMatrix<Type>"
435 "(GeometricField<Type, fvPatchField, volMesh>&, Istream&) : "
436 "constructing fvMatrix<Type> for field " << psi_.name()
440 // Initialise coupling coefficients
441 forAll(psi.mesh().boundary(), patchI)
448 psi.mesh().boundary()[patchI].size(),
458 psi.mesh().boundary()[patchI].size(),
468 Foam::fvMatrix<Type>::~fvMatrix()
472 Info<< "fvMatrix<Type>::~fvMatrix<Type>() : "
473 << "destroying fvMatrix<Type> for field " << psi_.name()
477 if (faceFluxCorrectionPtr_)
479 delete faceFluxCorrectionPtr_;
484 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
487 void Foam::fvMatrix<Type>::setValues
489 const labelUList& cellLabels,
490 const UList<Type>& values
493 this->setValuesFromList(cellLabels, values);
498 void Foam::fvMatrix<Type>::setValues
500 const labelUList& cellLabels,
501 const UIndirectList<Type>& values
504 this->setValuesFromList(cellLabels, values);
509 void Foam::fvMatrix<Type>::setReference
513 const bool forceReference
516 if ((forceReference || psi_.needReference()) && celli >= 0)
518 source()[celli] += diag()[celli]*value;
519 diag()[celli] += diag()[celli];
525 void Foam::fvMatrix<Type>::relax(const scalar alpha)
534 InfoIn("fvMatrix<Type>::relax(const scalar alpha)")
535 << "Relaxing " << psi_.name() << " by " << alpha
539 Field<Type>& S = source();
540 scalarField& D = diag();
542 // Store the current unrelaxed diagonal for use in updating the source
545 // Calculate the sum-mag off-diagonal from the interior faces
546 scalarField sumOff(D.size(), 0.0);
547 sumMagOffDiag(sumOff);
549 // Handle the boundary contributions to the diagonal
550 forAll(psi_.boundaryField(), patchI)
552 const fvPatchField<Type>& ptf = psi_.boundaryField()[patchI];
556 const labelUList& pa = lduAddr().patchAddr(patchI);
557 Field<Type>& iCoeffs = internalCoeffs_[patchI];
561 const Field<Type>& pCoeffs = boundaryCoeffs_[patchI];
563 // For coupled boundaries add the diagonal and
564 // off-diagonal contributions
567 D[pa[face]] += component(iCoeffs[face], 0);
568 sumOff[pa[face]] += mag(component(pCoeffs[face], 0));
573 // For non-coupled boundaries subtract the diagonal
574 // contribution off-diagonal sum which avoids having to remove
575 // it from the diagonal later.
576 // Also add the source contribution from the relaxation
579 Type iCoeff0 = iCoeffs[face];
580 iCoeffs[face] = cmptMag(iCoeffs[face]);
581 sumOff[pa[face]] -= cmptMin(iCoeffs[face]);
582 iCoeffs[face] /= alpha;
584 cmptMultiply(iCoeffs[face] - iCoeff0, psi_[pa[face]]);
590 // Ensure the matrix is diagonally dominant...
596 // Now remove the diagonal contribution from coupled boundaries
597 forAll(psi_.boundaryField(), patchI)
599 const fvPatchField<Type>& ptf = psi_.boundaryField()[patchI];
603 const labelUList& pa = lduAddr().patchAddr(patchI);
604 Field<Type>& iCoeffs = internalCoeffs_[patchI];
610 D[pa[face]] -= component(iCoeffs[face], 0);
616 // Finally add the relaxation contribution to the source.
617 S += (D - D0)*psi_.internalField();
622 void Foam::fvMatrix<Type>::relax()
624 word name = psi_.select
626 psi_.mesh().data::template lookupOrDefault<bool>
627 ("finalIteration", false)
630 if (psi_.mesh().relax(name))
632 relax(psi_.mesh().relaxationFactor(name));
638 void Foam::fvMatrix<Type>::boundaryManipulate
640 typename GeometricField<Type, fvPatchField, volMesh>::
641 GeometricBoundaryField& bFields
644 forAll(bFields, patchI)
646 bFields[patchI].manipulateMatrix(*this);
652 Foam::tmp<Foam::scalarField> Foam::fvMatrix<Type>::D() const
654 tmp<scalarField> tdiag(new scalarField(diag()));
655 addCmptAvBoundaryDiag(tdiag());
661 Foam::tmp<Foam::Field<Type> > Foam::fvMatrix<Type>::DD() const
663 tmp<Field<Type> > tdiag(pTraits<Type>::one*diag());
665 forAll(psi_.boundaryField(), patchI)
667 const fvPatchField<Type>& ptf = psi_.boundaryField()[patchI];
669 if (!ptf.coupled() && ptf.size())
673 lduAddr().patchAddr(patchI),
674 internalCoeffs_[patchI],
685 Foam::tmp<Foam::volScalarField> Foam::fvMatrix<Type>::A() const
687 tmp<volScalarField> tAphi
693 "A("+psi_.name()+')',
700 dimensions_/psi_.dimensions()/dimVol,
701 zeroGradientFvPatchScalarField::typeName
705 tAphi().internalField() = D()/psi_.mesh().V();
706 tAphi().correctBoundaryConditions();
713 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
714 Foam::fvMatrix<Type>::H() const
716 tmp<GeometricField<Type, fvPatchField, volMesh> > tHphi
718 new GeometricField<Type, fvPatchField, volMesh>
722 "H("+psi_.name()+')',
730 zeroGradientFvPatchScalarField::typeName
733 GeometricField<Type, fvPatchField, volMesh>& Hphi = tHphi();
735 // Loop over field components
736 for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
738 scalarField psiCmpt(psi_.internalField().component(cmpt));
740 scalarField boundaryDiagCmpt(psi_.size(), 0.0);
741 addBoundaryDiag(boundaryDiagCmpt, cmpt);
742 boundaryDiagCmpt.negate();
743 addCmptAvBoundaryDiag(boundaryDiagCmpt);
745 Hphi.internalField().replace(cmpt, boundaryDiagCmpt*psiCmpt);
748 Hphi.internalField() += lduMatrix::H(psi_.internalField()) + source_;
749 addBoundarySource(Hphi.internalField());
751 Hphi.internalField() /= psi_.mesh().V();
752 Hphi.correctBoundaryConditions();
754 typename Type::labelType validComponents
758 psi_.mesh().solutionD(),
759 pTraits<typename powProduct<Vector<label>, Type::rank>::type>::zero
763 for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
765 if (validComponents[cmpt] == -1)
770 dimensionedScalar("0", Hphi.dimensions(), 0.0)
780 Foam::tmp<Foam::volScalarField> Foam::fvMatrix<Type>::H1() const
782 tmp<volScalarField> tH1
795 dimensions_/(dimVol*psi_.dimensions()),
796 zeroGradientFvPatchScalarField::typeName
799 volScalarField& H1_ = tH1();
801 // Loop over field components
803 for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
805 scalarField psiCmpt(psi_.internalField().component(cmpt));
807 scalarField boundaryDiagCmpt(psi_.size(), 0.0);
808 addBoundaryDiag(boundaryDiagCmpt, cmpt);
809 boundaryDiagCmpt.negate();
810 addCmptAvBoundaryDiag(boundaryDiagCmpt);
812 H1_.internalField().replace(cmpt, boundaryDiagCmpt);
815 H1_.internalField() += lduMatrix::H1();
818 H1_.internalField() = lduMatrix::H1();
820 H1_.internalField() /= psi_.mesh().V();
821 H1_.correctBoundaryConditions();
828 Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
829 Foam::fvMatrix<Type>::
832 if (!psi_.mesh().fluxRequired(psi_.name()))
834 FatalErrorIn("fvMatrix<Type>::flux()")
835 << "flux requested but " << psi_.name()
836 << " not specified in the fluxRequired sub-dictionary"
838 << abort(FatalError);
841 // construct GeometricField<Type, fvsPatchField, surfaceMesh>
842 tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tfieldFlux
844 new GeometricField<Type, fvsPatchField, surfaceMesh>
848 "flux("+psi_.name()+')',
858 GeometricField<Type, fvsPatchField, surfaceMesh>& fieldFlux = tfieldFlux();
860 for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
862 fieldFlux.internalField().replace
865 lduMatrix::faceH(psi_.internalField().component(cmpt))
869 FieldField<Field, Type> InternalContrib = internalCoeffs_;
871 forAll(InternalContrib, patchI)
873 InternalContrib[patchI] =
876 InternalContrib[patchI],
877 psi_.boundaryField()[patchI].patchInternalField()
881 FieldField<Field, Type> NeighbourContrib = boundaryCoeffs_;
883 forAll(NeighbourContrib, patchI)
885 if (psi_.boundaryField()[patchI].coupled())
887 NeighbourContrib[patchI] =
890 NeighbourContrib[patchI],
891 psi_.boundaryField()[patchI].patchNeighbourField()
896 forAll(fieldFlux.boundaryField(), patchI)
898 fieldFlux.boundaryField()[patchI] =
899 InternalContrib[patchI] - NeighbourContrib[patchI];
902 if (faceFluxCorrectionPtr_)
904 fieldFlux += *faceFluxCorrectionPtr_;
911 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
914 void Foam::fvMatrix<Type>::operator=(const fvMatrix<Type>& fvmv)
918 FatalErrorIn("fvMatrix<Type>::operator=(const fvMatrix<Type>&)")
919 << "attempted assignment to self"
920 << abort(FatalError);
923 if (&psi_ != &(fvmv.psi_))
925 FatalErrorIn("fvMatrix<Type>::operator=(const fvMatrix<Type>&)")
926 << "different fields"
927 << abort(FatalError);
930 lduMatrix::operator=(fvmv);
931 source_ = fvmv.source_;
932 internalCoeffs_ = fvmv.internalCoeffs_;
933 boundaryCoeffs_ = fvmv.boundaryCoeffs_;
935 if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
937 *faceFluxCorrectionPtr_ = *fvmv.faceFluxCorrectionPtr_;
939 else if (fvmv.faceFluxCorrectionPtr_)
941 faceFluxCorrectionPtr_ =
942 new GeometricField<Type, fvsPatchField, surfaceMesh>
943 (*fvmv.faceFluxCorrectionPtr_);
949 void Foam::fvMatrix<Type>::operator=(const tmp<fvMatrix<Type> >& tfvmv)
957 void Foam::fvMatrix<Type>::negate()
961 internalCoeffs_.negate();
962 boundaryCoeffs_.negate();
964 if (faceFluxCorrectionPtr_)
966 faceFluxCorrectionPtr_->negate();
972 void Foam::fvMatrix<Type>::operator+=(const fvMatrix<Type>& fvmv)
974 checkMethod(*this, fvmv, "+=");
976 dimensions_ += fvmv.dimensions_;
977 lduMatrix::operator+=(fvmv);
978 source_ += fvmv.source_;
979 internalCoeffs_ += fvmv.internalCoeffs_;
980 boundaryCoeffs_ += fvmv.boundaryCoeffs_;
982 if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
984 *faceFluxCorrectionPtr_ += *fvmv.faceFluxCorrectionPtr_;
986 else if (fvmv.faceFluxCorrectionPtr_)
988 faceFluxCorrectionPtr_ = new
989 GeometricField<Type, fvsPatchField, surfaceMesh>
991 *fvmv.faceFluxCorrectionPtr_
998 void Foam::fvMatrix<Type>::operator+=(const tmp<fvMatrix<Type> >& tfvmv)
1000 operator+=(tfvmv());
1005 template<class Type>
1006 void Foam::fvMatrix<Type>::operator-=(const fvMatrix<Type>& fvmv)
1008 checkMethod(*this, fvmv, "+=");
1010 dimensions_ -= fvmv.dimensions_;
1011 lduMatrix::operator-=(fvmv);
1012 source_ -= fvmv.source_;
1013 internalCoeffs_ -= fvmv.internalCoeffs_;
1014 boundaryCoeffs_ -= fvmv.boundaryCoeffs_;
1016 if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
1018 *faceFluxCorrectionPtr_ -= *fvmv.faceFluxCorrectionPtr_;
1020 else if (fvmv.faceFluxCorrectionPtr_)
1022 faceFluxCorrectionPtr_ =
1023 new GeometricField<Type, fvsPatchField, surfaceMesh>
1024 (-*fvmv.faceFluxCorrectionPtr_);
1029 template<class Type>
1030 void Foam::fvMatrix<Type>::operator-=(const tmp<fvMatrix<Type> >& tfvmv)
1032 operator-=(tfvmv());
1037 template<class Type>
1038 void Foam::fvMatrix<Type>::operator+=
1040 const DimensionedField<Type, volMesh>& su
1043 checkMethod(*this, su, "+=");
1044 source() -= su.mesh().V()*su.field();
1048 template<class Type>
1049 void Foam::fvMatrix<Type>::operator+=
1051 const tmp<DimensionedField<Type, volMesh> >& tsu
1059 template<class Type>
1060 void Foam::fvMatrix<Type>::operator+=
1062 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu
1070 template<class Type>
1071 void Foam::fvMatrix<Type>::operator-=
1073 const DimensionedField<Type, volMesh>& su
1076 checkMethod(*this, su, "-=");
1077 source() += su.mesh().V()*su.field();
1081 template<class Type>
1082 void Foam::fvMatrix<Type>::operator-=
1084 const tmp<DimensionedField<Type, volMesh> >& tsu
1092 template<class Type>
1093 void Foam::fvMatrix<Type>::operator-=
1095 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu
1103 template<class Type>
1104 void Foam::fvMatrix<Type>::operator+=
1106 const dimensioned<Type>& su
1109 source() -= psi().mesh().V()*su;
1113 template<class Type>
1114 void Foam::fvMatrix<Type>::operator-=
1116 const dimensioned<Type>& su
1119 source() += psi().mesh().V()*su;
1123 template<class Type>
1124 void Foam::fvMatrix<Type>::operator+=
1131 template<class Type>
1132 void Foam::fvMatrix<Type>::operator-=
1139 template<class Type>
1140 void Foam::fvMatrix<Type>::operator*=
1142 const DimensionedField<scalar, volMesh>& dsf
1145 dimensions_ *= dsf.dimensions();
1146 lduMatrix::operator*=(dsf.field());
1147 source_ *= dsf.field();
1149 forAll(boundaryCoeffs_, patchI)
1153 dsf.mesh().boundary()[patchI].patchInternalField(dsf.field())
1156 internalCoeffs_[patchI] *= psf;
1157 boundaryCoeffs_[patchI] *= psf;
1160 if (faceFluxCorrectionPtr_)
1164 "fvMatrix<Type>::operator*="
1165 "(const DimensionedField<scalar, volMesh>&)"
1166 ) << "cannot scale a matrix containing a faceFluxCorrection"
1167 << abort(FatalError);
1172 template<class Type>
1173 void Foam::fvMatrix<Type>::operator*=
1175 const tmp<DimensionedField<scalar, volMesh> >& tdsf
1183 template<class Type>
1184 void Foam::fvMatrix<Type>::operator*=
1186 const volScalarField& vsf
1189 dimensions_ *= vsf.dimensions();
1190 lduMatrix::operator*=(vsf.field());
1191 source_ *= vsf.field();
1193 forAll(vsf.boundaryField(), patchI)
1195 const fvPatchScalarField& psf = vsf.boundaryField()[patchI];
1199 internalCoeffs_[patchI] *= psf.patchInternalField();
1200 boundaryCoeffs_[patchI] *= psf.patchNeighbourField();
1204 internalCoeffs_[patchI] *= psf.patchInternalField();
1205 boundaryCoeffs_[patchI] *= psf;
1209 if (faceFluxCorrectionPtr_)
1213 "fvMatrix<Type>::operator*="
1214 "(const DimensionedField<scalar, volMesh>&)"
1215 ) << "cannot scale a matrix containing a faceFluxCorrection"
1216 << abort(FatalError);
1220 template<class Type>
1221 void Foam::fvMatrix<Type>::operator*=
1223 const tmp<volScalarField>& tvsf
1231 template<class Type>
1232 void Foam::fvMatrix<Type>::operator*=
1234 const dimensioned<scalar>& ds
1237 dimensions_ *= ds.dimensions();
1238 lduMatrix::operator*=(ds.value());
1239 source_ *= ds.value();
1240 internalCoeffs_ *= ds.value();
1241 boundaryCoeffs_ *= ds.value();
1243 if (faceFluxCorrectionPtr_)
1245 *faceFluxCorrectionPtr_ *= ds.value();
1250 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
1252 template<class Type>
1253 void Foam::checkMethod
1255 const fvMatrix<Type>& fvm1,
1256 const fvMatrix<Type>& fvm2,
1260 if (&fvm1.psi() != &fvm2.psi())
1264 "checkMethod(const fvMatrix<Type>&, const fvMatrix<Type>&)"
1265 ) << "incompatible fields for operation "
1267 << "[" << fvm1.psi().name() << "] "
1269 << " [" << fvm2.psi().name() << "]"
1270 << abort(FatalError);
1273 if (dimensionSet::debug && fvm1.dimensions() != fvm2.dimensions())
1277 "checkMethod(const fvMatrix<Type>&, const fvMatrix<Type>&)"
1278 ) << "incompatible dimensions for operation "
1280 << "[" << fvm1.psi().name() << fvm1.dimensions()/dimVolume << " ] "
1282 << " [" << fvm2.psi().name() << fvm2.dimensions()/dimVolume << " ]"
1283 << abort(FatalError);
1288 template<class Type>
1289 void Foam::checkMethod
1291 const fvMatrix<Type>& fvm,
1292 const DimensionedField<Type, volMesh>& df,
1296 if (dimensionSet::debug && fvm.dimensions()/dimVolume != df.dimensions())
1300 "checkMethod(const fvMatrix<Type>&, const GeometricField<Type, "
1301 "fvPatchField, volMesh>&)"
1302 ) << "incompatible dimensions for operation "
1304 << "[" << fvm.psi().name() << fvm.dimensions()/dimVolume << " ] "
1306 << " [" << df.name() << df.dimensions() << " ]"
1307 << abort(FatalError);
1312 template<class Type>
1313 void Foam::checkMethod
1315 const fvMatrix<Type>& fvm,
1316 const dimensioned<Type>& dt,
1320 if (dimensionSet::debug && fvm.dimensions()/dimVolume != dt.dimensions())
1324 "checkMethod(const fvMatrix<Type>&, const dimensioned<Type>&)"
1325 ) << "incompatible dimensions for operation "
1327 << "[" << fvm.psi().name() << fvm.dimensions()/dimVolume << " ] "
1329 << " [" << dt.name() << dt.dimensions() << " ]"
1330 << abort(FatalError);
1335 template<class Type>
1336 Foam::lduMatrix::solverPerformance Foam::solve
1338 fvMatrix<Type>& fvm,
1339 const dictionary& solverControls
1342 return fvm.solve(solverControls);
1345 template<class Type>
1346 Foam::lduMatrix::solverPerformance Foam::solve
1348 const tmp<fvMatrix<Type> >& tfvm,
1349 const dictionary& solverControls
1352 lduMatrix::solverPerformance solverPerf =
1353 const_cast<fvMatrix<Type>&>(tfvm()).solve(solverControls);
1361 template<class Type>
1362 Foam::lduMatrix::solverPerformance Foam::solve(fvMatrix<Type>& fvm)
1367 template<class Type>
1368 Foam::lduMatrix::solverPerformance Foam::solve(const tmp<fvMatrix<Type> >& tfvm)
1370 lduMatrix::solverPerformance solverPerf =
1371 const_cast<fvMatrix<Type>&>(tfvm()).solve();
1379 template<class Type>
1380 Foam::tmp<Foam::fvMatrix<Type> > Foam::correction
1382 const fvMatrix<Type>& A
1385 tmp<Foam::fvMatrix<Type> > tAcorr = A - (A & A.psi());
1389 (A.hasUpper() || A.hasLower())
1390 && A.psi().mesh().fluxRequired(A.psi().name())
1393 tAcorr().faceFluxCorrectionPtr() = (-A.flux()).ptr();
1400 template<class Type>
1401 Foam::tmp<Foam::fvMatrix<Type> > Foam::correction
1403 const tmp<fvMatrix<Type> >& tA
1406 tmp<Foam::fvMatrix<Type> > tAcorr = tA - (tA() & tA().psi());
1408 // Note the matrix coefficients are still that of matrix A
1409 const fvMatrix<Type>& A = tAcorr();
1413 (A.hasUpper() || A.hasLower())
1414 && A.psi().mesh().fluxRequired(A.psi().name())
1417 tAcorr().faceFluxCorrectionPtr() = (-A.flux()).ptr();
1424 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
1426 template<class Type>
1427 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1429 const fvMatrix<Type>& A,
1430 const fvMatrix<Type>& B
1433 checkMethod(A, B, "==");
1437 template<class Type>
1438 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1440 const tmp<fvMatrix<Type> >& tA,
1441 const fvMatrix<Type>& B
1444 checkMethod(tA(), B, "==");
1448 template<class Type>
1449 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1451 const fvMatrix<Type>& A,
1452 const tmp<fvMatrix<Type> >& tB
1455 checkMethod(A, tB(), "==");
1459 template<class Type>
1460 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1462 const tmp<fvMatrix<Type> >& tA,
1463 const tmp<fvMatrix<Type> >& tB
1466 checkMethod(tA(), tB(), "==");
1470 template<class Type>
1471 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1473 const fvMatrix<Type>& A,
1474 const DimensionedField<Type, volMesh>& su
1477 checkMethod(A, su, "==");
1478 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1479 tC().source() += su.mesh().V()*su.field();
1483 template<class Type>
1484 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1486 const fvMatrix<Type>& A,
1487 const tmp<DimensionedField<Type, volMesh> >& tsu
1490 checkMethod(A, tsu(), "==");
1491 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1492 tC().source() += tsu().mesh().V()*tsu().field();
1497 template<class Type>
1498 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1500 const fvMatrix<Type>& A,
1501 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu
1504 checkMethod(A, tsu(), "==");
1505 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1506 tC().source() += tsu().mesh().V()*tsu().internalField();
1511 template<class Type>
1512 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1514 const tmp<fvMatrix<Type> >& tA,
1515 const DimensionedField<Type, volMesh>& su
1518 checkMethod(tA(), su, "==");
1519 tmp<fvMatrix<Type> > tC(tA.ptr());
1520 tC().source() += su.mesh().V()*su.field();
1524 template<class Type>
1525 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1527 const tmp<fvMatrix<Type> >& tA,
1528 const tmp<DimensionedField<Type, volMesh> >& tsu
1531 checkMethod(tA(), tsu(), "==");
1532 tmp<fvMatrix<Type> > tC(tA.ptr());
1533 tC().source() += tsu().mesh().V()*tsu().field();
1538 template<class Type>
1539 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1541 const tmp<fvMatrix<Type> >& tA,
1542 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu
1545 checkMethod(tA(), tsu(), "==");
1546 tmp<fvMatrix<Type> > tC(tA.ptr());
1547 tC().source() += tsu().mesh().V()*tsu().internalField();
1552 template<class Type>
1553 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1555 const fvMatrix<Type>& A,
1556 const dimensioned<Type>& su
1559 checkMethod(A, su, "==");
1560 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1561 tC().source() += A.psi().mesh().V()*su.value();
1565 template<class Type>
1566 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1568 const tmp<fvMatrix<Type> >& tA,
1569 const dimensioned<Type>& su
1572 checkMethod(tA(), su, "==");
1573 tmp<fvMatrix<Type> > tC(tA.ptr());
1574 tC().source() += tC().psi().mesh().V()*su.value();
1578 template<class Type>
1579 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1581 const fvMatrix<Type>& A,
1589 template<class Type>
1590 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
1592 const tmp<fvMatrix<Type> >& tA,
1600 template<class Type>
1601 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1603 const fvMatrix<Type>& A
1606 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1611 template<class Type>
1612 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1614 const tmp<fvMatrix<Type> >& tA
1617 tmp<fvMatrix<Type> > tC(tA.ptr());
1623 template<class Type>
1624 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1626 const fvMatrix<Type>& A,
1627 const fvMatrix<Type>& B
1630 checkMethod(A, B, "+");
1631 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1636 template<class Type>
1637 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1639 const tmp<fvMatrix<Type> >& tA,
1640 const fvMatrix<Type>& B
1643 checkMethod(tA(), B, "+");
1644 tmp<fvMatrix<Type> > tC(tA.ptr());
1649 template<class Type>
1650 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1652 const fvMatrix<Type>& A,
1653 const tmp<fvMatrix<Type> >& tB
1656 checkMethod(A, tB(), "+");
1657 tmp<fvMatrix<Type> > tC(tB.ptr());
1662 template<class Type>
1663 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1665 const tmp<fvMatrix<Type> >& tA,
1666 const tmp<fvMatrix<Type> >& tB
1669 checkMethod(tA(), tB(), "+");
1670 tmp<fvMatrix<Type> > tC(tA.ptr());
1676 template<class Type>
1677 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1679 const fvMatrix<Type>& A,
1680 const DimensionedField<Type, volMesh>& su
1683 checkMethod(A, su, "+");
1684 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1685 tC().source() -= su.mesh().V()*su.field();
1689 template<class Type>
1690 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1692 const fvMatrix<Type>& A,
1693 const tmp<DimensionedField<Type, volMesh> >& tsu
1696 checkMethod(A, tsu(), "+");
1697 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1698 tC().source() -= tsu().mesh().V()*tsu().field();
1703 template<class Type>
1704 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1706 const fvMatrix<Type>& A,
1707 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu
1710 checkMethod(A, tsu(), "+");
1711 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1712 tC().source() -= tsu().mesh().V()*tsu().internalField();
1717 template<class Type>
1718 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1720 const tmp<fvMatrix<Type> >& tA,
1721 const DimensionedField<Type, volMesh>& su
1724 checkMethod(tA(), su, "+");
1725 tmp<fvMatrix<Type> > tC(tA.ptr());
1726 tC().source() -= su.mesh().V()*su.field();
1730 template<class Type>
1731 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1733 const tmp<fvMatrix<Type> >& tA,
1734 const tmp<DimensionedField<Type, volMesh> >& tsu
1737 checkMethod(tA(), tsu(), "+");
1738 tmp<fvMatrix<Type> > tC(tA.ptr());
1739 tC().source() -= tsu().mesh().V()*tsu().field();
1744 template<class Type>
1745 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1747 const tmp<fvMatrix<Type> >& tA,
1748 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu
1751 checkMethod(tA(), tsu(), "+");
1752 tmp<fvMatrix<Type> > tC(tA.ptr());
1753 tC().source() -= tsu().mesh().V()*tsu().internalField();
1758 template<class Type>
1759 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1761 const DimensionedField<Type, volMesh>& su,
1762 const fvMatrix<Type>& A
1765 checkMethod(A, su, "+");
1766 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1767 tC().source() -= su.mesh().V()*su.field();
1771 template<class Type>
1772 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1774 const tmp<DimensionedField<Type, volMesh> >& tsu,
1775 const fvMatrix<Type>& A
1778 checkMethod(A, tsu(), "+");
1779 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1780 tC().source() -= tsu().mesh().V()*tsu().field();
1785 template<class Type>
1786 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1788 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu,
1789 const fvMatrix<Type>& A
1792 checkMethod(A, tsu(), "+");
1793 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1794 tC().source() -= tsu().mesh().V()*tsu().internalField();
1799 template<class Type>
1800 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1802 const DimensionedField<Type, volMesh>& su,
1803 const tmp<fvMatrix<Type> >& tA
1806 checkMethod(tA(), su, "+");
1807 tmp<fvMatrix<Type> > tC(tA.ptr());
1808 tC().source() -= su.mesh().V()*su.field();
1812 template<class Type>
1813 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1815 const tmp<DimensionedField<Type, volMesh> >& tsu,
1816 const tmp<fvMatrix<Type> >& tA
1819 checkMethod(tA(), tsu(), "+");
1820 tmp<fvMatrix<Type> > tC(tA.ptr());
1821 tC().source() -= tsu().mesh().V()*tsu().field();
1826 template<class Type>
1827 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
1829 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu,
1830 const tmp<fvMatrix<Type> >& tA
1833 checkMethod(tA(), tsu(), "+");
1834 tmp<fvMatrix<Type> > tC(tA.ptr());
1835 tC().source() -= tsu().mesh().V()*tsu().internalField();
1841 template<class Type>
1842 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1844 const fvMatrix<Type>& A,
1845 const fvMatrix<Type>& B
1848 checkMethod(A, B, "-");
1849 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1854 template<class Type>
1855 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1857 const tmp<fvMatrix<Type> >& tA,
1858 const fvMatrix<Type>& B
1861 checkMethod(tA(), B, "-");
1862 tmp<fvMatrix<Type> > tC(tA.ptr());
1867 template<class Type>
1868 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1870 const fvMatrix<Type>& A,
1871 const tmp<fvMatrix<Type> >& tB
1874 checkMethod(A, tB(), "-");
1875 tmp<fvMatrix<Type> > tC(tB.ptr());
1881 template<class Type>
1882 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1884 const tmp<fvMatrix<Type> >& tA,
1885 const tmp<fvMatrix<Type> >& tB
1888 checkMethod(tA(), tB(), "-");
1889 tmp<fvMatrix<Type> > tC(tA.ptr());
1895 template<class Type>
1896 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1898 const fvMatrix<Type>& A,
1899 const DimensionedField<Type, volMesh>& su
1902 checkMethod(A, su, "-");
1903 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1904 tC().source() += su.mesh().V()*su.field();
1908 template<class Type>
1909 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1911 const fvMatrix<Type>& A,
1912 const tmp<DimensionedField<Type, volMesh> >& tsu
1915 checkMethod(A, tsu(), "-");
1916 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1917 tC().source() += tsu().mesh().V()*tsu().field();
1922 template<class Type>
1923 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1925 const fvMatrix<Type>& A,
1926 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu
1929 checkMethod(A, tsu(), "-");
1930 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1931 tC().source() += tsu().mesh().V()*tsu().internalField();
1936 template<class Type>
1937 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1939 const tmp<fvMatrix<Type> >& tA,
1940 const DimensionedField<Type, volMesh>& su
1943 checkMethod(tA(), su, "-");
1944 tmp<fvMatrix<Type> > tC(tA.ptr());
1945 tC().source() += su.mesh().V()*su.field();
1949 template<class Type>
1950 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1952 const tmp<fvMatrix<Type> >& tA,
1953 const tmp<DimensionedField<Type, volMesh> >& tsu
1956 checkMethod(tA(), tsu(), "-");
1957 tmp<fvMatrix<Type> > tC(tA.ptr());
1958 tC().source() += tsu().mesh().V()*tsu().field();
1963 template<class Type>
1964 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1966 const tmp<fvMatrix<Type> >& tA,
1967 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu
1970 checkMethod(tA(), tsu(), "-");
1971 tmp<fvMatrix<Type> > tC(tA.ptr());
1972 tC().source() += tsu().mesh().V()*tsu().internalField();
1977 template<class Type>
1978 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1980 const DimensionedField<Type, volMesh>& su,
1981 const fvMatrix<Type>& A
1984 checkMethod(A, su, "-");
1985 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
1987 tC().source() -= su.mesh().V()*su.field();
1991 template<class Type>
1992 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
1994 const tmp<DimensionedField<Type, volMesh> >& tsu,
1995 const fvMatrix<Type>& A
1998 checkMethod(A, tsu(), "-");
1999 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
2001 tC().source() -= tsu().mesh().V()*tsu().field();
2006 template<class Type>
2007 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
2009 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu,
2010 const fvMatrix<Type>& A
2013 checkMethod(A, tsu(), "-");
2014 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
2016 tC().source() -= tsu().mesh().V()*tsu().internalField();
2021 template<class Type>
2022 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
2024 const DimensionedField<Type, volMesh>& su,
2025 const tmp<fvMatrix<Type> >& tA
2028 checkMethod(tA(), su, "-");
2029 tmp<fvMatrix<Type> > tC(tA.ptr());
2031 tC().source() -= su.mesh().V()*su.field();
2035 template<class Type>
2036 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
2038 const tmp<DimensionedField<Type, volMesh> >& tsu,
2039 const tmp<fvMatrix<Type> >& tA
2042 checkMethod(tA(), tsu(), "-");
2043 tmp<fvMatrix<Type> > tC(tA.ptr());
2045 tC().source() -= tsu().mesh().V()*tsu().field();
2050 template<class Type>
2051 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
2053 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tsu,
2054 const tmp<fvMatrix<Type> >& tA
2057 checkMethod(tA(), tsu(), "-");
2058 tmp<fvMatrix<Type> > tC(tA.ptr());
2060 tC().source() -= tsu().mesh().V()*tsu().internalField();
2065 template<class Type>
2066 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
2068 const fvMatrix<Type>& A,
2069 const dimensioned<Type>& su
2072 checkMethod(A, su, "+");
2073 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
2074 tC().source() -= su.value()*A.psi().mesh().V();
2078 template<class Type>
2079 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
2081 const tmp<fvMatrix<Type> >& tA,
2082 const dimensioned<Type>& su
2085 checkMethod(tA(), su, "+");
2086 tmp<fvMatrix<Type> > tC(tA.ptr());
2087 tC().source() -= su.value()*tC().psi().mesh().V();
2091 template<class Type>
2092 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
2094 const dimensioned<Type>& su,
2095 const fvMatrix<Type>& A
2098 checkMethod(A, su, "+");
2099 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
2100 tC().source() -= su.value()*A.psi().mesh().V();
2104 template<class Type>
2105 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator+
2107 const dimensioned<Type>& su,
2108 const tmp<fvMatrix<Type> >& tA
2111 checkMethod(tA(), su, "+");
2112 tmp<fvMatrix<Type> > tC(tA.ptr());
2113 tC().source() -= su.value()*tC().psi().mesh().V();
2117 template<class Type>
2118 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
2120 const fvMatrix<Type>& A,
2121 const dimensioned<Type>& su
2124 checkMethod(A, su, "-");
2125 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
2126 tC().source() += su.value()*tC().psi().mesh().V();
2130 template<class Type>
2131 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
2133 const tmp<fvMatrix<Type> >& tA,
2134 const dimensioned<Type>& su
2137 checkMethod(tA(), su, "-");
2138 tmp<fvMatrix<Type> > tC(tA.ptr());
2139 tC().source() += su.value()*tC().psi().mesh().V();
2143 template<class Type>
2144 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
2146 const dimensioned<Type>& su,
2147 const fvMatrix<Type>& A
2150 checkMethod(A, su, "-");
2151 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
2153 tC().source() -= su.value()*A.psi().mesh().V();
2157 template<class Type>
2158 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator-
2160 const dimensioned<Type>& su,
2161 const tmp<fvMatrix<Type> >& tA
2164 checkMethod(tA(), su, "-");
2165 tmp<fvMatrix<Type> > tC(tA.ptr());
2167 tC().source() -= su.value()*tC().psi().mesh().V();
2172 template<class Type>
2173 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator*
2175 const DimensionedField<scalar, volMesh>& dsf,
2176 const fvMatrix<Type>& A
2179 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
2184 template<class Type>
2185 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator*
2187 const tmp< DimensionedField<scalar, volMesh> >& tdsf,
2188 const fvMatrix<Type>& A
2191 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
2196 template<class Type>
2197 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator*
2199 const tmp<volScalarField>& tvsf,
2200 const fvMatrix<Type>& A
2203 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
2208 template<class Type>
2209 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator*
2211 const DimensionedField<scalar, volMesh>& dsf,
2212 const tmp<fvMatrix<Type> >& tA
2215 tmp<fvMatrix<Type> > tC(tA.ptr());
2220 template<class Type>
2221 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator*
2223 const tmp<DimensionedField<scalar, volMesh> >& tdsf,
2224 const tmp<fvMatrix<Type> >& tA
2227 tmp<fvMatrix<Type> > tC(tA.ptr());
2232 template<class Type>
2233 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator*
2235 const tmp<volScalarField>& tvsf,
2236 const tmp<fvMatrix<Type> >& tA
2239 tmp<fvMatrix<Type> > tC(tA.ptr());
2244 template<class Type>
2245 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator*
2247 const dimensioned<scalar>& ds,
2248 const fvMatrix<Type>& A
2251 tmp<fvMatrix<Type> > tC(new fvMatrix<Type>(A));
2256 template<class Type>
2257 Foam::tmp<Foam::fvMatrix<Type> > Foam::operator*
2259 const dimensioned<scalar>& ds,
2260 const tmp<fvMatrix<Type> >& tA
2263 tmp<fvMatrix<Type> > tC(tA.ptr());
2269 template<class Type>
2270 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
2273 const fvMatrix<Type>& M,
2274 const DimensionedField<Type, volMesh>& psi
2277 tmp<GeometricField<Type, fvPatchField, volMesh> > tMphi
2279 new GeometricField<Type, fvPatchField, volMesh>
2290 M.dimensions()/dimVol,
2291 zeroGradientFvPatchScalarField::typeName
2294 GeometricField<Type, fvPatchField, volMesh>& Mphi = tMphi();
2296 // Loop over field components
2297 for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
2299 scalarField psiCmpt(psi.field().component(cmpt));
2300 scalarField boundaryDiagCmpt(M.diag());
2301 M.addBoundaryDiag(boundaryDiagCmpt, cmpt);
2302 Mphi.internalField().replace(cmpt, -boundaryDiagCmpt*psiCmpt);
2305 Mphi.internalField() += M.lduMatrix::H(psi.field()) + M.source();
2306 M.addBoundarySource(Mphi.internalField());
2308 Mphi.internalField() /= -psi.mesh().V();
2309 Mphi.correctBoundaryConditions();
2314 template<class Type>
2315 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
2318 const fvMatrix<Type>& M,
2319 const tmp<DimensionedField<Type, volMesh> >& tpsi
2322 tmp<GeometricField<Type, fvPatchField, volMesh> > tMpsi = M & tpsi();
2327 template<class Type>
2328 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
2331 const fvMatrix<Type>& M,
2332 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tpsi
2335 tmp<GeometricField<Type, fvPatchField, volMesh> > tMpsi = M & tpsi();
2340 template<class Type>
2341 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
2344 const tmp<fvMatrix<Type> >& tM,
2345 const DimensionedField<Type, volMesh>& psi
2348 tmp<GeometricField<Type, fvPatchField, volMesh> > tMpsi = tM() & psi;
2353 template<class Type>
2354 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
2357 const tmp<fvMatrix<Type> >& tM,
2358 const tmp<DimensionedField<Type, volMesh> >& tpsi
2361 tmp<GeometricField<Type, fvPatchField, volMesh> > tMpsi = tM() & tpsi();
2367 template<class Type>
2368 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
2371 const tmp<fvMatrix<Type> >& tM,
2372 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tpsi
2375 tmp<GeometricField<Type, fvPatchField, volMesh> > tMpsi = tM() & tpsi();
2382 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
2384 template<class Type>
2385 Foam::Ostream& Foam::operator<<(Ostream& os, const fvMatrix<Type>& fvm)
2387 os << static_cast<const lduMatrix&>(fvm) << nl
2388 << fvm.dimensions_ << nl
2389 << fvm.source_ << nl
2390 << fvm.internalCoeffs_ << nl
2391 << fvm.boundaryCoeffs_ << endl;
2393 os.check("Ostream& operator<<(Ostream&, fvMatrix<Type>&");
2399 // * * * * * * * * * * * * * * * * Solvers * * * * * * * * * * * * * * * * * //
2401 #include "fvMatrixSolve.C"
2403 // ************************************************************************* //