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-2022 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 =
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 =
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 (
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.
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 (
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  (
582  psi_.mesh().data::template lookupOrDefault<bool>
583  ("finalIteration", false)
584  && psi_.mesh().solution().relaxEquation(psi_.name() + "Final")
585  )
586  {
587  return psi_.mesh().solution().equationRelaxationFactor
588  (
589  psi_.name() + "Final"
590  );
591  }
592  else if (psi_.mesh().solution().relaxEquation(psi_.name()))
593  {
594  return psi_.mesh().solution().equationRelaxationFactor(psi_.name());
595  }
596  else
597  {
598  return 0;
599  }
600 }
601 
602 
603 template<class Type>
605 {
606  if (alpha <= 0)
607  {
608  return;
609  }
610 
611  if (debug)
612  {
614  << "Relaxing " << psi_.name() << " by " << alpha << endl;
615  }
616 
617  Field<Type>& S = source();
618  scalarField& D = diag();
619 
620  // Store the current unrelaxed diagonal for use in updating the source
621  scalarField D0(D);
622 
623  // Calculate the sum-mag off-diagonal from the interior faces
624  scalarField sumOff(D.size(), 0.0);
625  sumMagOffDiag(sumOff);
626 
627  // Handle the boundary contributions to the diagonal
628  forAll(psi_.boundaryField(), patchi)
629  {
630  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
631 
632  if (ptf.size())
633  {
634  const labelUList& pa = lduAddr().patchAddr(patchi);
635  Field<Type>& iCoeffs = internalCoeffs_[patchi];
636 
637  if (ptf.coupled())
638  {
639  const Field<Type>& pCoeffs = boundaryCoeffs_[patchi];
640 
641  // For coupled boundaries add the diagonal and
642  // off-diagonal contributions
643  forAll(pa, face)
644  {
645  D[pa[face]] += component(iCoeffs[face], 0);
646  sumOff[pa[face]] += mag(component(pCoeffs[face], 0));
647  }
648  }
649  else
650  {
651  // For non-coupled boundaries add the maximum magnitude diagonal
652  // contribution to ensure stability
653  forAll(pa, face)
654  {
655  D[pa[face]] += cmptMax(cmptMag(iCoeffs[face]));
656  }
657  }
658  }
659  }
660 
661 
662  if (debug)
663  {
664  // Calculate amount of non-dominance.
665  label nNon = 0;
666  scalar maxNon = 0.0;
667  scalar sumNon = 0.0;
668  forAll(D, celli)
669  {
670  scalar d = (sumOff[celli] - D[celli])/mag(D[celli]);
671 
672  if (d > 0)
673  {
674  nNon++;
675  maxNon = max(maxNon, d);
676  sumNon += d;
677  }
678  }
679 
680  reduce(nNon, sumOp<label>(), UPstream::msgType(), psi_.mesh().comm());
681  reduce
682  (
683  maxNon,
684  maxOp<scalar>(),
686  psi_.mesh().comm()
687  );
688  reduce
689  (
690  sumNon,
691  sumOp<scalar>(),
693  psi_.mesh().comm()
694  );
695  sumNon /= returnReduce
696  (
697  D.size(),
698  sumOp<label>(),
700  psi_.mesh().comm()
701  );
702 
704  << "Matrix dominance test for " << psi_.name() << nl
705  << " number of non-dominant cells : " << nNon << nl
706  << " maximum relative non-dominance : " << maxNon << nl
707  << " average relative non-dominance : " << sumNon << nl
708  << endl;
709  }
710 
711 
712  // Ensure the matrix is diagonally dominant...
713  // Assumes that the central coefficient is positive and ensures it is
714  forAll(D, celli)
715  {
716  D[celli] = max(mag(D[celli]), sumOff[celli]);
717  }
718 
719  // ... then relax
720  D /= alpha;
721 
722  // Now remove the diagonal contribution from coupled boundaries
723  forAll(psi_.boundaryField(), patchi)
724  {
725  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
726 
727  if (ptf.size())
728  {
729  const labelUList& pa = lduAddr().patchAddr(patchi);
730  Field<Type>& iCoeffs = internalCoeffs_[patchi];
731 
732  if (ptf.coupled())
733  {
734  forAll(pa, face)
735  {
736  D[pa[face]] -= component(iCoeffs[face], 0);
737  }
738  }
739  else
740  {
741  forAll(pa, face)
742  {
743  D[pa[face]] -= cmptMin(iCoeffs[face]);
744  }
745  }
746  }
747  }
748 
749  // Finally add the relaxation contribution to the source.
750  S += (D - D0)*psi_.primitiveField();
751 }
752 
753 
754 template<class Type>
756 {
758 }
759 
760 
761 template<class Type>
763 (
765  Boundary& bFields
766 )
767 {
768  forAll(bFields, patchi)
769  {
770  bFields[patchi].manipulateMatrix(*this);
771  }
772 }
773 
774 
775 template<class Type>
777 {
778  tmp<scalarField> tdiag(new scalarField(diag()));
779  addCmptAvBoundaryDiag(tdiag.ref());
780  return tdiag;
781 }
782 
783 
784 template<class Type>
786 {
788 
789  forAll(psi_.boundaryField(), patchi)
790  {
791  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
792 
793  if (!ptf.coupled() && ptf.size())
794  {
796  (
797  lduAddr().patchAddr(patchi),
798  internalCoeffs_[patchi],
799  tdiag.ref()
800  );
801  }
802  }
803 
804  return tdiag;
805 }
806 
807 
808 template<class Type>
810 {
811  tmp<volScalarField> tAphi
812  (
814  (
815  "A("+psi_.name()+')',
816  psi_.mesh(),
817  dimensions_/psi_.dimensions()/dimVol,
818  extrapolatedCalculatedFvPatchScalarField::typeName
819  )
820  );
821 
822  tAphi.ref().primitiveFieldRef() = D()/psi_.mesh().V();
823  tAphi.ref().correctBoundaryConditions();
824 
825  return tAphi;
826 }
827 
828 
829 template<class Type>
832 {
834  (
836  (
837  "H("+psi_.name()+')',
838  psi_.mesh(),
839  dimensions_/dimVol,
840  extrapolatedCalculatedFvPatchScalarField::typeName
841  )
842  );
844 
845  // Loop over field components
846  for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
847  {
848  scalarField psiCmpt(psi_.primitiveField().component(cmpt));
849 
850  scalarField boundaryDiagCmpt(psi_.size(), 0.0);
851  addBoundaryDiag(boundaryDiagCmpt, cmpt);
852  boundaryDiagCmpt.negate();
853  addCmptAvBoundaryDiag(boundaryDiagCmpt);
854 
855  Hphi.primitiveFieldRef().replace(cmpt, boundaryDiagCmpt*psiCmpt);
856  }
857 
858  Hphi.primitiveFieldRef() += lduMatrix::H(psi_.primitiveField()) + source_;
860 
861  Hphi.primitiveFieldRef() /= psi_.mesh().V();
863 
864  typename Type::labelType validComponents
865  (
866  psi_.mesh().template validComponents<Type>()
867  );
868 
869  for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
870  {
871  if (validComponents[cmpt] == -1)
872  {
873  Hphi.replace
874  (
875  cmpt,
876  dimensionedScalar(Hphi.dimensions(), 0)
877  );
878  }
879  }
880 
881  return tHphi;
882 }
883 
884 
885 template<class Type>
887 {
889  (
891  (
892  "H(1)",
893  psi_.mesh(),
894  dimensions_/(dimVol*psi_.dimensions()),
895  extrapolatedCalculatedFvPatchScalarField::typeName
896  )
897  );
898  volScalarField& H1_ = tH1.ref();
899 
900  H1_.primitiveFieldRef() = lduMatrix::H1();
901 
902  forAll(psi_.boundaryField(), patchi)
903  {
904  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
905 
906  if (ptf.coupled() && ptf.size())
907  {
909  (
910  lduAddr().patchAddr(patchi),
911  boundaryCoeffs_[patchi].component(0),
912  H1_
913  );
914  }
915  }
916 
917  H1_.primitiveFieldRef() /= psi_.mesh().V();
918  H1_.correctBoundaryConditions();
919 
920  return tH1;
921 }
922 
923 
924 template<class Type>
927 flux() const
928 {
929  if (!psi_.mesh().schemes().fluxRequired(psi_.name()))
930  {
932  << "flux requested but " << psi_.name()
933  << " not specified in the fluxRequired sub-dictionary"
934  " of fvSchemes."
935  << abort(FatalError);
936  }
937 
938  // construct GeometricField<Type, fvsPatchField, surfaceMesh>
940  (
942  (
943  "flux("+psi_.name()+')',
944  psi_.mesh(),
945  dimensions()
946  )
947  );
949  tfieldFlux.ref();
950 
951  for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
952  {
953  fieldFlux.primitiveFieldRef().replace
954  (
955  cmpt,
956  lduMatrix::faceH(psi_.primitiveField().component(cmpt))
957  );
958  }
959 
960  FieldField<Field, Type> InternalContrib = internalCoeffs_;
961 
962  forAll(InternalContrib, patchi)
963  {
964  InternalContrib[patchi] =
966  (
967  InternalContrib[patchi],
968  psi_.boundaryField()[patchi].patchInternalField()
969  );
970  }
971 
972  FieldField<Field, Type> NeighbourContrib = boundaryCoeffs_;
973 
974  forAll(NeighbourContrib, patchi)
975  {
976  if (psi_.boundaryField()[patchi].coupled())
977  {
978  NeighbourContrib[patchi] =
980  (
981  NeighbourContrib[patchi],
982  psi_.boundaryField()[patchi].patchNeighbourField()
983  );
984  }
985  }
986 
988  Boundary& ffbf = fieldFlux.boundaryFieldRef();
989 
990  forAll(ffbf, patchi)
991  {
992  ffbf[patchi] = InternalContrib[patchi] - NeighbourContrib[patchi];
993  }
994 
995  if (faceFluxCorrectionPtr_)
996  {
997  fieldFlux += *faceFluxCorrectionPtr_;
998  }
999 
1000  return tfieldFlux;
1001 }
1002 
1003 
1004 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1005 
1006 template<class Type>
1008 {
1009  if (this == &fvmv)
1010  {
1012  << "attempted assignment to self"
1013  << abort(FatalError);
1014  }
1015 
1016  if (&psi_ != &(fvmv.psi_))
1017  {
1019  << "different fields"
1020  << abort(FatalError);
1021  }
1022 
1023  dimensions_ = fvmv.dimensions_;
1024  lduMatrix::operator=(fvmv);
1025  source_ = fvmv.source_;
1026  internalCoeffs_ = fvmv.internalCoeffs_;
1027  boundaryCoeffs_ = fvmv.boundaryCoeffs_;
1028 
1029  if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
1030  {
1031  *faceFluxCorrectionPtr_ = *fvmv.faceFluxCorrectionPtr_;
1032  }
1033  else if (fvmv.faceFluxCorrectionPtr_)
1034  {
1035  faceFluxCorrectionPtr_ =
1037  (*fvmv.faceFluxCorrectionPtr_);
1038  }
1039 }
1040 
1041 
1042 template<class Type>
1044 {
1045  operator=(tfvmv());
1046  tfvmv.clear();
1047 }
1048 
1049 
1050 template<class Type>
1052 {
1054  source_.negate();
1055  internalCoeffs_.negate();
1056  boundaryCoeffs_.negate();
1057 
1058  if (faceFluxCorrectionPtr_)
1059  {
1060  faceFluxCorrectionPtr_->negate();
1061  }
1062 }
1063 
1064 
1065 template<class Type>
1067 {
1068  checkMethod(*this, fvmv, "+=");
1069 
1070  dimensions_ += fvmv.dimensions_;
1071  lduMatrix::operator+=(fvmv);
1072  source_ += fvmv.source_;
1073  internalCoeffs_ += fvmv.internalCoeffs_;
1074  boundaryCoeffs_ += fvmv.boundaryCoeffs_;
1075 
1076  if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
1077  {
1078  *faceFluxCorrectionPtr_ += *fvmv.faceFluxCorrectionPtr_;
1079  }
1080  else if (fvmv.faceFluxCorrectionPtr_)
1081  {
1082  faceFluxCorrectionPtr_ = new
1084  (
1085  *fvmv.faceFluxCorrectionPtr_
1086  );
1087  }
1088 }
1089 
1090 
1091 template<class Type>
1093 {
1094  operator+=(tfvmv());
1095  tfvmv.clear();
1096 }
1097 
1098 
1099 template<class Type>
1101 {
1102  checkMethod(*this, fvmv, "-=");
1103 
1104  dimensions_ -= fvmv.dimensions_;
1105  lduMatrix::operator-=(fvmv);
1106  source_ -= fvmv.source_;
1107  internalCoeffs_ -= fvmv.internalCoeffs_;
1108  boundaryCoeffs_ -= fvmv.boundaryCoeffs_;
1109 
1110  if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
1111  {
1112  *faceFluxCorrectionPtr_ -= *fvmv.faceFluxCorrectionPtr_;
1113  }
1114  else if (fvmv.faceFluxCorrectionPtr_)
1115  {
1116  faceFluxCorrectionPtr_ =
1118  (-*fvmv.faceFluxCorrectionPtr_);
1119  }
1120 }
1121 
1122 
1123 template<class Type>
1125 {
1126  operator-=(tfvmv());
1127  tfvmv.clear();
1128 }
1129 
1130 
1131 template<class Type>
1132 void Foam::fvMatrix<Type>::operator+=
1135 )
1136 {
1137  checkMethod(*this, su, "+=");
1138  source() -= su.mesh().V()*su.field();
1139 }
1140 
1141 
1142 template<class Type>
1143 void Foam::fvMatrix<Type>::operator+=
1146 )
1147 {
1148  operator+=(tsu());
1149  tsu.clear();
1150 }
1151 
1152 
1153 template<class Type>
1154 void Foam::fvMatrix<Type>::operator+=
1157 )
1158 {
1159  operator+=(tsu());
1160  tsu.clear();
1161 }
1162 
1163 
1164 template<class Type>
1165 void Foam::fvMatrix<Type>::operator-=
1168 )
1169 {
1170  checkMethod(*this, su, "-=");
1171  source() += su.mesh().V()*su.field();
1172 }
1173 
1174 
1175 template<class Type>
1176 void Foam::fvMatrix<Type>::operator-=
1179 )
1180 {
1181  operator-=(tsu());
1182  tsu.clear();
1183 }
1184 
1185 
1186 template<class Type>
1187 void Foam::fvMatrix<Type>::operator-=
1190 )
1191 {
1192  operator-=(tsu());
1193  tsu.clear();
1194 }
1195 
1196 
1197 template<class Type>
1198 void Foam::fvMatrix<Type>::operator+=
1200  const dimensioned<Type>& su
1201 )
1202 {
1203  source() -= psi().mesh().V()*su;
1204 }
1205 
1206 
1207 template<class Type>
1208 void Foam::fvMatrix<Type>::operator-=
1210  const dimensioned<Type>& su
1211 )
1212 {
1213  source() += psi().mesh().V()*su;
1214 }
1215 
1216 
1217 template<class Type>
1218 void Foam::fvMatrix<Type>::operator+=
1220  const zero&
1221 )
1222 {}
1223 
1224 
1225 template<class Type>
1226 void Foam::fvMatrix<Type>::operator-=
1228  const zero&
1229 )
1230 {}
1231 
1232 
1233 template<class Type>
1234 void Foam::fvMatrix<Type>::operator*=
1236  const volScalarField::Internal& dsf
1237 )
1238 {
1239  dimensions_ *= dsf.dimensions();
1240  lduMatrix::operator*=(dsf.field());
1241  source_ *= dsf.field();
1242 
1243  forAll(boundaryCoeffs_, patchi)
1244  {
1245  scalarField pisf
1246  (
1247  dsf.mesh().boundary()[patchi].patchInternalField(dsf.field())
1248  );
1249 
1250  internalCoeffs_[patchi] *= pisf;
1251  boundaryCoeffs_[patchi] *= pisf;
1252  }
1253 
1254  if (faceFluxCorrectionPtr_)
1255  {
1257  << "cannot scale a matrix containing a faceFluxCorrection"
1258  << abort(FatalError);
1259  }
1260 }
1261 
1262 
1263 template<class Type>
1264 void Foam::fvMatrix<Type>::operator*=
1266  const tmp<volScalarField::Internal>& tdsf
1267 )
1268 {
1269  operator*=(tdsf());
1270  tdsf.clear();
1271 }
1272 
1273 
1274 template<class Type>
1275 void Foam::fvMatrix<Type>::operator*=
1277  const tmp<volScalarField>& tvsf
1278 )
1279 {
1280  operator*=(tvsf());
1281  tvsf.clear();
1282 }
1283 
1284 
1285 template<class Type>
1286 void Foam::fvMatrix<Type>::operator*=
1288  const dimensioned<scalar>& ds
1289 )
1290 {
1291  dimensions_ *= ds.dimensions();
1292  lduMatrix::operator*=(ds.value());
1293  source_ *= ds.value();
1294  internalCoeffs_ *= ds.value();
1295  boundaryCoeffs_ *= ds.value();
1296 
1297  if (faceFluxCorrectionPtr_)
1298  {
1299  *faceFluxCorrectionPtr_ *= ds.value();
1300  }
1301 }
1302 
1303 
1304 template<class Type>
1305 void Foam::fvMatrix<Type>::operator/=
1307  const volScalarField::Internal& dsf
1308 )
1309 {
1310  dimensions_ /= dsf.dimensions();
1311  lduMatrix::operator/=(dsf.field());
1312  source_ /= dsf.field();
1313 
1314  forAll(boundaryCoeffs_, patchi)
1315  {
1316  scalarField pisf
1317  (
1318  dsf.mesh().boundary()[patchi].patchInternalField(dsf.field())
1319  );
1320 
1321  internalCoeffs_[patchi] /= pisf;
1322  boundaryCoeffs_[patchi] /= pisf;
1323  }
1324 
1325  if (faceFluxCorrectionPtr_)
1326  {
1328  << "cannot scale a matrix containing a faceFluxCorrection"
1329  << abort(FatalError);
1330  }
1331 }
1332 
1333 
1334 template<class Type>
1335 void Foam::fvMatrix<Type>::operator/=
1337  const tmp<volScalarField::Internal>& tdsf
1338 )
1339 {
1340  operator/=(tdsf());
1341  tdsf.clear();
1342 }
1343 
1344 
1345 template<class Type>
1346 void Foam::fvMatrix<Type>::operator/=
1348  const tmp<volScalarField>& tvsf
1349 )
1350 {
1351  operator/=(tvsf());
1352  tvsf.clear();
1353 }
1354 
1355 
1356 template<class Type>
1357 void Foam::fvMatrix<Type>::operator/=
1359  const dimensioned<scalar>& ds
1360 )
1361 {
1362  dimensions_ /= ds.dimensions();
1363  lduMatrix::operator/=(ds.value());
1364  source_ /= ds.value();
1365  internalCoeffs_ /= ds.value();
1366  boundaryCoeffs_ /= ds.value();
1367 
1368  if (faceFluxCorrectionPtr_)
1369  {
1370  *faceFluxCorrectionPtr_ /= ds.value();
1371  }
1372 }
1373 
1374 
1375 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
1376 
1377 template<class Type>
1378 void Foam::checkMethod
1380  const fvMatrix<Type>& fvm1,
1381  const fvMatrix<Type>& fvm2,
1382  const char* op
1383 )
1384 {
1385  if (&fvm1.psi() != &fvm2.psi())
1386  {
1388  << "incompatible fields for operation "
1389  << endl << " "
1390  << "[" << fvm1.psi().name() << "] "
1391  << op
1392  << " [" << fvm2.psi().name() << "]"
1393  << abort(FatalError);
1394  }
1395 
1396  if (dimensionSet::debug && fvm1.dimensions() != fvm2.dimensions())
1397  {
1399  << "incompatible dimensions for operation "
1400  << endl << " "
1401  << "[" << fvm1.psi().name() << fvm1.dimensions()/dimVolume << " ] "
1402  << op
1403  << " [" << fvm2.psi().name() << fvm2.dimensions()/dimVolume << " ]"
1404  << abort(FatalError);
1405  }
1406 }
1407 
1408 
1409 template<class Type>
1410 void Foam::checkMethod
1412  const fvMatrix<Type>& fvm,
1414  const char* op
1415 )
1416 {
1417  if (dimensionSet::debug && fvm.dimensions()/dimVolume != df.dimensions())
1418  {
1420  << endl << " "
1421  << "[" << fvm.psi().name() << fvm.dimensions()/dimVolume << " ] "
1422  << op
1423  << " [" << df.name() << df.dimensions() << " ]"
1424  << abort(FatalError);
1425  }
1426 }
1427 
1428 
1429 template<class Type>
1430 void Foam::checkMethod
1432  const fvMatrix<Type>& fvm,
1433  const dimensioned<Type>& dt,
1434  const char* op
1435 )
1436 {
1437  if (dimensionSet::debug && fvm.dimensions()/dimVolume != dt.dimensions())
1438  {
1440  << "incompatible dimensions for operation "
1441  << endl << " "
1442  << "[" << fvm.psi().name() << fvm.dimensions()/dimVolume << " ] "
1443  << op
1444  << " [" << dt.name() << dt.dimensions() << " ]"
1445  << abort(FatalError);
1446  }
1447 }
1448 
1449 
1450 template<class Type>
1452 (
1453  const fvMatrix<Type>& A
1454 )
1455 {
1456  tmp<Foam::fvMatrix<Type>> tAcorr = A - (A & A.psi());
1457 
1458  // Delete the faceFluxCorrection from the correction matrix
1459  // as it does not have a clear meaning or purpose
1460  deleteDemandDrivenData(tAcorr.ref().faceFluxCorrectionPtr());
1461 
1462  return tAcorr;
1463 }
1464 
1465 
1466 template<class Type>
1468 (
1469  const tmp<fvMatrix<Type>>& tA
1470 )
1471 {
1472  tmp<Foam::fvMatrix<Type>> tAcorr = tA - (tA() & tA().psi());
1473 
1474  // Delete the faceFluxCorrection from the correction matrix
1475  // as it does not have a clear meaning or purpose
1476  deleteDemandDrivenData(tAcorr.ref().faceFluxCorrectionPtr());
1477 
1478  return tAcorr;
1479 }
1480 
1481 
1482 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
1483 
1484 template<class Type>
1485 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1486 (
1487  const fvMatrix<Type>& A,
1488  const fvMatrix<Type>& B
1489 )
1490 {
1491  checkMethod(A, B, "==");
1492  return (A - B);
1493 }
1494 
1495 template<class Type>
1496 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1497 (
1498  const tmp<fvMatrix<Type>>& tA,
1499  const fvMatrix<Type>& B
1500 )
1501 {
1502  checkMethod(tA(), B, "==");
1503  return (tA - B);
1504 }
1505 
1506 template<class Type>
1507 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1508 (
1509  const fvMatrix<Type>& A,
1510  const tmp<fvMatrix<Type>>& tB
1511 )
1512 {
1513  checkMethod(A, tB(), "==");
1514  return (A - tB);
1515 }
1516 
1517 template<class Type>
1518 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1519 (
1520  const tmp<fvMatrix<Type>>& tA,
1521  const tmp<fvMatrix<Type>>& tB
1522 )
1523 {
1524  checkMethod(tA(), tB(), "==");
1525  return (tA - tB);
1526 }
1527 
1528 template<class Type>
1529 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1530 (
1531  const fvMatrix<Type>& A,
1533 )
1534 {
1535  checkMethod(A, su, "==");
1536  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1537  tC.ref().source() += su.mesh().V()*su.field();
1538  return tC;
1539 }
1540 
1541 template<class Type>
1542 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1543 (
1544  const fvMatrix<Type>& A,
1546 )
1547 {
1548  checkMethod(A, tsu(), "==");
1549  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1550  tC.ref().source() += tsu().mesh().V()*tsu().field();
1551  tsu.clear();
1552  return tC;
1553 }
1554 
1555 template<class Type>
1556 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1557 (
1558  const fvMatrix<Type>& A,
1560 )
1561 {
1562  checkMethod(A, tsu(), "==");
1563  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1564  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
1565  tsu.clear();
1566  return tC;
1567 }
1568 
1569 template<class Type>
1570 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1571 (
1572  const tmp<fvMatrix<Type>>& tA,
1574 )
1575 {
1576  checkMethod(tA(), su, "==");
1577  tmp<fvMatrix<Type>> tC(tA.ptr());
1578  tC.ref().source() += su.mesh().V()*su.field();
1579  return tC;
1580 }
1581 
1582 template<class Type>
1583 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1584 (
1585  const tmp<fvMatrix<Type>>& tA,
1587 )
1588 {
1589  checkMethod(tA(), tsu(), "==");
1590  tmp<fvMatrix<Type>> tC(tA.ptr());
1591  tC.ref().source() += tsu().mesh().V()*tsu().field();
1592  tsu.clear();
1593  return tC;
1594 }
1595 
1596 template<class Type>
1597 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1598 (
1599  const tmp<fvMatrix<Type>>& tA,
1601 )
1602 {
1603  checkMethod(tA(), tsu(), "==");
1604  tmp<fvMatrix<Type>> tC(tA.ptr());
1605  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
1606  tsu.clear();
1607  return tC;
1608 }
1609 
1610 template<class Type>
1611 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1612 (
1613  const fvMatrix<Type>& A,
1614  const dimensioned<Type>& su
1615 )
1616 {
1617  checkMethod(A, su, "==");
1618  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1619  tC.ref().source() += A.psi().mesh().V()*su.value();
1620  return tC;
1621 }
1622 
1623 template<class Type>
1624 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1625 (
1626  const tmp<fvMatrix<Type>>& tA,
1627  const dimensioned<Type>& su
1628 )
1629 {
1630  checkMethod(tA(), su, "==");
1631  tmp<fvMatrix<Type>> tC(tA.ptr());
1632  tC.ref().source() += tC().psi().mesh().V()*su.value();
1633  return tC;
1634 }
1635 
1636 template<class Type>
1637 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1638 (
1639  const fvMatrix<Type>& A,
1640  const zero&
1641 )
1642 {
1643  return A;
1644 }
1645 
1646 
1647 template<class Type>
1648 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1649 (
1650  const tmp<fvMatrix<Type>>& tA,
1651  const zero&
1652 )
1653 {
1654  return tA;
1655 }
1656 
1657 
1658 template<class Type>
1659 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1660 (
1661  const fvMatrix<Type>& A
1662 )
1663 {
1664  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1665  tC.ref().negate();
1666  return tC;
1667 }
1668 
1669 template<class Type>
1670 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1671 (
1672  const tmp<fvMatrix<Type>>& tA
1673 )
1674 {
1675  tmp<fvMatrix<Type>> tC(tA.ptr());
1676  tC.ref().negate();
1677  return tC;
1678 }
1679 
1680 
1681 template<class Type>
1682 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1683 (
1684  const fvMatrix<Type>& A,
1685  const fvMatrix<Type>& B
1686 )
1687 {
1688  checkMethod(A, B, "+");
1689  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1690  tC.ref() += B;
1691  return tC;
1692 }
1693 
1694 template<class Type>
1695 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1696 (
1697  const tmp<fvMatrix<Type>>& tA,
1698  const fvMatrix<Type>& B
1699 )
1700 {
1701  checkMethod(tA(), B, "+");
1702  tmp<fvMatrix<Type>> tC(tA.ptr());
1703  tC.ref() += B;
1704  return tC;
1705 }
1706 
1707 template<class Type>
1708 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1709 (
1710  const fvMatrix<Type>& A,
1711  const tmp<fvMatrix<Type>>& tB
1712 )
1713 {
1714  checkMethod(A, tB(), "+");
1715  tmp<fvMatrix<Type>> tC(tB.ptr());
1716  tC.ref() += A;
1717  return tC;
1718 }
1719 
1720 template<class Type>
1721 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1722 (
1723  const tmp<fvMatrix<Type>>& tA,
1724  const tmp<fvMatrix<Type>>& tB
1725 )
1726 {
1727  checkMethod(tA(), tB(), "+");
1728  tmp<fvMatrix<Type>> tC(tA.ptr());
1729  tC.ref() += tB();
1730  tB.clear();
1731  return tC;
1732 }
1733 
1734 template<class Type>
1735 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1736 (
1737  const fvMatrix<Type>& A,
1739 )
1740 {
1741  checkMethod(A, su, "+");
1742  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1743  tC.ref().source() -= su.mesh().V()*su.field();
1744  return tC;
1745 }
1746 
1747 template<class Type>
1748 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1749 (
1750  const fvMatrix<Type>& A,
1752 )
1753 {
1754  checkMethod(A, tsu(), "+");
1755  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1756  tC.ref().source() -= tsu().mesh().V()*tsu().field();
1757  tsu.clear();
1758  return tC;
1759 }
1760 
1761 template<class Type>
1762 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1763 (
1764  const fvMatrix<Type>& A,
1766 )
1767 {
1768  checkMethod(A, tsu(), "+");
1769  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1770  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1771  tsu.clear();
1772  return tC;
1773 }
1774 
1775 template<class Type>
1776 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1777 (
1778  const tmp<fvMatrix<Type>>& tA,
1780 )
1781 {
1782  checkMethod(tA(), su, "+");
1783  tmp<fvMatrix<Type>> tC(tA.ptr());
1784  tC.ref().source() -= su.mesh().V()*su.field();
1785  return tC;
1786 }
1787 
1788 template<class Type>
1789 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1790 (
1791  const tmp<fvMatrix<Type>>& tA,
1793 )
1794 {
1795  checkMethod(tA(), tsu(), "+");
1796  tmp<fvMatrix<Type>> tC(tA.ptr());
1797  tC.ref().source() -= tsu().mesh().V()*tsu().field();
1798  tsu.clear();
1799  return tC;
1800 }
1801 
1802 template<class Type>
1803 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1804 (
1805  const tmp<fvMatrix<Type>>& tA,
1807 )
1808 {
1809  checkMethod(tA(), tsu(), "+");
1810  tmp<fvMatrix<Type>> tC(tA.ptr());
1811  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1812  tsu.clear();
1813  return tC;
1814 }
1815 
1816 template<class Type>
1817 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1818 (
1820  const fvMatrix<Type>& A
1821 )
1822 {
1823  checkMethod(A, su, "+");
1824  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1825  tC.ref().source() -= su.mesh().V()*su.field();
1826  return tC;
1827 }
1828 
1829 template<class Type>
1830 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1831 (
1833  const fvMatrix<Type>& A
1834 )
1835 {
1836  checkMethod(A, tsu(), "+");
1837  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1838  tC.ref().source() -= tsu().mesh().V()*tsu().field();
1839  tsu.clear();
1840  return tC;
1841 }
1842 
1843 template<class Type>
1844 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1845 (
1847  const fvMatrix<Type>& A
1848 )
1849 {
1850  checkMethod(A, tsu(), "+");
1851  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1852  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1853  tsu.clear();
1854  return tC;
1855 }
1856 
1857 template<class Type>
1858 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1859 (
1861  const tmp<fvMatrix<Type>>& tA
1862 )
1863 {
1864  checkMethod(tA(), su, "+");
1865  tmp<fvMatrix<Type>> tC(tA.ptr());
1866  tC.ref().source() -= su.mesh().V()*su.field();
1867  return tC;
1868 }
1869 
1870 template<class Type>
1871 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1872 (
1874  const tmp<fvMatrix<Type>>& tA
1875 )
1876 {
1877  checkMethod(tA(), tsu(), "+");
1878  tmp<fvMatrix<Type>> tC(tA.ptr());
1879  tC.ref().source() -= tsu().mesh().V()*tsu().field();
1880  tsu.clear();
1881  return tC;
1882 }
1883 
1884 template<class Type>
1885 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1886 (
1888  const tmp<fvMatrix<Type>>& tA
1889 )
1890 {
1891  checkMethod(tA(), tsu(), "+");
1892  tmp<fvMatrix<Type>> tC(tA.ptr());
1893  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1894  tsu.clear();
1895  return tC;
1896 }
1897 
1898 
1899 template<class Type>
1900 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1901 (
1902  const fvMatrix<Type>& A,
1903  const fvMatrix<Type>& B
1904 )
1905 {
1906  checkMethod(A, B, "-");
1907  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1908  tC.ref() -= B;
1909  return tC;
1910 }
1911 
1912 template<class Type>
1913 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1914 (
1915  const tmp<fvMatrix<Type>>& tA,
1916  const fvMatrix<Type>& B
1917 )
1918 {
1919  checkMethod(tA(), B, "-");
1920  tmp<fvMatrix<Type>> tC(tA.ptr());
1921  tC.ref() -= B;
1922  return tC;
1923 }
1924 
1925 template<class Type>
1926 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1927 (
1928  const fvMatrix<Type>& A,
1929  const tmp<fvMatrix<Type>>& tB
1930 )
1931 {
1932  checkMethod(A, tB(), "-");
1933  tmp<fvMatrix<Type>> tC(tB.ptr());
1934  tC.ref() -= A;
1935  tC.ref().negate();
1936  return tC;
1937 }
1938 
1939 template<class Type>
1940 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1941 (
1942  const tmp<fvMatrix<Type>>& tA,
1943  const tmp<fvMatrix<Type>>& tB
1944 )
1945 {
1946  checkMethod(tA(), tB(), "-");
1947  tmp<fvMatrix<Type>> tC(tA.ptr());
1948  tC.ref() -= tB();
1949  tB.clear();
1950  return tC;
1951 }
1952 
1953 template<class Type>
1954 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1955 (
1956  const fvMatrix<Type>& A,
1958 )
1959 {
1960  checkMethod(A, su, "-");
1961  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1962  tC.ref().source() += su.mesh().V()*su.field();
1963  return tC;
1964 }
1965 
1966 template<class Type>
1967 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1968 (
1969  const fvMatrix<Type>& A,
1971 )
1972 {
1973  checkMethod(A, tsu(), "-");
1974  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1975  tC.ref().source() += tsu().mesh().V()*tsu().field();
1976  tsu.clear();
1977  return tC;
1978 }
1979 
1980 template<class Type>
1981 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1982 (
1983  const fvMatrix<Type>& A,
1985 )
1986 {
1987  checkMethod(A, tsu(), "-");
1988  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1989  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
1990  tsu.clear();
1991  return tC;
1992 }
1993 
1994 template<class Type>
1995 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1996 (
1997  const tmp<fvMatrix<Type>>& tA,
1999 )
2000 {
2001  checkMethod(tA(), su, "-");
2002  tmp<fvMatrix<Type>> tC(tA.ptr());
2003  tC.ref().source() += su.mesh().V()*su.field();
2004  return tC;
2005 }
2006 
2007 template<class Type>
2008 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2009 (
2010  const tmp<fvMatrix<Type>>& tA,
2012 )
2013 {
2014  checkMethod(tA(), tsu(), "-");
2015  tmp<fvMatrix<Type>> tC(tA.ptr());
2016  tC.ref().source() += tsu().mesh().V()*tsu().field();
2017  tsu.clear();
2018  return tC;
2019 }
2020 
2021 template<class Type>
2022 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2023 (
2024  const tmp<fvMatrix<Type>>& tA,
2026 )
2027 {
2028  checkMethod(tA(), tsu(), "-");
2029  tmp<fvMatrix<Type>> tC(tA.ptr());
2030  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
2031  tsu.clear();
2032  return tC;
2033 }
2034 
2035 template<class Type>
2036 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2037 (
2039  const fvMatrix<Type>& A
2040 )
2041 {
2042  checkMethod(A, su, "-");
2043  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2044  tC.ref().negate();
2045  tC.ref().source() -= su.mesh().V()*su.field();
2046  return tC;
2047 }
2048 
2049 template<class Type>
2050 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2051 (
2053  const fvMatrix<Type>& A
2054 )
2055 {
2056  checkMethod(A, tsu(), "-");
2057  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2058  tC.ref().negate();
2059  tC.ref().source() -= tsu().mesh().V()*tsu().field();
2060  tsu.clear();
2061  return tC;
2062 }
2063 
2064 template<class Type>
2065 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2066 (
2068  const fvMatrix<Type>& A
2069 )
2070 {
2071  checkMethod(A, tsu(), "-");
2072  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2073  tC.ref().negate();
2074  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
2075  tsu.clear();
2076  return tC;
2077 }
2078 
2079 template<class Type>
2080 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2081 (
2083  const tmp<fvMatrix<Type>>& tA
2084 )
2085 {
2086  checkMethod(tA(), su, "-");
2087  tmp<fvMatrix<Type>> tC(tA.ptr());
2088  tC.ref().negate();
2089  tC.ref().source() -= su.mesh().V()*su.field();
2090  return tC;
2091 }
2092 
2093 template<class Type>
2094 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2095 (
2097  const tmp<fvMatrix<Type>>& tA
2098 )
2099 {
2100  checkMethod(tA(), tsu(), "-");
2101  tmp<fvMatrix<Type>> tC(tA.ptr());
2102  tC.ref().negate();
2103  tC.ref().source() -= tsu().mesh().V()*tsu().field();
2104  tsu.clear();
2105  return tC;
2106 }
2107 
2108 template<class Type>
2109 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2110 (
2112  const tmp<fvMatrix<Type>>& tA
2113 )
2114 {
2115  checkMethod(tA(), tsu(), "-");
2116  tmp<fvMatrix<Type>> tC(tA.ptr());
2117  tC.ref().negate();
2118  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
2119  tsu.clear();
2120  return tC;
2121 }
2122 
2123 template<class Type>
2124 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2125 (
2126  const fvMatrix<Type>& A,
2127  const dimensioned<Type>& su
2128 )
2129 {
2130  checkMethod(A, su, "+");
2131  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2132  tC.ref().source() -= su.value()*A.psi().mesh().V();
2133  return tC;
2134 }
2135 
2136 template<class Type>
2137 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2138 (
2139  const tmp<fvMatrix<Type>>& tA,
2140  const dimensioned<Type>& su
2141 )
2142 {
2143  checkMethod(tA(), su, "+");
2144  tmp<fvMatrix<Type>> tC(tA.ptr());
2145  tC.ref().source() -= su.value()*tC().psi().mesh().V();
2146  return tC;
2147 }
2148 
2149 template<class Type>
2150 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2151 (
2152  const dimensioned<Type>& su,
2153  const fvMatrix<Type>& A
2154 )
2155 {
2156  checkMethod(A, su, "+");
2157  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2158  tC.ref().source() -= su.value()*A.psi().mesh().V();
2159  return tC;
2160 }
2161 
2162 template<class Type>
2163 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2164 (
2165  const dimensioned<Type>& su,
2166  const tmp<fvMatrix<Type>>& tA
2167 )
2168 {
2169  checkMethod(tA(), su, "+");
2170  tmp<fvMatrix<Type>> tC(tA.ptr());
2171  tC.ref().source() -= su.value()*tC().psi().mesh().V();
2172  return tC;
2173 }
2174 
2175 template<class Type>
2176 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2177 (
2178  const fvMatrix<Type>& A,
2179  const dimensioned<Type>& su
2180 )
2181 {
2182  checkMethod(A, su, "-");
2183  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2184  tC.ref().source() += su.value()*tC().psi().mesh().V();
2185  return tC;
2186 }
2187 
2188 template<class Type>
2189 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2190 (
2191  const tmp<fvMatrix<Type>>& tA,
2192  const dimensioned<Type>& su
2193 )
2194 {
2195  checkMethod(tA(), su, "-");
2196  tmp<fvMatrix<Type>> tC(tA.ptr());
2197  tC.ref().source() += su.value()*tC().psi().mesh().V();
2198  return tC;
2199 }
2200 
2201 template<class Type>
2202 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2203 (
2204  const dimensioned<Type>& su,
2205  const fvMatrix<Type>& A
2206 )
2207 {
2208  checkMethod(A, su, "-");
2209  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2210  tC.ref().negate();
2211  tC.ref().source() -= su.value()*A.psi().mesh().V();
2212  return tC;
2213 }
2214 
2215 template<class Type>
2216 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2217 (
2218  const dimensioned<Type>& su,
2219  const tmp<fvMatrix<Type>>& tA
2220 )
2221 {
2222  checkMethod(tA(), su, "-");
2223  tmp<fvMatrix<Type>> tC(tA.ptr());
2224  tC.ref().negate();
2225  tC.ref().source() -= su.value()*tC().psi().mesh().V();
2226  return tC;
2227 }
2228 
2229 
2230 template<class Type>
2231 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2232 (
2233  const volScalarField::Internal& dsf,
2234  const fvMatrix<Type>& A
2235 )
2236 {
2237  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2238  tC.ref() *= dsf;
2239  return tC;
2240 }
2241 
2242 template<class Type>
2243 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2244 (
2245  const tmp<volScalarField::Internal>& tdsf,
2246  const fvMatrix<Type>& A
2247 )
2248 {
2249  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2250  tC.ref() *= tdsf;
2251  return tC;
2252 }
2253 
2254 template<class Type>
2255 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2256 (
2257  const tmp<volScalarField>& tvsf,
2258  const fvMatrix<Type>& A
2259 )
2260 {
2261  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2262  tC.ref() *= tvsf;
2263  return tC;
2264 }
2265 
2266 template<class Type>
2267 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2268 (
2269  const volScalarField::Internal& dsf,
2270  const tmp<fvMatrix<Type>>& tA
2271 )
2272 {
2273  tmp<fvMatrix<Type>> tC(tA.ptr());
2274  tC.ref() *= dsf;
2275  return tC;
2276 }
2277 
2278 template<class Type>
2279 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2280 (
2281  const tmp<volScalarField::Internal>& tdsf,
2282  const tmp<fvMatrix<Type>>& tA
2283 )
2284 {
2285  tmp<fvMatrix<Type>> tC(tA.ptr());
2286  tC.ref() *= tdsf;
2287  return tC;
2288 }
2289 
2290 template<class Type>
2291 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2292 (
2293  const tmp<volScalarField>& tvsf,
2294  const tmp<fvMatrix<Type>>& tA
2295 )
2296 {
2297  tmp<fvMatrix<Type>> tC(tA.ptr());
2298  tC.ref() *= tvsf;
2299  return tC;
2300 }
2301 
2302 template<class Type>
2303 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2304 (
2305  const dimensioned<scalar>& ds,
2306  const fvMatrix<Type>& A
2307 )
2308 {
2309  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2310  tC.ref() *= ds;
2311  return tC;
2312 }
2313 
2314 template<class Type>
2315 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2316 (
2317  const dimensioned<scalar>& ds,
2318  const tmp<fvMatrix<Type>>& tA
2319 )
2320 {
2321  tmp<fvMatrix<Type>> tC(tA.ptr());
2322  tC.ref() *= ds;
2323  return tC;
2324 }
2325 
2326 
2327 template<class Type>
2328 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2329 (
2330  const fvMatrix<Type>& A,
2331  const volScalarField::Internal& dsf
2332 )
2333 {
2334  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2335  tC.ref() /= dsf;
2336  return tC;
2337 }
2338 
2339 template<class Type>
2340 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2341 (
2342  const fvMatrix<Type>& A,
2343  const tmp<volScalarField::Internal>& tdsf
2344 )
2345 {
2346  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2347  tC.ref() /= tdsf;
2348  return tC;
2349 }
2350 
2351 template<class Type>
2352 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2353 (
2354  const fvMatrix<Type>& A,
2355  const tmp<volScalarField>& tvsf
2356 )
2357 {
2358  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2359  tC.ref() /= tvsf;
2360  return tC;
2361 }
2362 
2363 template<class Type>
2364 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2365 (
2366  const tmp<fvMatrix<Type>>& tA,
2367  const volScalarField::Internal& dsf
2368 )
2369 {
2370  tmp<fvMatrix<Type>> tC(tA.ptr());
2371  tC.ref() /= dsf;
2372  return tC;
2373 }
2374 
2375 template<class Type>
2376 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2377 (
2378  const tmp<fvMatrix<Type>>& tA,
2379  const tmp<volScalarField::Internal>& tdsf
2380 )
2381 {
2382  tmp<fvMatrix<Type>> tC(tA.ptr());
2383  tC.ref() /= tdsf;
2384  return tC;
2385 }
2386 
2387 template<class Type>
2388 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2389 (
2390  const tmp<fvMatrix<Type>>& tA,
2391  const tmp<volScalarField>& tvsf
2392 )
2393 {
2394  tmp<fvMatrix<Type>> tC(tA.ptr());
2395  tC.ref() /= tvsf;
2396  return tC;
2397 }
2398 
2399 template<class Type>
2400 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2401 (
2402  const fvMatrix<Type>& A,
2403  const dimensioned<scalar>& ds
2404 )
2405 {
2406  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2407  tC.ref() /= ds;
2408  return tC;
2409 }
2410 
2411 template<class Type>
2412 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator/
2413 (
2414  const tmp<fvMatrix<Type>>& tA,
2415  const dimensioned<scalar>& ds
2416 )
2417 {
2418  tmp<fvMatrix<Type>> tC(tA.ptr());
2419  tC.ref() /= ds;
2420  return tC;
2421 }
2422 
2423 
2424 template<class Type>
2426 Foam::operator&
2427 (
2428  const fvMatrix<Type>& M,
2430 )
2431 {
2433  (
2435  (
2436  "M&" + psi.name(),
2437  psi.mesh(),
2438  M.dimensions()/dimVol,
2439  extrapolatedCalculatedFvPatchScalarField::typeName
2440  )
2441  );
2443 
2444  // Loop over field components
2445  if (M.hasDiag())
2446  {
2447  for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
2448  {
2449  scalarField psiCmpt(psi.field().component(cmpt));
2450  scalarField boundaryDiagCmpt(M.diag());
2451  M.addBoundaryDiag(boundaryDiagCmpt, cmpt);
2452  Mphi.primitiveFieldRef().replace(cmpt, -boundaryDiagCmpt*psiCmpt);
2453  }
2454  }
2455  else
2456  {
2457  Mphi.primitiveFieldRef() = Zero;
2458  }
2459 
2460  Mphi.primitiveFieldRef() += M.lduMatrix::H(psi.field()) + M.source();
2461  M.addBoundarySource(Mphi.primitiveFieldRef());
2462 
2463  Mphi.primitiveFieldRef() /= -psi.mesh().V();
2465 
2466  return tMphi;
2467 }
2468 
2469 template<class Type>
2471 Foam::operator&
2472 (
2473  const fvMatrix<Type>& M,
2475 )
2476 {
2478  tpsi.clear();
2479  return tMpsi;
2480 }
2481 
2482 template<class Type>
2484 Foam::operator&
2485 (
2486  const fvMatrix<Type>& M,
2488 )
2489 {
2491  tpsi.clear();
2492  return tMpsi;
2493 }
2494 
2495 template<class Type>
2497 Foam::operator&
2498 (
2499  const tmp<fvMatrix<Type>>& tM,
2501 )
2502 {
2504  tM.clear();
2505  return tMpsi;
2506 }
2507 
2508 template<class Type>
2510 Foam::operator&
2511 (
2512  const tmp<fvMatrix<Type>>& tM,
2514 )
2515 {
2516  tmp<GeometricField<Type, fvPatchField, volMesh>> tMpsi = tM() & tpsi();
2517  tM.clear();
2518  tpsi.clear();
2519  return tMpsi;
2520 }
2521 
2522 template<class Type>
2524 Foam::operator&
2525 (
2526  const tmp<fvMatrix<Type>>& tM,
2528 )
2529 {
2530  tmp<GeometricField<Type, fvPatchField, volMesh>> tMpsi = tM() & tpsi();
2531  tM.clear();
2532  tpsi.clear();
2533  return tMpsi;
2534 }
2535 
2536 
2537 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
2538 
2539 template<class Type>
2540 Foam::Ostream& Foam::operator<<(Ostream& os, const fvMatrix<Type>& fvm)
2541 {
2542  os << static_cast<const lduMatrix&>(fvm) << nl
2543  << fvm.dimensions_ << nl
2544  << fvm.source_ << nl
2545  << fvm.internalCoeffs_ << nl
2546  << fvm.boundaryCoeffs_ << endl;
2547 
2548  os.check("Ostream& operator<<(Ostream&, fvMatrix<Type>&");
2549 
2550  return os;
2551 }
2552 
2553 
2554 // * * * * * * * * * * * * * * * * Solvers * * * * * * * * * * * * * * * * * //
2555 
2556 #include "fvMatrixSolve.C"
2557 
2558 // ************************************************************************* //
const fvPatchList & patches
Foam::surfaceFields.
void addToInternalField(const labelUList &addr, const Field< Type2 > &pf, Field< Type2 > &intf) const
Add patch contribution to internal field.
Definition: fvMatrix.C:40
void replace(const direction, const GeometricField< cmptType, PatchField, GeoMesh > &)
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Return the correction form of the given matrix.
void setValue(const label celli, const Type &value)
Set solution in the given cell to the specified value.
Definition: fvMatrix.C:179
tmp< Field< Type > > faceH(const Field< Type > &) const
void cmptMax(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
const word & name() const
Return name.
Definition: IOobject.H:315
void clear() const
If object pointer points to valid object:
Definition: tmpI.H:237
void addBoundaryDiag(scalarField &diag, const direction cmpt) const
Definition: fvMatrix.C:113
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Reference counter for various OpenFOAM components.
Definition: refCount.H:49
void relax()
Relax matrix (for steady-state solution).
Definition: fvMatrix.C:755
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:92
label nInternalFaces() const
tmp< DimensionedField< typename DimensionedField< Type, GeoMesh >::cmptType, GeoMesh >> cmptAv(const DimensionedField< Type, GeoMesh > &df)
void negate()
Definition: fvMatrix.C:1051
lduMatrix(const lduMesh &)
Construct given an LDU addressed mesh.
Definition: lduMatrix.C:43
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:181
const GeometricField< Type, fvPatchField, volMesh > & psi() const
Definition: fvMatrix.H:290
uint8_t direction
Definition: direction.H:45
void addCmptAvBoundaryDiag(scalarField &diag) const
Definition: fvMatrix.C:131
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setReference(const label celli, const Type &value, const bool forceReference=false)
Set reference level for solution.
Definition: fvMatrix.C:563
volScalarField alpha(IOobject("alpha", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
static tmp< GeometricField< scalar, fvPatchField, volMesh > > New(const word &name, const Internal &, const PtrList< fvPatchField< scalar >> &)
Return a temporary field constructed from name,.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
tmp< GeometricField< Type, fvPatchField, volMesh > > H() const
Return the H operation source.
Definition: fvMatrix.C:831
Traits class for primitives.
Definition: pTraits.H:50
void operator-=(const fvMatrix< Type > &)
Definition: fvMatrix.C:1100
scalar relaxationFactor() const
Return the relaxation factor for this equation.
Definition: fvMatrix.C:578
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:66
const cellList & cells() const
Generic GeometricField class.
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:476
Generic dimensioned Type class.
tmp< volScalarField > H1() const
Return H(1)
Definition: fvMatrix.C:886
void subtractFromInternalField(const labelUList &addr, const Field< Type2 > &pf, Field< Type2 > &intf) const
Subtract patch contribution from internal field.
Definition: fvMatrix.C:77
fvMesh & mesh
DimensionedField< scalar, volMesh > Internal
Type of the internal field from which this GeometricField is derived.
tmp< scalarField > H1() const
void sumMagOffDiag(scalarField &sumOff) const
const dimensionedScalar c
Speed of light in a vacuum.
conserve primitiveFieldRef()+
Generic field type.
Definition: FieldField.H:51
tmp< scalarField > D() const
Return the matrix scalar diagonal.
Definition: fvMatrix.C:776
void operator=(const fvMatrix< Type > &)
Definition: fvMatrix.C:1007
const labelUList & neighbour() const
Internal face neighbour.
Definition: fvMesh.H:423
const dimensionSet & dimensions() const
Return dimensions.
Dimension set for the base types.
Definition: dimensionSet.H:121
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
const cellShapeList & cells
void operator/=(const volScalarField::Internal &)
Definition: fvMatrix.C:1306
bool hasDiag() const
Definition: lduMatrix.H:580
Pre-declare SubField and related Field type.
Definition: Field.H:56
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
tmp< fvMatrix< Type > > S(const Pair< tmp< volScalarField::Internal >> &, const GeometricField< Type, fvPatchField, volMesh > &)
const dimensionSet dimVol
tmp< fvMatrix< Type > > ddt(const GeometricField< Type, fvPatchField, volMesh > &vf)
Definition: fvmDdt.C:46
Calculate the matrix for the first temporal derivative.
dimensionSet cmptMag(const dimensionSet &)
Definition: dimensionSet.C:275
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
virtual ~fvMatrix()
Destructor.
Definition: fvMatrix.C:482
virtual bool coupled() const
Return true if this patch field is coupled.
Definition: fvPatchField.H:323
A special matrix type and solver, designed for finite volume solutions of scalar equations. Face addressing is used to make all matrix assembly and solution loops vectorise.
Definition: fvPatchField.H:72
label eventNo() const
Event number at last update.
Definition: regIOobjectI.H:89
static const zero Zero
Definition: zero.H:97
errorManip< error > abort(error &err)
Definition: errorManip.H:131
void operator=(const lduMatrix &)
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
void updateCoeffs()
Update the boundary condition coefficients.
dimensioned< Type > cmptMultiply(const dimensioned< Type > &, const dimensioned< Type > &)
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
tmp< fvMatrix< Type > > clone() const
Clone.
Definition: fvMatrix.C:470
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:54
Internal::FieldType & primitiveFieldRef()
Return a reference to the internal field.
static const char nl
Definition: Ostream.H:260
void operator*=(const scalarField &)
Field< Type > & source()
Definition: fvMatrix.H:300
void operator/=(const scalarField &)
const Mesh & mesh() const
Return mesh.
void operator*=(const volScalarField::Internal &)
Definition: fvMatrix.C:1235
const word & name() const
Return const reference to name.
const Field< Type > & field() const
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
const labelUList & owner() const
Internal face owner.
Definition: fvMesh.H:417
Internal & ref()
Return a reference to the dimensioned internal field.
void operator+=(const fvMatrix< Type > &)
Definition: fvMatrix.C:1066
void setValues(const labelUList &cells, const ListType< Type > &values)
Set solution in given cells to the specified values.
Definition: fvMatrix.C:502
tmp< Field< Type > > DD() const
Return the matrix Type diagonal.
Definition: fvMatrix.C:785
lduMatrix is a general matrix class in which the coefficients are stored as three arrays...
Definition: lduMatrix.H:79
tmp< volScalarField > A() const
Return the central coefficient.
Definition: fvMatrix.C:809
const UCompactListList< label > & polyBFacePatchFaces() const
Return poly-bFace-patch-face addressing.
Definition: fvMesh.C:941
label patchi
const lduAddressing & lduAddr() const
Return the LDU addressing.
Definition: lduMatrix.H:550
Boundary & boundaryFieldRef()
Return a reference to the boundary field.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:865
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:57
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:95
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const dimensionSet & dimensions() const
Return const reference to dimensions.
const dimensionSet dimVolume
void correctBoundaryConditions()
Correct boundary field.
void checkMethod(const fvMatrix< Type > &, const fvMatrix< Type > &, const char *)
Definition: fvMatrix.C:1379
A class representing the concept of 0 used to avoid unnecessary manipulations for objects that are kn...
Definition: zero.H:49
dimensioned< scalar > mag(const dimensioned< Type > &)
void addBoundarySource(Field< Type > &source, const bool couples=true) const
Definition: fvMatrix.C:147
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > flux() const
Return the face-flux field from the matrix.
Definition: fvMatrix.C:927
void boundaryManipulate(typename GeometricField< Type, fvPatchField, volMesh >::Boundary &values)
Manipulate based on a boundary field.
Definition: fvMatrix.C:763
tmp< Field< Type > > H(const Field< Type > &) const
void operator-=(const lduMatrix &)
void operator+=(const lduMatrix &)
T * ptr() const
Return tmp pointer for reuse.
Definition: tmpI.H:205
A class for managing temporary objects.
Definition: PtrList.H:53
scalarField & diag()
Definition: lduMatrix.C:186
void cmptMin(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
void deleteDemandDrivenData(DataPtr &dataPtr)
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
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
fvMatrix(const GeometricField< Type, fvPatchField, volMesh > &, const dimensionSet &)
Construct given a field to solve for.
Definition: fvMatrix.C:285
#define M(I)
#define InfoInFunction
Report an information message using Foam::Info.
const dimensionSet & dimensions() const
Definition: fvMatrix.H:295