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