fvMatrix.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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
19  for more details.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "volFields.H"
27 #include "surfaceFields.H"
30 #include "coupledFvPatchFields.H"
31 #include "UIndirectList.H"
32 #include "UCompactListList.H"
33 #include "fvmDdt.H"
34 
35 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
36 
37 template<class Type>
38 template<class Type2>
40 (
41  const labelUList& addr,
42  const Field<Type2>& pf,
43  Field<Type2>& intf
44 ) const
45 {
46  if (addr.size() != pf.size())
47  {
49  << "sizes of addressing and field are different"
50  << abort(FatalError);
51  }
52 
53  forAll(addr, facei)
54  {
55  intf[addr[facei]] += pf[facei];
56  }
57 }
58 
59 
60 template<class Type>
61 template<class Type2>
63 (
64  const labelUList& addr,
65  const tmp<Field<Type2>>& tpf,
66  Field<Type2>& intf
67 ) const
68 {
69  addToInternalField(addr, tpf(), intf);
70  tpf.clear();
71 }
72 
73 
74 template<class Type>
75 template<class Type2>
77 (
78  const labelUList& addr,
79  const Field<Type2>& pf,
80  Field<Type2>& intf
81 ) const
82 {
83  if (addr.size() != pf.size())
84  {
86  << "sizes of addressing and field are different"
87  << abort(FatalError);
88  }
89 
90  forAll(addr, facei)
91  {
92  intf[addr[facei]] -= pf[facei];
93  }
94 }
95 
96 
97 template<class Type>
98 template<class Type2>
100 (
101  const labelUList& addr,
102  const tmp<Field<Type2>>& tpf,
103  Field<Type2>& intf
104 ) const
105 {
106  subtractFromInternalField(addr, tpf(), intf);
107  tpf.clear();
108 }
109 
110 
111 template<class Type>
113 (
114  scalarField& diag,
115  const direction solveCmpt
116 ) const
117 {
118  forAll(internalCoeffs_, patchi)
119  {
120  addToInternalField
121  (
122  lduAddr().patchAddr(patchi),
123  internalCoeffs_[patchi].component(solveCmpt),
124  diag
125  );
126  }
127 }
128 
129 
130 template<class Type>
132 {
133  forAll(internalCoeffs_, patchi)
134  {
135  addToInternalField
136  (
137  lduAddr().patchAddr(patchi),
138  cmptAv(internalCoeffs_[patchi]),
139  diag
140  );
141  }
142 }
143 
144 
145 template<class Type>
147 (
148  Field<Type>& source,
149  const bool couples
150 ) const
151 {
152  forAll(psi_.boundaryField(), patchi)
153  {
154  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
155  const Field<Type>& pbc = boundaryCoeffs_[patchi];
156 
157  if (!ptf.coupled())
158  {
159  addToInternalField(lduAddr().patchAddr(patchi), pbc, source);
160  }
161  else if (couples)
162  {
163  const tmp<Field<Type>> tpnf = ptf.patchNeighbourField();
164  const Field<Type>& pnf = tpnf();
165 
166  const labelUList& addr = lduAddr().patchAddr(patchi);
167 
168  forAll(addr, facei)
169  {
170  source[addr[facei]] += cmptMultiply(pbc[facei], pnf[facei]);
171  }
172  }
173  }
174 }
175 
176 
177 template<class Type>
179 (
180  const label celli,
181  const Type& value
182 )
183 {
184  const fvMesh& mesh = psi_.mesh();
185 
186  const cellList& cells = mesh.cells();
187  const labelUList& own = mesh.owner();
188  const labelUList& nei = mesh.neighbour();
189 
190  scalarField& Diag = diag();
191 
192  Field<Type>& psi =
193  const_cast<VolField<Type>&>(psi_)
195 
196  psi[celli] = value;
197  source_[celli] = value*Diag[celli];
198 
199  if (symmetric() || asymmetric())
200  {
201  const cell& c = cells[celli];
202 
203  forAll(c, j)
204  {
205  const label facei = c[j];
206 
207  if (mesh.isInternalFace(facei))
208  {
209  if (symmetric())
210  {
211  if (celli == own[facei])
212  {
213  source_[nei[facei]] -= upper()[facei]*value;
214  }
215  else
216  {
217  source_[own[facei]] -= upper()[facei]*value;
218  }
219 
220  upper()[facei] = 0.0;
221  }
222  else
223  {
224  if (celli == own[facei])
225  {
226  source_[nei[facei]] -= lower()[facei]*value;
227  }
228  else
229  {
230  source_[own[facei]] -= upper()[facei]*value;
231  }
232 
233  upper()[facei] = 0.0;
234  lower()[facei] = 0.0;
235  }
236  }
237  else
238  {
239  const label bFacei = facei - mesh.nInternalFaces();
240 
241  const labelUList patches =
242  mesh.polyBFacePatches()[bFacei];
243  const labelUList patchFaces =
244  mesh.polyBFacePatchFaces()[bFacei];
245 
246  forAll(patches, i)
247  {
248  internalCoeffs_[patches[i]][patchFaces[i]] = Zero;
249  boundaryCoeffs_[patches[i]][patchFaces[i]] = Zero;
250  }
251  }
252  }
253  }
254 }
255 
256 
257 template<class Type>
259 (
260  const label celli,
261  const Type& value,
262  const scalar fraction,
263  const scalarField& ddtDiag
264 )
265 {
266  Field<Type>& psi =
267  const_cast<VolField<Type>&>(psi_)
269 
270  psi[celli] = (1 - fraction)*psi[celli] + fraction*value;
271 
272  const scalar coeff =
273  fraction/(1 - fraction)
274  *(diag()[celli] - ddtDiag[celli]);
275 
276  diag()[celli] += coeff;
277  source()[celli] += coeff*value;
278 }
279 
280 
281 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
282 
283 template<class Type>
285 (
286  const VolField<Type>& psi,
287  const dimensionSet& ds
288 )
289 :
290  lduMatrix(psi.mesh()),
291  psi_(psi),
292  dimensions_(ds),
293  source_(psi.size(), Zero),
294  internalCoeffs_(psi.mesh().boundary().size()),
295  boundaryCoeffs_(psi.mesh().boundary().size()),
296  faceFluxCorrectionPtr_(nullptr)
297 {
298  if (debug)
299  {
301  << "Constructing fvMatrix<Type> for field " << psi_.name() << endl;
302  }
303 
304  // Initialise coupling coefficients
305  forAll(psi.mesh().boundary(), patchi)
306  {
307  internalCoeffs_.set
308  (
309  patchi,
310  new Field<Type>
311  (
312  psi.mesh().boundary()[patchi].size(),
313  Zero
314  )
315  );
316 
317  boundaryCoeffs_.set
318  (
319  patchi,
320  new Field<Type>
321  (
322  psi.mesh().boundary()[patchi].size(),
323  Zero
324  )
325  );
326  }
327 
328  // Update the boundary coefficients of psi without changing its event No.
329  VolField<Type>& psiRef =
330  const_cast<VolField<Type>&>(psi_);
331 
332  label currentStatePsi = psiRef.eventNo();
333  psiRef.boundaryFieldRef().updateCoeffs();
334  psiRef.eventNo() = currentStatePsi;
335 }
336 
337 
338 template<class Type>
340 :
341  tmp<fvMatrix<Type>>::refCount(),
342  lduMatrix(fvm),
343  psi_(fvm.psi_),
344  dimensions_(fvm.dimensions_),
345  source_(fvm.source_),
346  internalCoeffs_(fvm.internalCoeffs_),
347  boundaryCoeffs_(fvm.boundaryCoeffs_),
348  faceFluxCorrectionPtr_(nullptr)
349 {
350  if (debug)
351  {
353  << "Copying fvMatrix<Type> for field " << psi_.name() << endl;
354  }
355 
356  if (fvm.faceFluxCorrectionPtr_)
357  {
358  faceFluxCorrectionPtr_ = new
360  (
361  *(fvm.faceFluxCorrectionPtr_)
362  );
363  }
364 }
365 
366 
367 template<class Type>
369 :
370  lduMatrix
371  (
372  const_cast<fvMatrix<Type>&>(tfvm()),
373  tfvm.isTmp()
374  ),
375  psi_(tfvm().psi_),
376  dimensions_(tfvm().dimensions_),
377  source_
378  (
379  const_cast<fvMatrix<Type>&>(tfvm()).source_,
380  tfvm.isTmp()
381  ),
382  internalCoeffs_
383  (
384  const_cast<fvMatrix<Type>&>(tfvm()).internalCoeffs_,
385  tfvm.isTmp()
386  ),
387  boundaryCoeffs_
388  (
389  const_cast<fvMatrix<Type>&>(tfvm()).boundaryCoeffs_,
390  tfvm.isTmp()
391  ),
392  faceFluxCorrectionPtr_(nullptr)
393 {
394  if (debug)
395  {
397  << "Copying fvMatrix<Type> for field " << psi_.name() << endl;
398  }
399 
400  if (tfvm().faceFluxCorrectionPtr_)
401  {
402  if (tfvm.isTmp())
403  {
404  faceFluxCorrectionPtr_ = tfvm().faceFluxCorrectionPtr_;
405  tfvm().faceFluxCorrectionPtr_ = nullptr;
406  }
407  else
408  {
409  faceFluxCorrectionPtr_ = new
411  (
412  *(tfvm().faceFluxCorrectionPtr_)
413  );
414  }
415  }
416 
417  tfvm.clear();
418 }
419 
420 
421 template<class Type>
423 (
424  const VolField<Type>& psi,
425  Istream& is
426 )
427 :
428  lduMatrix(psi.mesh()),
429  psi_(psi),
430  dimensions_(is),
431  source_(is),
432  internalCoeffs_(psi.mesh().boundary().size()),
433  boundaryCoeffs_(psi.mesh().boundary().size()),
434  faceFluxCorrectionPtr_(nullptr)
435 {
436  if (debug)
437  {
439  << "Constructing fvMatrix<Type> for field " << psi_.name() << endl;
440  }
441 
442  // Initialise coupling coefficients
443  forAll(psi.mesh().boundary(), patchi)
444  {
445  internalCoeffs_.set
446  (
447  patchi,
448  new Field<Type>
449  (
450  psi.mesh().boundary()[patchi].size(),
451  Zero
452  )
453  );
454 
455  boundaryCoeffs_.set
456  (
457  patchi,
458  new Field<Type>
459  (
460  psi.mesh().boundary()[patchi].size(),
461  Zero
462  )
463  );
464  }
465 
466 }
467 
468 
469 template<class Type>
471 {
472  return tmp<fvMatrix<Type>>
473  (
474  new fvMatrix<Type>(*this)
475  );
476 }
477 
478 
479 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * * //
480 
481 template<class Type>
483 {
484  if (debug)
485  {
487  << "Destroying fvMatrix<Type> for field " << psi_.name() << endl;
488  }
489 
490  if (faceFluxCorrectionPtr_)
491  {
492  delete faceFluxCorrectionPtr_;
493  }
494 }
495 
496 
497 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
498 
499 template<class Type>
500 template<template<class> class ListType>
502 (
503  const labelUList& cellLabels,
504  const ListType<Type>& values
505 )
506 {
507  // Fix the values
508  forAll(cellLabels, i)
509  {
510  setValue(cellLabels[i], values[i]);
511  }
512 }
513 
514 
515 template<class Type>
516 template<template<class> class ListType>
518 (
519  const labelUList& cellLabels,
520  const ListType<Type>& values,
521  const scalarList& fractions,
522  const bool hasDdt
523 )
524 {
525  // Get the proportion of the diagonal associated with iterative update
526  scalarField ddtDiag(diag().size(), 0);
527  const scalar alpha = relaxationFactor();
528  if (alpha > 0)
529  {
530  ddtDiag += (1 - alpha)*diag();
531  }
532  if (hasDdt)
533  {
534  const fvMatrix<Type> ddtEqn(fvm::ddt(psi_));
535  if (ddtEqn.hasDiag())
536  {
537  ddtDiag += ddtEqn.diag();
538  }
539  }
540 
541  forAll(cellLabels, i)
542  {
543  if (- rootSmall < fractions[i] && fractions[i] < rootSmall)
544  {
545  // Do nothing
546  }
547  else if (1 - rootSmall < fractions[i] && fractions[i] < 1 + rootSmall)
548  {
549  // Fix the values
550  setValue(cellLabels[i], values[i]);
551  }
552  else
553  {
554  // Fractionally fix the values
555  setValue(cellLabels[i], values[i], fractions[i], ddtDiag);
556  }
557  }
558 }
559 
560 
561 template<class Type>
563 (
564  const label celli,
565  const Type& value,
566  const bool forceReference
567 )
568 {
569  if ((forceReference || psi_.needReference()) && celli >= 0)
570  {
571  source()[celli] += diag()[celli]*value;
572  diag()[celli] += diag()[celli];
573  }
574 }
575 
576 
577 template<class Type>
579 {
580  if
581  (
583  && psi_.mesh().solution().relaxEquation(psi_.name() + "Final")
584  )
585  {
586  return psi_.mesh().solution().equationRelaxationFactor
587  (
588  psi_.name() + "Final"
589  );
590  }
591  else if (psi_.mesh().solution().relaxEquation(psi_.name()))
592  {
593  return psi_.mesh().solution().equationRelaxationFactor(psi_.name());
594  }
595  else
596  {
597  return 0;
598  }
599 }
600 
601 
602 template<class Type>
604 {
605  if (alpha <= 0)
606  {
607  return;
608  }
609 
610  if (debug)
611  {
613  << "Relaxing " << psi_.name() << " by " << alpha << endl;
614  }
615 
616  Field<Type>& S = source();
617  scalarField& D = diag();
618 
619  // Store the current unrelaxed diagonal for use in updating the source
620  scalarField D0(D);
621 
622  // Calculate the sum-mag off-diagonal from the interior faces
623  scalarField sumOff(D.size(), 0.0);
624  sumMagOffDiag(sumOff);
625 
626  // Handle the boundary contributions to the diagonal
627  forAll(psi_.boundaryField(), patchi)
628  {
629  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
630 
631  if (ptf.size())
632  {
633  const labelUList& pa = lduAddr().patchAddr(patchi);
634  Field<Type>& iCoeffs = internalCoeffs_[patchi];
635 
636  if (ptf.coupled())
637  {
638  const Field<Type>& pCoeffs = boundaryCoeffs_[patchi];
639 
640  // For coupled boundaries add the diagonal and
641  // off-diagonal contributions
642  forAll(pa, face)
643  {
644  D[pa[face]] += component(iCoeffs[face], 0);
645  sumOff[pa[face]] += mag(component(pCoeffs[face], 0));
646  }
647  }
648  else
649  {
650  // For non-coupled boundaries add the maximum magnitude diagonal
651  // contribution to ensure stability
652  forAll(pa, face)
653  {
654  D[pa[face]] += cmptMax(cmptMag(iCoeffs[face]));
655  }
656  }
657  }
658  }
659 
660 
661  if (debug)
662  {
663  // Calculate amount of non-dominance.
664  label nNon = 0;
665  scalar maxNon = 0.0;
666  scalar sumNon = 0.0;
667  forAll(D, celli)
668  {
669  scalar d = (sumOff[celli] - D[celli])/mag(D[celli]);
670 
671  if (d > 0)
672  {
673  nNon++;
674  maxNon = max(maxNon, d);
675  sumNon += d;
676  }
677  }
678 
679  reduce(nNon, sumOp<label>(), UPstream::msgType(), psi_.mesh().comm());
680  reduce
681  (
682  maxNon,
683  maxOp<scalar>(),
685  psi_.mesh().comm()
686  );
687  reduce
688  (
689  sumNon,
690  sumOp<scalar>(),
692  psi_.mesh().comm()
693  );
694  sumNon /= returnReduce
695  (
696  D.size(),
697  sumOp<label>(),
699  psi_.mesh().comm()
700  );
701 
703  << "Matrix dominance test for " << psi_.name() << nl
704  << " number of non-dominant cells : " << nNon << nl
705  << " maximum relative non-dominance : " << maxNon << nl
706  << " average relative non-dominance : " << sumNon << nl
707  << endl;
708  }
709 
710 
711  // Ensure the matrix is diagonally dominant...
712  // Assumes that the central coefficient is positive and ensures it is
713  forAll(D, celli)
714  {
715  D[celli] = max(mag(D[celli]), sumOff[celli]);
716  }
717 
718  // ... then relax
719  D /= alpha;
720 
721  // Now remove the diagonal contribution from coupled boundaries
722  forAll(psi_.boundaryField(), patchi)
723  {
724  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
725 
726  if (ptf.size())
727  {
728  const labelUList& pa = lduAddr().patchAddr(patchi);
729  Field<Type>& iCoeffs = internalCoeffs_[patchi];
730 
731  if (ptf.coupled())
732  {
733  forAll(pa, face)
734  {
735  D[pa[face]] -= component(iCoeffs[face], 0);
736  }
737  }
738  else
739  {
740  forAll(pa, face)
741  {
742  D[pa[face]] -= cmptMin(iCoeffs[face]);
743  }
744  }
745  }
746  }
747 
748  // Finally add the relaxation contribution to the source.
749  S += (D - D0)*psi_.primitiveField();
750 }
751 
752 
753 template<class Type>
755 {
756  relax(relaxationFactor());
757 }
758 
759 
760 template<class Type>
762 (
763  typename VolField<Type>::
764  Boundary& bFields
765 )
766 {
767  forAll(bFields, patchi)
768  {
769  bFields[patchi].manipulateMatrix(*this);
770  }
771 }
772 
773 
774 template<class Type>
776 {
777  tmp<scalarField> tdiag(new scalarField(diag()));
778  addCmptAvBoundaryDiag(tdiag.ref());
779  return tdiag;
780 }
781 
782 
783 template<class Type>
785 {
787 
788  forAll(psi_.boundaryField(), patchi)
789  {
790  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
791 
792  if (!ptf.coupled() && ptf.size())
793  {
794  addToInternalField
795  (
796  lduAddr().patchAddr(patchi),
797  internalCoeffs_[patchi],
798  tdiag.ref()
799  );
800  }
801  }
802 
803  return tdiag;
804 }
805 
806 
807 template<class Type>
809 {
810  tmp<volScalarField> tAphi
811  (
813  (
814  "A(" + psi_.name() + ')',
815  psi_.mesh(),
816  dimensions_/psi_.dimensions()/dimVolume,
817  extrapolatedCalculatedFvPatchScalarField::typeName
818  )
819  );
820 
821  tAphi.ref().primitiveFieldRef() = D()/psi_.mesh().V();
822  tAphi.ref().correctBoundaryConditions();
823 
824  return tAphi;
825 }
826 
827 
828 template<class Type>
830 {
832  (
834  (
835  "Su(" +psi_.name() + ')',
836  psi_.mesh(),
837  dimensions_/dimVolume,
838  -source()/psi_.mesh().V()
839  )
840  );
841 
842  return tSu;
843 }
844 
845 
846 template<class Type>
848 {
850  (
852  (
853  "Sp(" + psi_.name() + ')',
854  psi_.mesh(),
855  dimensions_/psi_.dimensions()/dimVolume,
856  hasDiag()
857  ? diag()/psi_.mesh().V()
858  : tmp<scalarField>(new scalarField(lduAddr().size(), scalar(0)))
859  )
860  );
861 
862  return tSp;
863 }
864 
865 
866 template<class Type>
869 {
870  tmp<VolField<Type>> tHphi
871  (
873  (
874  "H(" + psi_.name() + ')',
875  psi_.mesh(),
876  dimensions_/dimVolume,
877  extrapolatedCalculatedFvPatchScalarField::typeName
878  )
879  );
880  VolField<Type>& Hphi = tHphi.ref();
881 
882  // Loop over field components
883  for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
884  {
885  scalarField psiCmpt(psi_.primitiveField().component(cmpt));
886 
887  scalarField boundaryDiagCmpt(psi_.size(), 0.0);
888  addBoundaryDiag(boundaryDiagCmpt, cmpt);
889  boundaryDiagCmpt.negate();
890  addCmptAvBoundaryDiag(boundaryDiagCmpt);
891 
892  Hphi.primitiveFieldRef().replace(cmpt, boundaryDiagCmpt*psiCmpt);
893  }
894 
895  Hphi.primitiveFieldRef() += lduMatrix::H(psi_.primitiveField()) + source_;
896  addBoundarySource(Hphi.primitiveFieldRef());
897 
898  Hphi.primitiveFieldRef() /= psi_.mesh().V();
900 
901  typename Type::labelType validComponents
902  (
903  psi_.mesh().template validComponents<Type>()
904  );
905 
906  for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
907  {
908  if (validComponents[cmpt] == -1)
909  {
910  Hphi.replace
911  (
912  cmpt,
913  dimensionedScalar(Hphi.dimensions(), 0)
914  );
915  }
916  }
917 
918  return tHphi;
919 }
920 
921 
922 template<class Type>
924 {
926  (
928  (
929  "H(1)",
930  psi_.mesh(),
931  dimensions_/(dimVolume*psi_.dimensions()),
932  extrapolatedCalculatedFvPatchScalarField::typeName
933  )
934  );
935  volScalarField& H1_ = tH1.ref();
936 
938 
939  forAll(psi_.boundaryField(), patchi)
940  {
941  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
942 
943  if (ptf.coupled() && ptf.size())
944  {
945  addToInternalField
946  (
947  lduAddr().patchAddr(patchi),
948  boundaryCoeffs_[patchi].component(0),
949  H1_
950  );
951  }
952  }
953 
954  H1_.primitiveFieldRef() /= psi_.mesh().V();
956 
957  return tH1;
958 }
959 
960 
961 template<class Type>
964 flux() const
965 {
966  if (!psi_.mesh().schemes().fluxRequired(psi_.name()))
967  {
969  << "flux requested but " << psi_.name()
970  << " not specified in the fluxRequired sub-dictionary"
971  " of fvSchemes."
972  << abort(FatalError);
973  }
974 
975  // construct SurfaceField<Type>
976  tmp<SurfaceField<Type>> tfieldFlux
977  (
979  (
980  "flux(" + psi_.name() + ')',
981  psi_.mesh(),
982  dimensions()
983  )
984  );
985  SurfaceField<Type>& fieldFlux =
986  tfieldFlux.ref();
987 
988  for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
989  {
990  fieldFlux.primitiveFieldRef().replace
991  (
992  cmpt,
993  lduMatrix::faceH(psi_.primitiveField().component(cmpt))
994  );
995  }
996 
997  FieldField<Field, Type> InternalContrib = internalCoeffs_;
998 
999  forAll(InternalContrib, patchi)
1000  {
1001  InternalContrib[patchi] =
1002  cmptMultiply
1003  (
1004  InternalContrib[patchi],
1005  psi_.boundaryField()[patchi].patchInternalField()
1006  );
1007  }
1008 
1009  FieldField<Field, Type> NeighbourContrib = boundaryCoeffs_;
1010 
1011  forAll(NeighbourContrib, patchi)
1012  {
1013  if (psi_.boundaryField()[patchi].coupled())
1014  {
1015  NeighbourContrib[patchi] =
1016  cmptMultiply
1017  (
1018  NeighbourContrib[patchi],
1019  psi_.boundaryField()[patchi].patchNeighbourField()
1020  );
1021  }
1022  }
1023 
1024  typename SurfaceField<Type>::
1025  Boundary& ffbf = fieldFlux.boundaryFieldRef();
1026 
1027  forAll(ffbf, patchi)
1028  {
1029  ffbf[patchi] = InternalContrib[patchi] - NeighbourContrib[patchi];
1030  }
1031 
1032  if (faceFluxCorrectionPtr_)
1033  {
1034  fieldFlux += *faceFluxCorrectionPtr_;
1035  }
1036 
1037  return tfieldFlux;
1038 }
1039 
1040 
1041 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1042 
1043 template<class Type>
1045 {
1046  if (this == &fvmv)
1047  {
1049  << "attempted assignment to self"
1050  << abort(FatalError);
1051  }
1052 
1053  if (&psi_ != &(fvmv.psi_))
1054  {
1056  << "different fields"
1057  << abort(FatalError);
1058  }
1059 
1060  dimensions_ = fvmv.dimensions_;
1061  lduMatrix::operator=(fvmv);
1062  source_ = fvmv.source_;
1063  internalCoeffs_ = fvmv.internalCoeffs_;
1064  boundaryCoeffs_ = fvmv.boundaryCoeffs_;
1065 
1066  if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
1067  {
1068  *faceFluxCorrectionPtr_ = *fvmv.faceFluxCorrectionPtr_;
1069  }
1070  else if (fvmv.faceFluxCorrectionPtr_)
1071  {
1072  faceFluxCorrectionPtr_ =
1073  new SurfaceField<Type>
1074  (*fvmv.faceFluxCorrectionPtr_);
1075  }
1076 }
1077 
1078 
1079 template<class Type>
1081 {
1082  operator=(tfvmv());
1083  tfvmv.clear();
1084 }
1085 
1086 
1087 template<class Type>
1089 {
1091  source_.negate();
1092  internalCoeffs_.negate();
1093  boundaryCoeffs_.negate();
1094 
1095  if (faceFluxCorrectionPtr_)
1096  {
1097  faceFluxCorrectionPtr_->negate();
1098  }
1099 }
1100 
1101 
1102 template<class Type>
1104 {
1105  checkMethod(*this, fvmv, "+=");
1106 
1107  dimensions_ += fvmv.dimensions_;
1108  lduMatrix::operator+=(fvmv);
1109  source_ += fvmv.source_;
1110  internalCoeffs_ += fvmv.internalCoeffs_;
1111  boundaryCoeffs_ += fvmv.boundaryCoeffs_;
1112 
1113  if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
1114  {
1115  *faceFluxCorrectionPtr_ += *fvmv.faceFluxCorrectionPtr_;
1116  }
1117  else if (fvmv.faceFluxCorrectionPtr_)
1118  {
1119  faceFluxCorrectionPtr_ = new
1121  (
1122  *fvmv.faceFluxCorrectionPtr_
1123  );
1124  }
1125 }
1126 
1127 
1128 template<class Type>
1130 {
1131  operator+=(tfvmv());
1132  tfvmv.clear();
1133 }
1134 
1135 
1136 template<class Type>
1138 {
1139  checkMethod(*this, fvmv, "-=");
1140 
1141  dimensions_ -= fvmv.dimensions_;
1142  lduMatrix::operator-=(fvmv);
1143  source_ -= fvmv.source_;
1144  internalCoeffs_ -= fvmv.internalCoeffs_;
1145  boundaryCoeffs_ -= fvmv.boundaryCoeffs_;
1146 
1147  if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
1148  {
1149  *faceFluxCorrectionPtr_ -= *fvmv.faceFluxCorrectionPtr_;
1150  }
1151  else if (fvmv.faceFluxCorrectionPtr_)
1152  {
1153  faceFluxCorrectionPtr_ =
1154  new SurfaceField<Type>
1155  (-*fvmv.faceFluxCorrectionPtr_);
1156  }
1157 }
1158 
1159 
1160 template<class Type>
1162 {
1163  operator-=(tfvmv());
1164  tfvmv.clear();
1165 }
1166 
1167 
1168 template<class Type>
1170 (
1172 )
1173 {
1174  checkMethod(*this, su, "+=");
1175  source() -= su.mesh().V()*su.primitiveField();
1176 }
1177 
1178 
1179 template<class Type>
1181 (
1183 )
1184 {
1185  operator+=(tsu());
1186  tsu.clear();
1187 }
1188 
1189 
1190 template<class Type>
1192 (
1193  const tmp<VolField<Type>>& tsu
1194 )
1195 {
1196  operator+=(tsu());
1197  tsu.clear();
1198 }
1199 
1200 
1201 template<class Type>
1203 (
1205 )
1206 {
1207  checkMethod(*this, su, "-=");
1208  source() += su.mesh().V()*su.primitiveField();
1209 }
1210 
1211 
1212 template<class Type>
1214 (
1216 )
1217 {
1218  operator-=(tsu());
1219  tsu.clear();
1220 }
1221 
1222 
1223 template<class Type>
1225 (
1226  const tmp<VolField<Type>>& tsu
1227 )
1228 {
1229  operator-=(tsu());
1230  tsu.clear();
1231 }
1232 
1233 
1234 template<class Type>
1236 (
1237  const dimensioned<Type>& su
1238 )
1239 {
1240  source() -= psi().mesh().V()*su;
1241 }
1242 
1243 
1244 template<class Type>
1246 (
1247  const dimensioned<Type>& su
1248 )
1249 {
1250  source() += psi().mesh().V()*su;
1251 }
1252 
1253 
1254 template<class Type>
1256 (
1257  const zero&
1258 )
1259 {}
1260 
1261 
1262 template<class Type>
1264 (
1265  const zero&
1266 )
1267 {}
1268 
1269 
1270 template<class Type>
1272 (
1273  const volScalarField::Internal& dsf
1274 )
1275 {
1276  dimensions_ *= dsf.dimensions();
1277  lduMatrix::operator*=(dsf.primitiveField());
1278  source_ *= dsf.primitiveField();
1279 
1280  forAll(boundaryCoeffs_, patchi)
1281  {
1282  scalarField pisf
1283  (
1284  dsf.mesh().boundary()[patchi].patchInternalField
1285  (
1286  dsf.primitiveField()
1287  )
1288  );
1289 
1290  internalCoeffs_[patchi] *= pisf;
1291  boundaryCoeffs_[patchi] *= pisf;
1292  }
1293 
1294  if (faceFluxCorrectionPtr_)
1295  {
1297  << "cannot scale a matrix containing a faceFluxCorrection"
1298  << abort(FatalError);
1299  }
1300 }
1301 
1302 
1303 template<class Type>
1305 (
1306  const tmp<volScalarField::Internal>& tdsf
1307 )
1308 {
1309  operator*=(tdsf());
1310  tdsf.clear();
1311 }
1312 
1313 
1314 template<class Type>
1316 (
1317  const tmp<volScalarField>& tvsf
1318 )
1319 {
1320  operator*=(tvsf());
1321  tvsf.clear();
1322 }
1323 
1324 
1325 template<class Type>
1327 (
1328  const dimensioned<scalar>& ds
1329 )
1330 {
1331  dimensions_ *= ds.dimensions();
1332  lduMatrix::operator*=(ds.value());
1333  source_ *= ds.value();
1334  internalCoeffs_ *= ds.value();
1335  boundaryCoeffs_ *= ds.value();
1336 
1337  if (faceFluxCorrectionPtr_)
1338  {
1339  *faceFluxCorrectionPtr_ *= ds.value();
1340  }
1341 }
1342 
1343 
1344 template<class Type>
1346 (
1347  const volScalarField::Internal& dsf
1348 )
1349 {
1350  dimensions_ /= dsf.dimensions();
1351  lduMatrix::operator/=(dsf.primitiveField());
1352  source_ /= dsf.primitiveField();
1353 
1354  forAll(boundaryCoeffs_, patchi)
1355  {
1356  scalarField pisf
1357  (
1358  dsf.mesh().boundary()[patchi].patchInternalField
1359  (
1360  dsf.primitiveField()
1361  )
1362  );
1363 
1364  internalCoeffs_[patchi] /= pisf;
1365  boundaryCoeffs_[patchi] /= pisf;
1366  }
1367 
1368  if (faceFluxCorrectionPtr_)
1369  {
1371  << "cannot scale a matrix containing a faceFluxCorrection"
1372  << abort(FatalError);
1373  }
1374 }
1375 
1376 
1377 template<class Type>
1379 (
1380  const tmp<volScalarField::Internal>& tdsf
1381 )
1382 {
1383  operator/=(tdsf());
1384  tdsf.clear();
1385 }
1386 
1387 
1388 template<class Type>
1390 (
1391  const tmp<volScalarField>& tvsf
1392 )
1393 {
1394  operator/=(tvsf());
1395  tvsf.clear();
1396 }
1397 
1398 
1399 template<class Type>
1401 (
1402  const dimensioned<scalar>& ds
1403 )
1404 {
1405  dimensions_ /= ds.dimensions();
1406  lduMatrix::operator/=(ds.value());
1407  source_ /= ds.value();
1408  internalCoeffs_ /= ds.value();
1409  boundaryCoeffs_ /= ds.value();
1410 
1411  if (faceFluxCorrectionPtr_)
1412  {
1413  *faceFluxCorrectionPtr_ /= ds.value();
1414  }
1415 }
1416 
1417 
1418 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
1419 
1420 template<class Type>
1422 (
1423  const fvMatrix<Type>& fvm1,
1424  const fvMatrix<Type>& fvm2,
1425  const char* op
1426 )
1427 {
1428  if (&fvm1.psi() != &fvm2.psi())
1429  {
1431  << "incompatible fields for operation "
1432  << endl << " "
1433  << "[" << fvm1.psi().name() << "] "
1434  << op
1435  << " [" << fvm2.psi().name() << "]"
1436  << abort(FatalError);
1437  }
1438 
1439  if (dimensionSet::debug && fvm1.dimensions() != fvm2.dimensions())
1440  {
1442  << "incompatible dimensions for operation "
1443  << endl << " "
1444  << "[" << fvm1.psi().name() << fvm1.dimensions()/dimVolume << " ] "
1445  << op
1446  << " [" << fvm2.psi().name() << fvm2.dimensions()/dimVolume << " ]"
1447  << abort(FatalError);
1448  }
1449 }
1450 
1451 
1452 template<class Type>
1454 (
1455  const fvMatrix<Type>& fvm,
1457  const char* op
1458 )
1459 {
1460  if (dimensionSet::debug && fvm.dimensions()/dimVolume != df.dimensions())
1461  {
1463  << endl << " "
1464  << "[" << fvm.psi().name() << fvm.dimensions()/dimVolume << " ] "
1465  << op
1466  << " [" << df.name() << df.dimensions() << " ]"
1467  << abort(FatalError);
1468  }
1469 }
1470 
1471 
1472 template<class Type>
1474 (
1475  const fvMatrix<Type>& fvm,
1476  const dimensioned<Type>& dt,
1477  const char* op
1478 )
1479 {
1480  if (dimensionSet::debug && fvm.dimensions()/dimVolume != dt.dimensions())
1481  {
1483  << "incompatible dimensions for operation "
1484  << endl << " "
1485  << "[" << fvm.psi().name() << fvm.dimensions()/dimVolume << " ] "
1486  << op
1487  << " [" << dt.name() << dt.dimensions() << " ]"
1488  << abort(FatalError);
1489  }
1490 }
1491 
1492 
1493 template<class Type>
1495 (
1496  const fvMatrix<Type>& A
1497 )
1498 {
1499  tmp<Foam::fvMatrix<Type>> tAcorr = A - (A & A.psi());
1500 
1501  // Delete the faceFluxCorrection from the correction matrix
1502  // as it does not have a clear meaning or purpose
1503  deleteDemandDrivenData(tAcorr.ref().faceFluxCorrectionPtr());
1504 
1505  return tAcorr;
1506 }
1507 
1508 
1509 template<class Type>
1511 (
1512  const tmp<fvMatrix<Type>>& tA
1513 )
1514 {
1515  tmp<Foam::fvMatrix<Type>> tAcorr = tA - (tA() & tA().psi());
1516 
1517  // Delete the faceFluxCorrection from the correction matrix
1518  // as it does not have a clear meaning or purpose
1519  deleteDemandDrivenData(tAcorr.ref().faceFluxCorrectionPtr());
1520 
1521  return tAcorr;
1522 }
1523 
1524 
1525 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
1526 
1527 template<class Type>
1528 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1529 (
1530  const fvMatrix<Type>& A,
1531  const fvMatrix<Type>& B
1532 )
1533 {
1534  checkMethod(A, B, "==");
1535  return (A - B);
1536 }
1537 
1538 template<class Type>
1539 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1540 (
1541  const tmp<fvMatrix<Type>>& tA,
1542  const fvMatrix<Type>& B
1543 )
1544 {
1545  checkMethod(tA(), B, "==");
1546  return (tA - B);
1547 }
1548 
1549 template<class Type>
1550 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1551 (
1552  const fvMatrix<Type>& A,
1553  const tmp<fvMatrix<Type>>& tB
1554 )
1555 {
1556  checkMethod(A, tB(), "==");
1557  return (A - tB);
1558 }
1559 
1560 template<class Type>
1561 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1562 (
1563  const tmp<fvMatrix<Type>>& tA,
1564  const tmp<fvMatrix<Type>>& tB
1565 )
1566 {
1567  checkMethod(tA(), tB(), "==");
1568  return (tA - tB);
1569 }
1570 
1571 template<class Type>
1572 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1573 (
1574  const fvMatrix<Type>& A,
1575  const DimensionedField<Type, volMesh>& su
1576 )
1577 {
1578  checkMethod(A, su, "==");
1579  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1580  tC.ref().source() += su.mesh().V()*su.primitiveField();
1581  return tC;
1582 }
1583 
1584 template<class Type>
1585 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1586 (
1587  const fvMatrix<Type>& A,
1588  const tmp<DimensionedField<Type, volMesh>>& tsu
1589 )
1590 {
1591  checkMethod(A, tsu(), "==");
1592  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1593  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
1594  tsu.clear();
1595  return tC;
1596 }
1597 
1598 template<class Type>
1599 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1600 (
1601  const fvMatrix<Type>& A,
1602  const tmp<VolField<Type>>& tsu
1603 )
1604 {
1605  checkMethod(A, tsu(), "==");
1606  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1607  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
1608  tsu.clear();
1609  return tC;
1610 }
1611 
1612 template<class Type>
1613 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1614 (
1615  const tmp<fvMatrix<Type>>& tA,
1616  const DimensionedField<Type, volMesh>& su
1617 )
1618 {
1619  checkMethod(tA(), su, "==");
1620  tmp<fvMatrix<Type>> tC(tA.ptr());
1621  tC.ref().source() += su.mesh().V()*su.primitiveField();
1622  return tC;
1623 }
1624 
1625 template<class Type>
1626 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1627 (
1628  const tmp<fvMatrix<Type>>& tA,
1629  const tmp<DimensionedField<Type, volMesh>>& tsu
1630 )
1631 {
1632  checkMethod(tA(), tsu(), "==");
1633  tmp<fvMatrix<Type>> tC(tA.ptr());
1634  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
1635  tsu.clear();
1636  return tC;
1637 }
1638 
1639 template<class Type>
1640 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1641 (
1642  const tmp<fvMatrix<Type>>& tA,
1643  const tmp<VolField<Type>>& tsu
1644 )
1645 {
1646  checkMethod(tA(), tsu(), "==");
1647  tmp<fvMatrix<Type>> tC(tA.ptr());
1648  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
1649  tsu.clear();
1650  return tC;
1651 }
1652 
1653 template<class Type>
1654 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1655 (
1656  const fvMatrix<Type>& A,
1657  const dimensioned<Type>& su
1658 )
1659 {
1660  checkMethod(A, su, "==");
1661  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1662  tC.ref().source() += A.psi().mesh().V()*su.value();
1663  return tC;
1664 }
1665 
1666 template<class Type>
1667 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1668 (
1669  const tmp<fvMatrix<Type>>& tA,
1670  const dimensioned<Type>& su
1671 )
1672 {
1673  checkMethod(tA(), su, "==");
1674  tmp<fvMatrix<Type>> tC(tA.ptr());
1675  tC.ref().source() += tC().psi().mesh().V()*su.value();
1676  return tC;
1677 }
1678 
1679 template<class Type>
1680 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1681 (
1682  const fvMatrix<Type>& A,
1683  const zero&
1684 )
1685 {
1686  return A;
1687 }
1688 
1689 
1690 template<class Type>
1691 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1692 (
1693  const tmp<fvMatrix<Type>>& tA,
1694  const zero&
1695 )
1696 {
1697  return tA;
1698 }
1699 
1700 
1701 template<class Type>
1702 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1703 (
1704  const fvMatrix<Type>& A
1705 )
1706 {
1707  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1708  tC.ref().negate();
1709  return tC;
1710 }
1711 
1712 template<class Type>
1713 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1714 (
1715  const tmp<fvMatrix<Type>>& tA
1716 )
1717 {
1718  tmp<fvMatrix<Type>> tC(tA.ptr());
1719  tC.ref().negate();
1720  return tC;
1721 }
1722 
1723 
1724 template<class Type>
1725 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1726 (
1727  const fvMatrix<Type>& A,
1728  const fvMatrix<Type>& B
1729 )
1730 {
1731  checkMethod(A, B, "+");
1732  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1733  tC.ref() += B;
1734  return tC;
1735 }
1736 
1737 template<class Type>
1738 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1739 (
1740  const tmp<fvMatrix<Type>>& tA,
1741  const fvMatrix<Type>& B
1742 )
1743 {
1744  checkMethod(tA(), B, "+");
1745  tmp<fvMatrix<Type>> tC(tA.ptr());
1746  tC.ref() += B;
1747  return tC;
1748 }
1749 
1750 template<class Type>
1751 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1752 (
1753  const fvMatrix<Type>& A,
1754  const tmp<fvMatrix<Type>>& tB
1755 )
1756 {
1757  checkMethod(A, tB(), "+");
1758  tmp<fvMatrix<Type>> tC(tB.ptr());
1759  tC.ref() += A;
1760  return tC;
1761 }
1762 
1763 template<class Type>
1764 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1765 (
1766  const tmp<fvMatrix<Type>>& tA,
1767  const tmp<fvMatrix<Type>>& tB
1768 )
1769 {
1770  checkMethod(tA(), tB(), "+");
1771  tmp<fvMatrix<Type>> tC(tA.ptr());
1772  tC.ref() += tB();
1773  tB.clear();
1774  return tC;
1775 }
1776 
1777 template<class Type>
1778 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1779 (
1780  const fvMatrix<Type>& A,
1781  const DimensionedField<Type, volMesh>& su
1782 )
1783 {
1784  checkMethod(A, su, "+");
1785  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1786  tC.ref().source() -= su.mesh().V()*su.primitiveField();
1787  return tC;
1788 }
1789 
1790 template<class Type>
1791 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1792 (
1793  const fvMatrix<Type>& A,
1794  const tmp<DimensionedField<Type, volMesh>>& tsu
1795 )
1796 {
1797  checkMethod(A, tsu(), "+");
1798  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1799  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1800  tsu.clear();
1801  return tC;
1802 }
1803 
1804 template<class Type>
1805 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1806 (
1807  const fvMatrix<Type>& A,
1808  const tmp<VolField<Type>>& tsu
1809 )
1810 {
1811  checkMethod(A, tsu(), "+");
1812  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1813  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1814  tsu.clear();
1815  return tC;
1816 }
1817 
1818 template<class Type>
1819 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1820 (
1821  const tmp<fvMatrix<Type>>& tA,
1822  const DimensionedField<Type, volMesh>& su
1823 )
1824 {
1825  checkMethod(tA(), su, "+");
1826  tmp<fvMatrix<Type>> tC(tA.ptr());
1827  tC.ref().source() -= su.mesh().V()*su.primitiveField();
1828  return tC;
1829 }
1830 
1831 template<class Type>
1832 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1833 (
1834  const tmp<fvMatrix<Type>>& tA,
1835  const tmp<DimensionedField<Type, volMesh>>& tsu
1836 )
1837 {
1838  checkMethod(tA(), tsu(), "+");
1839  tmp<fvMatrix<Type>> tC(tA.ptr());
1840  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1841  tsu.clear();
1842  return tC;
1843 }
1844 
1845 template<class Type>
1846 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1847 (
1848  const tmp<fvMatrix<Type>>& tA,
1849  const tmp<VolField<Type>>& tsu
1850 )
1851 {
1852  checkMethod(tA(), tsu(), "+");
1853  tmp<fvMatrix<Type>> tC(tA.ptr());
1854  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1855  tsu.clear();
1856  return tC;
1857 }
1858 
1859 template<class Type>
1860 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1861 (
1862  const DimensionedField<Type, volMesh>& su,
1863  const fvMatrix<Type>& A
1864 )
1865 {
1866  checkMethod(A, su, "+");
1867  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1868  tC.ref().source() -= su.mesh().V()*su.primitiveField();
1869  return tC;
1870 }
1871 
1872 template<class Type>
1873 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1874 (
1875  const tmp<DimensionedField<Type, volMesh>>& tsu,
1876  const fvMatrix<Type>& A
1877 )
1878 {
1879  checkMethod(A, tsu(), "+");
1880  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1881  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1882  tsu.clear();
1883  return tC;
1884 }
1885 
1886 template<class Type>
1887 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1888 (
1889  const tmp<VolField<Type>>& tsu,
1890  const fvMatrix<Type>& A
1891 )
1892 {
1893  checkMethod(A, tsu(), "+");
1894  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1895  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1896  tsu.clear();
1897  return tC;
1898 }
1899 
1900 template<class Type>
1901 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1902 (
1903  const DimensionedField<Type, volMesh>& su,
1904  const tmp<fvMatrix<Type>>& tA
1905 )
1906 {
1907  checkMethod(tA(), su, "+");
1908  tmp<fvMatrix<Type>> tC(tA.ptr());
1909  tC.ref().source() -= su.mesh().V()*su.primitiveField();
1910  return tC;
1911 }
1912 
1913 template<class Type>
1914 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1915 (
1916  const tmp<DimensionedField<Type, volMesh>>& tsu,
1917  const tmp<fvMatrix<Type>>& tA
1918 )
1919 {
1920  checkMethod(tA(), tsu(), "+");
1921  tmp<fvMatrix<Type>> tC(tA.ptr());
1922  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1923  tsu.clear();
1924  return tC;
1925 }
1926 
1927 template<class Type>
1928 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1929 (
1930  const tmp<VolField<Type>>& tsu,
1931  const tmp<fvMatrix<Type>>& tA
1932 )
1933 {
1934  checkMethod(tA(), tsu(), "+");
1935  tmp<fvMatrix<Type>> tC(tA.ptr());
1936  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1937  tsu.clear();
1938  return tC;
1939 }
1940 
1941 
1942 template<class Type>
1943 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1944 (
1945  const fvMatrix<Type>& A,
1946  const fvMatrix<Type>& B
1947 )
1948 {
1949  checkMethod(A, B, "-");
1950  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1951  tC.ref() -= B;
1952  return tC;
1953 }
1954 
1955 template<class Type>
1956 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1957 (
1958  const tmp<fvMatrix<Type>>& tA,
1959  const fvMatrix<Type>& B
1960 )
1961 {
1962  checkMethod(tA(), B, "-");
1963  tmp<fvMatrix<Type>> tC(tA.ptr());
1964  tC.ref() -= B;
1965  return tC;
1966 }
1967 
1968 template<class Type>
1969 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1970 (
1971  const fvMatrix<Type>& A,
1972  const tmp<fvMatrix<Type>>& tB
1973 )
1974 {
1975  checkMethod(A, tB(), "-");
1976  tmp<fvMatrix<Type>> tC(tB.ptr());
1977  tC.ref() -= A;
1978  tC.ref().negate();
1979  return tC;
1980 }
1981 
1982 template<class Type>
1983 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1984 (
1985  const tmp<fvMatrix<Type>>& tA,
1986  const tmp<fvMatrix<Type>>& tB
1987 )
1988 {
1989  checkMethod(tA(), tB(), "-");
1990  tmp<fvMatrix<Type>> tC(tA.ptr());
1991  tC.ref() -= tB();
1992  tB.clear();
1993  return tC;
1994 }
1995 
1996 template<class Type>
1997 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1998 (
1999  const fvMatrix<Type>& A,
2000  const DimensionedField<Type, volMesh>& su
2001 )
2002 {
2003  checkMethod(A, su, "-");
2004  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2005  tC.ref().source() += su.mesh().V()*su.primitiveField();
2006  return tC;
2007 }
2008 
2009 template<class Type>
2010 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2011 (
2012  const fvMatrix<Type>& A,
2013  const tmp<DimensionedField<Type, volMesh>>& tsu
2014 )
2015 {
2016  checkMethod(A, tsu(), "-");
2017  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2018  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
2019  tsu.clear();
2020  return tC;
2021 }
2022 
2023 template<class Type>
2024 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2025 (
2026  const fvMatrix<Type>& A,
2027  const tmp<VolField<Type>>& tsu
2028 )
2029 {
2030  checkMethod(A, tsu(), "-");
2031  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2032  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
2033  tsu.clear();
2034  return tC;
2035 }
2036 
2037 template<class Type>
2038 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2039 (
2040  const tmp<fvMatrix<Type>>& tA,
2041  const DimensionedField<Type, volMesh>& su
2042 )
2043 {
2044  checkMethod(tA(), su, "-");
2045  tmp<fvMatrix<Type>> tC(tA.ptr());
2046  tC.ref().source() += su.mesh().V()*su.primitiveField();
2047  return tC;
2048 }
2049 
2050 template<class Type>
2051 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2052 (
2053  const tmp<fvMatrix<Type>>& tA,
2054  const tmp<DimensionedField<Type, volMesh>>& tsu
2055 )
2056 {
2057  checkMethod(tA(), tsu(), "-");
2058  tmp<fvMatrix<Type>> tC(tA.ptr());
2059  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
2060  tsu.clear();
2061  return tC;
2062 }
2063 
2064 template<class Type>
2065 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2066 (
2067  const tmp<fvMatrix<Type>>& tA,
2068  const tmp<VolField<Type>>& tsu
2069 )
2070 {
2071  checkMethod(tA(), tsu(), "-");
2072  tmp<fvMatrix<Type>> tC(tA.ptr());
2073  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
2074  tsu.clear();
2075  return tC;
2076 }
2077 
2078 template<class Type>
2079 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2080 (
2081  const DimensionedField<Type, volMesh>& su,
2082  const fvMatrix<Type>& A
2083 )
2084 {
2085  checkMethod(A, su, "-");
2086  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2087  tC.ref().negate();
2088  tC.ref().source() -= su.mesh().V()*su.primitiveField();
2089  return tC;
2090 }
2091 
2092 template<class Type>
2093 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2094 (
2095  const tmp<DimensionedField<Type, volMesh>>& tsu,
2096  const fvMatrix<Type>& A
2097 )
2098 {
2099  checkMethod(A, tsu(), "-");
2100  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2101  tC.ref().negate();
2102  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
2103  tsu.clear();
2104  return tC;
2105 }
2106 
2107 template<class Type>
2108 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2109 (
2110  const tmp<VolField<Type>>& tsu,
2111  const fvMatrix<Type>& A
2112 )
2113 {
2114  checkMethod(A, tsu(), "-");
2115  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2116  tC.ref().negate();
2117  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
2118  tsu.clear();
2119  return tC;
2120 }
2121 
2122 template<class Type>
2123 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2124 (
2125  const DimensionedField<Type, volMesh>& su,
2126  const tmp<fvMatrix<Type>>& tA
2127 )
2128 {
2129  checkMethod(tA(), su, "-");
2130  tmp<fvMatrix<Type>> tC(tA.ptr());
2131  tC.ref().negate();
2132  tC.ref().source() -= su.mesh().V()*su.primitiveField();
2133  return tC;
2134 }
2135 
2136 template<class Type>
2137 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2138 (
2139  const tmp<DimensionedField<Type, volMesh>>& tsu,
2140  const tmp<fvMatrix<Type>>& tA
2141 )
2142 {
2143  checkMethod(tA(), tsu(), "-");
2144  tmp<fvMatrix<Type>> tC(tA.ptr());
2145  tC.ref().negate();
2146  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
2147  tsu.clear();
2148  return tC;
2149 }
2150 
2151 template<class Type>
2152 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2153 (
2154  const tmp<VolField<Type>>& tsu,
2155  const tmp<fvMatrix<Type>>& tA
2156 )
2157 {
2158  checkMethod(tA(), tsu(), "-");
2159  tmp<fvMatrix<Type>> tC(tA.ptr());
2160  tC.ref().negate();
2161  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
2162  tsu.clear();
2163  return tC;
2164 }
2165 
2166 template<class Type>
2167 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2168 (
2169  const fvMatrix<Type>& A,
2170  const dimensioned<Type>& su
2171 )
2172 {
2173  checkMethod(A, su, "+");
2174  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2175  tC.ref().source() -= su.value()*A.psi().mesh().V();
2176  return tC;
2177 }
2178 
2179 template<class Type>
2180 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2181 (
2182  const tmp<fvMatrix<Type>>& tA,
2183  const dimensioned<Type>& su
2184 )
2185 {
2186  checkMethod(tA(), su, "+");
2187  tmp<fvMatrix<Type>> tC(tA.ptr());
2188  tC.ref().source() -= su.value()*tC().psi().mesh().V();
2189  return tC;
2190 }
2191 
2192 template<class Type>
2193 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2194 (
2195  const dimensioned<Type>& su,
2196  const fvMatrix<Type>& A
2197 )
2198 {
2199  checkMethod(A, su, "+");
2200  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2201  tC.ref().source() -= su.value()*A.psi().mesh().V();
2202  return tC;
2203 }
2204 
2205 template<class Type>
2206 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2207 (
2208  const dimensioned<Type>& su,
2209  const tmp<fvMatrix<Type>>& tA
2210 )
2211 {
2212  checkMethod(tA(), su, "+");
2213  tmp<fvMatrix<Type>> tC(tA.ptr());
2214  tC.ref().source() -= su.value()*tC().psi().mesh().V();
2215  return tC;
2216 }
2217 
2218 template<class Type>
2219 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2220 (
2221  const fvMatrix<Type>& A,
2222  const dimensioned<Type>& su
2223 )
2224 {
2225  checkMethod(A, su, "-");
2226  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2227  tC.ref().source() += su.value()*tC().psi().mesh().V();
2228  return tC;
2229 }
2230 
2231 template<class Type>
2232 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2233 (
2234  const tmp<fvMatrix<Type>>& tA,
2235  const dimensioned<Type>& su
2236 )
2237 {
2238  checkMethod(tA(), su, "-");
2239  tmp<fvMatrix<Type>> tC(tA.ptr());
2240  tC.ref().source() += su.value()*tC().psi().mesh().V();
2241  return tC;
2242 }
2243 
2244 template<class Type>
2245 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2246 (
2247  const dimensioned<Type>& su,
2248  const fvMatrix<Type>& A
2249 )
2250 {
2251  checkMethod(A, su, "-");
2252  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2253  tC.ref().negate();
2254  tC.ref().source() -= su.value()*A.psi().mesh().V();
2255  return tC;
2256 }
2257 
2258 template<class Type>
2259 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2260 (
2261  const dimensioned<Type>& su,
2262  const tmp<fvMatrix<Type>>& tA
2263 )
2264 {
2265  checkMethod(tA(), su, "-");
2266  tmp<fvMatrix<Type>> tC(tA.ptr());
2267  tC.ref().negate();
2268  tC.ref().source() -= su.value()*tC().psi().mesh().V();
2269  return tC;
2270 }
2271 
2272 
2273 template<class Type>
2274 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2275 (
2276  const volScalarField::Internal& dsf,
2277  const fvMatrix<Type>& A
2278 )
2279 {
2280  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2281  tC.ref() *= dsf;
2282  return tC;
2283 }
2284 
2285 template<class Type>
2286 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2287 (
2288  const tmp<volScalarField::Internal>& tdsf,
2289  const fvMatrix<Type>& A
2290 )
2291 {
2292  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2293  tC.ref() *= tdsf;
2294  return tC;
2295 }
2296 
2297 template<class Type>
2298 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2299 (
2300  const tmp<volScalarField>& tvsf,
2301  const fvMatrix<Type>& A
2302 )
2303 {
2304  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2305  tC.ref() *= tvsf;
2306  return tC;
2307 }
2308 
2309 template<class Type>
2310 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2311 (
2312  const volScalarField::Internal& dsf,
2313  const tmp<fvMatrix<Type>>& tA
2314 )
2315 {
2316  tmp<fvMatrix<Type>> tC(tA.ptr());
2317  tC.ref() *= dsf;
2318  return tC;
2319 }
2320 
2321 template<class Type>
2322 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2323 (
2324  const tmp<volScalarField::Internal>& tdsf,
2325  const tmp<fvMatrix<Type>>& tA
2326 )
2327 {
2328  tmp<fvMatrix<Type>> tC(tA.ptr());
2329  tC.ref() *= tdsf;
2330  return tC;
2331 }
2332 
2333 template<class Type>
2334 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2335 (
2336  const tmp<volScalarField>& tvsf,
2337  const tmp<fvMatrix<Type>>& tA
2338 )
2339 {
2340  tmp<fvMatrix<Type>> tC(tA.ptr());
2341  tC.ref() *= tvsf;
2342  return tC;
2343 }
2344 
2345 template<class Type>
2346 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2347 (
2348  const dimensioned<scalar>& ds,
2349  const fvMatrix<Type>& A
2350 )
2351 {
2352  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2353  tC.ref() *= ds;
2354  return tC;
2355 }
2356 
2357 template<class Type>
2358 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2359 (
2360  const dimensioned<scalar>& ds,
2361  const tmp<fvMatrix<Type>>& tA
2362 )
2363 {
2364  tmp<fvMatrix<Type>> tC(tA.ptr());
2365  tC.ref() *= ds;
2366  return tC;
2367 }
2368 
2369 
2370 template<class Type>
2371 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2372 (
2373  const fvMatrix<Type>& A,
2374  const volScalarField::Internal& dsf
2375 )
2376 {
2377  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2378  tC.ref() /= dsf;
2379  return tC;
2380 }
2381 
2382 template<class Type>
2383 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2384 (
2385  const fvMatrix<Type>& A,
2386  const tmp<volScalarField::Internal>& tdsf
2387 )
2388 {
2389  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2390  tC.ref() /= tdsf;
2391  return tC;
2392 }
2393 
2394 template<class Type>
2395 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2396 (
2397  const fvMatrix<Type>& A,
2398  const tmp<volScalarField>& tvsf
2399 )
2400 {
2401  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2402  tC.ref() /= tvsf;
2403  return tC;
2404 }
2405 
2406 template<class Type>
2407 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2408 (
2409  const tmp<fvMatrix<Type>>& tA,
2410  const volScalarField::Internal& dsf
2411 )
2412 {
2413  tmp<fvMatrix<Type>> tC(tA.ptr());
2414  tC.ref() /= dsf;
2415  return tC;
2416 }
2417 
2418 template<class Type>
2419 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2420 (
2421  const tmp<fvMatrix<Type>>& tA,
2422  const tmp<volScalarField::Internal>& tdsf
2423 )
2424 {
2425  tmp<fvMatrix<Type>> tC(tA.ptr());
2426  tC.ref() /= tdsf;
2427  return tC;
2428 }
2429 
2430 template<class Type>
2431 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2432 (
2433  const tmp<fvMatrix<Type>>& tA,
2434  const tmp<volScalarField>& tvsf
2435 )
2436 {
2437  tmp<fvMatrix<Type>> tC(tA.ptr());
2438  tC.ref() /= tvsf;
2439  return tC;
2440 }
2441 
2442 template<class Type>
2443 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2444 (
2445  const fvMatrix<Type>& A,
2446  const dimensioned<scalar>& ds
2447 )
2448 {
2449  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2450  tC.ref() /= ds;
2451  return tC;
2452 }
2453 
2454 template<class Type>
2455 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2456 (
2457  const tmp<fvMatrix<Type>>& tA,
2458  const dimensioned<scalar>& ds
2459 )
2460 {
2461  tmp<fvMatrix<Type>> tC(tA.ptr());
2462  tC.ref() /= ds;
2463  return tC;
2464 }
2465 
2466 
2467 template<class Type>
2469 Foam::operator&
2470 (
2471  const fvMatrix<Type>& M,
2472  const DimensionedField<Type, volMesh>& psi
2473 )
2474 {
2475  tmp<VolField<Type>> tMphi
2476  (
2478  (
2479  "M&" + psi.name(),
2480  psi.mesh(),
2481  M.dimensions()/dimVolume,
2482  extrapolatedCalculatedFvPatchScalarField::typeName
2483  )
2484  );
2485  VolField<Type>& Mphi = tMphi.ref();
2486 
2487  // Loop over field components
2488  if (M.hasDiag())
2489  {
2490  for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
2491  {
2492  scalarField psiCmpt(psi.primitiveField().component(cmpt));
2493  scalarField boundaryDiagCmpt(M.diag());
2494  M.addBoundaryDiag(boundaryDiagCmpt, cmpt);
2495  Mphi.primitiveFieldRef().replace(cmpt, -boundaryDiagCmpt*psiCmpt);
2496  }
2497  }
2498  else
2499  {
2500  Mphi.primitiveFieldRef() = Zero;
2501  }
2502 
2503  Mphi.primitiveFieldRef() +=
2504  M.lduMatrix::H(psi.primitiveField()) + M.source();
2505  M.addBoundarySource(Mphi.primitiveFieldRef());
2506 
2507  Mphi.primitiveFieldRef() /= -psi.mesh().V();
2508  Mphi.correctBoundaryConditions();
2509 
2510  return tMphi;
2511 }
2512 
2513 template<class Type>
2515 Foam::operator&
2516 (
2517  const fvMatrix<Type>& M,
2518  const tmp<DimensionedField<Type, volMesh>>& tpsi
2519 )
2520 {
2521  tmp<VolField<Type>> tMpsi = M & tpsi();
2522  tpsi.clear();
2523  return tMpsi;
2524 }
2525 
2526 template<class Type>
2528 Foam::operator&
2529 (
2530  const fvMatrix<Type>& M,
2531  const tmp<VolField<Type>>& tpsi
2532 )
2533 {
2534  tmp<VolField<Type>> tMpsi = M & tpsi();
2535  tpsi.clear();
2536  return tMpsi;
2537 }
2538 
2539 template<class Type>
2541 Foam::operator&
2542 (
2543  const tmp<fvMatrix<Type>>& tM,
2544  const DimensionedField<Type, volMesh>& psi
2545 )
2546 {
2547  tmp<VolField<Type>> tMpsi = tM() & psi;
2548  tM.clear();
2549  return tMpsi;
2550 }
2551 
2552 template<class Type>
2554 Foam::operator&
2555 (
2556  const tmp<fvMatrix<Type>>& tM,
2557  const tmp<DimensionedField<Type, volMesh>>& tpsi
2558 )
2559 {
2560  tmp<VolField<Type>> tMpsi = tM() & tpsi();
2561  tM.clear();
2562  tpsi.clear();
2563  return tMpsi;
2564 }
2565 
2566 template<class Type>
2568 Foam::operator&
2569 (
2570  const tmp<fvMatrix<Type>>& tM,
2571  const tmp<VolField<Type>>& tpsi
2572 )
2573 {
2574  tmp<VolField<Type>> tMpsi = tM() & tpsi();
2575  tM.clear();
2576  tpsi.clear();
2577  return tMpsi;
2578 }
2579 
2580 
2581 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
2582 
2583 template<class Type>
2584 Foam::Ostream& Foam::operator<<(Ostream& os, const fvMatrix<Type>& fvm)
2585 {
2586  os << static_cast<const lduMatrix&>(fvm) << nl
2587  << fvm.dimensions_ << nl
2588  << fvm.source_ << nl
2589  << fvm.internalCoeffs_ << nl
2590  << fvm.boundaryCoeffs_ << endl;
2591 
2592  os.check("Ostream& operator<<(Ostream&, fvMatrix<Type>&");
2593 
2594  return os;
2595 }
2596 
2597 
2598 // * * * * * * * * * * * * * * * * Solvers * * * * * * * * * * * * * * * * * //
2599 
2600 #include "fvMatrixSolve.C"
2601 
2602 // ************************************************************************* //
static const Foam::dimensionedScalar A("A", Foam::dimPressure, 611.21)
static const Foam::dimensionedScalar B("B", Foam::dimless, 18.678)
static const Foam::dimensionedScalar D("D", Foam::dimTemperature, 257.14)
EaEqn relax()
#define M(I)
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const dimensionSet & dimensions() const
Return dimensions.
const Mesh & mesh() const
Return mesh.
static tmp< DimensionedField< Type, GeoMesh > > New(const word &name, const Mesh &mesh, const dimensionSet &, const Field< Type > &)
Return a temporary field constructed from name, mesh,.
Generic field type.
Definition: FieldField.H:77
Pre-declare SubField and related Field type.
Definition: Field.H:83
void replace(const direction, const UList< cmptType > &)
Replace a component field of the field.
Definition: Field.C:491
void negate()
Negate this field.
Definition: Field.C:470
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
Definition: Field.C:479
void updateCoeffs()
Update the boundary condition coefficients.
Generic GeometricField class.
Internal::FieldType & primitiveFieldRef()
Return a reference to the primitive field.
DimensionedField< Type, GeoMesh > Internal
Type of the internal field from which this GeometricField is derived.
const Internal::FieldType & primitiveField() const
Return a const-reference to the primitive field.
void replace(const direction, const GeometricField< cmptType, PatchField, GeoMesh > &)
void correctBoundaryConditions()
Correct boundary field.
Boundary & boundaryFieldRef()
Return a reference to the boundary field.
static tmp< GeometricField< Type, PatchField, GeoMesh > > New(const word &name, const Internal &, const PtrList< PatchField< Type >> &, const HashPtrTable< Source > &=HashPtrTable< Source >())
Return a temporary field constructed from name,.
const word & name() const
Return name.
Definition: IOobject.H:310
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:92
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:476
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:60
Dimension set for the base types.
Definition: dimensionSet.H:125
Generic dimensioned Type class.
const dimensionSet & dimensions() const
Return const reference to dimensions.
const word & name() const
Return const reference to name.
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:76
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition: fvMatrix.H:118
void operator-=(const fvMatrix< Type > &)
Definition: fvMatrix.C:1137
tmp< Field< Type > > DD() const
Return the matrix Type diagonal.
Definition: fvMatrix.C:784
tmp< volScalarField > A() const
Return the central coefficient.
Definition: fvMatrix.C:808
void addToInternalField(const labelUList &addr, const Field< Type2 > &pf, Field< Type2 > &intf) const
Add patch contribution to internal field.
Definition: fvMatrix.C:40
void setValue(const label celli, const Type &value)
Set solution in the given cell to the specified value.
Definition: fvMatrix.C:179
void boundaryManipulate(typename VolField< Type >::Boundary &values)
Manipulate based on a boundary field.
Definition: fvMatrix.C:762
void relax()
Relax matrix (for steady-state solution).
Definition: fvMatrix.C:754
tmp< volScalarField > H1() const
Return H(1)
Definition: fvMatrix.C:923
tmp< VolField< Type > > H() const
Return the H operation source.
Definition: fvMatrix.C:868
void operator+=(const fvMatrix< Type > &)
Definition: fvMatrix.C:1103
virtual ~fvMatrix()
Destructor.
Definition: fvMatrix.C:482
VolField< Type > & psi()
Definition: fvMatrix.H:289
tmp< SurfaceField< Type > > flux() const
Return the face-flux field from the matrix.
Definition: fvMatrix.C:964
void addCmptAvBoundaryDiag(scalarField &diag) const
Definition: fvMatrix.C:131
void addBoundarySource(Field< Type > &source, const bool couples=true) const
Definition: fvMatrix.C:147
fvMatrix(const VolField< Type > &, const dimensionSet &)
Construct given a field to solve for.
Definition: fvMatrix.C:285
tmp< volScalarField::Internal > Sp() const
Return the implicit source.
Definition: fvMatrix.C:847
void setReference(const label celli, const Type &value, const bool forceReference=false)
Set reference level for solution.
Definition: fvMatrix.C:563
scalar relaxationFactor() const
Return the relaxation factor for this equation.
Definition: fvMatrix.C:578
void addBoundaryDiag(scalarField &diag, const direction cmpt) const
Definition: fvMatrix.C:113
void negate()
Definition: fvMatrix.C:1088
void setValues(const labelUList &cells, const ListType< Type > &values)
Set solution in given cells to the specified values.
Definition: fvMatrix.C:502
tmp< fvMatrix< Type > > clone() const
Clone.
Definition: fvMatrix.C:470
tmp< VolInternalField< Type > > Su() const
Return the explicit source.
Definition: fvMatrix.C:829
tmp< scalarField > D() const
Return the matrix scalar diagonal.
Definition: fvMatrix.C:775
void subtractFromInternalField(const labelUList &addr, const Field< Type2 > &pf, Field< Type2 > &intf) const
Subtract patch contribution from internal field.
Definition: fvMatrix.C:77
const dimensionSet & dimensions() const
Definition: fvMatrix.H:302
void operator=(const fvMatrix< Type > &)
Definition: fvMatrix.C:1044
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:99
const labelUList & owner() const
Internal face owner.
Definition: fvMesh.H:469
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:911
const UCompactListList< label > & polyBFacePatchFaces() const
Return poly-bFace-patch-face addressing.
Definition: fvMesh.C:987
const labelUList & neighbour() const
Internal face neighbour.
Definition: fvMesh.H:475
const polyMesh & mesh() const
Return reference to polyMesh.
Definition: fvMesh.H:441
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:88
virtual bool coupled() const
Return true if this patch field is coupled.
Definition: fvPatchField.H:328
virtual tmp< Field< Type > > patchNeighbourField(const Pstream::commsTypes commsType=Pstream::commsTypes::blocking) const
Return patchField on the opposite patch of a coupled patch.
Definition: fvPatchField.H:433
lduMatrix is a general matrix class in which the coefficients are stored as three arrays,...
Definition: lduMatrix.H:80
tmp< scalarField > H1() const
tmp< Field< Type > > faceH(const Field< Type > &) const
void operator=(const lduMatrix &)
tmp< Field< Type > > H(const Field< Type > &) const
void operator*=(const scalarField &)
scalarField & diag()
Definition: lduMatrix.C:186
void operator/=(const scalarField &)
void operator+=(const lduMatrix &)
void operator-=(const lduMatrix &)
bool hasDiag() const
Definition: lduMatrix.H:580
Traits class for primitives.
Definition: pTraits.H:53
label nInternalFaces() const
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
const cellList & cells() const
Reference counter for various OpenFOAM components.
Definition: refCount.H:50
label eventNo() const
Event number at last update.
Definition: regIOobjectI.H:89
static bool finalIteration(const objectRegistry &registry)
Lookup solutionControl from the objectRegistry and return finalIter.
A class for managing temporary objects.
Definition: tmp.H:55
T * ptr() const
Return tmp pointer for reuse.
Definition: tmpI.H:205
void clear() const
If object pointer points to valid object:
Definition: tmpI.H:237
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:181
A class representing the concept of 0 used to avoid unnecessary manipulations for objects that are kn...
Definition: zero.H:50
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
Calculate the matrix for the first temporal derivative.
label patchi
const cellShapeList & cells
const fvPatchList & patches
const volScalarField & psi
volScalarField alpha(IOobject("alpha", runTime.name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
#define InfoInFunction
Report an information message using Foam::Info.
const dimensionedScalar c
Speed of light in a vacuum.
tmp< fvMatrix< Type > > S(const Pair< tmp< volScalarField::Internal >> &, const VolField< Type > &)
tmp< fvMatrix< Type > > ddt(const VolField< Type > &vf)
Definition: fvmDdt.C:46
static const zero Zero
Definition: zero.H:97
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
const HashTable< dimensionSet > & dimensions()
Get the table of dimension sets.
Definition: dimensionSets.C:96
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
void deleteDemandDrivenData(DataType *&dataPtr)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
void cmptMin(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
void checkMethod(const fvMatrix< Type > &, const fvMatrix< Type > &, const char *)
Definition: fvMatrix.C:1422
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
tmp< DimensionedField< typename DimensionedField< Type, GeoMesh >::cmptType, GeoMesh >> cmptAv(const DimensionedField< Type, GeoMesh > &df)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
const dimensionSet dimVolume
dimensioned< scalar > mag(const dimensioned< Type > &)
typename VolField< Type >::Internal VolInternalField
Definition: volFieldsFwd.H:61
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Return the correction form of the given matrix.
dimensioned< Type > cmptMultiply(const dimensioned< Type > &, const dimensioned< Type > &)
dimensionSet cmptMag(const dimensionSet &)
Definition: dimensionSet.C:296
void cmptMax(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
Ostream & operator<<(Ostream &os, const fvConstraints &constraints)
error FatalError
static const char nl
Definition: Ostream.H:266
uint8_t direction
Definition: direction.H:45
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
dictionary fractions(initialConditions.subDict("fractions"))
faceListList boundary(nPatches)
Foam::surfaceFields.
conserve primitiveFieldRef()+