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-2019 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 
36 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
37 
38 template<class Type>
39 template<class Type2>
41 (
42  const labelUList& addr,
43  const Field<Type2>& pf,
44  Field<Type2>& intf
45 ) const
46 {
47  if (addr.size() != pf.size())
48  {
50  << "sizes of addressing and field are different"
51  << abort(FatalError);
52  }
53 
54  forAll(addr, facei)
55  {
56  intf[addr[facei]] += pf[facei];
57  }
58 }
59 
60 
61 template<class Type>
62 template<class Type2>
64 (
65  const labelUList& addr,
66  const tmp<Field<Type2>>& tpf,
67  Field<Type2>& intf
68 ) const
69 {
70  addToInternalField(addr, tpf(), intf);
71  tpf.clear();
72 }
73 
74 
75 template<class Type>
76 template<class Type2>
78 (
79  const labelUList& addr,
80  const Field<Type2>& pf,
81  Field<Type2>& intf
82 ) const
83 {
84  if (addr.size() != pf.size())
85  {
87  << "sizes of addressing and field are different"
88  << abort(FatalError);
89  }
90 
91  forAll(addr, facei)
92  {
93  intf[addr[facei]] -= pf[facei];
94  }
95 }
96 
97 
98 template<class Type>
99 template<class Type2>
101 (
102  const labelUList& addr,
103  const tmp<Field<Type2>>& tpf,
104  Field<Type2>& intf
105 ) const
106 {
107  subtractFromInternalField(addr, tpf(), intf);
108  tpf.clear();
109 }
110 
111 
112 template<class Type>
114 (
115  scalarField& diag,
116  const direction solveCmpt
117 ) const
118 {
119  forAll(internalCoeffs_, patchi)
120  {
121  addToInternalField
122  (
123  lduAddr().patchAddr(patchi),
124  internalCoeffs_[patchi].component(solveCmpt),
125  diag
126  );
127  }
128 }
129 
130 
131 template<class Type>
133 {
134  forAll(internalCoeffs_, patchi)
135  {
136  addToInternalField
137  (
138  lduAddr().patchAddr(patchi),
139  cmptAv(internalCoeffs_[patchi]),
140  diag
141  );
142  }
143 }
144 
145 
146 template<class Type>
148 (
149  Field<Type>& source,
150  const bool couples
151 ) const
152 {
153  forAll(psi_.boundaryField(), patchi)
154  {
155  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
156  const Field<Type>& pbc = boundaryCoeffs_[patchi];
157 
158  if (!ptf.coupled())
159  {
160  addToInternalField(lduAddr().patchAddr(patchi), pbc, source);
161  }
162  else if (couples)
163  {
164  const tmp<Field<Type>> tpnf = ptf.patchNeighbourField();
165  const Field<Type>& pnf = tpnf();
166 
167  const labelUList& addr = lduAddr().patchAddr(patchi);
168 
169  forAll(addr, facei)
170  {
171  source[addr[facei]] += cmptMultiply(pbc[facei], pnf[facei]);
172  }
173  }
174  }
175 }
176 
177 
178 template<class Type>
179 template<template<class> class ListType>
181 (
182  const labelUList& cellLabels,
183  const ListType<Type>& values
184 )
185 {
186  const fvMesh& mesh = psi_.mesh();
187 
188  const cellList& cells = mesh.cells();
189  const labelUList& own = mesh.owner();
190  const labelUList& nei = mesh.neighbour();
191 
192  scalarField& Diag = diag();
193  Field<Type>& psi =
194  const_cast
195  <
197  >(psi_).primitiveFieldRef();
198 
199  forAll(cellLabels, i)
200  {
201  const label celli = cellLabels[i];
202  const Type& value = values[i];
203 
204  psi[celli] = value;
205  source_[celli] = value*Diag[celli];
206 
207  if (symmetric() || asymmetric())
208  {
209  const cell& c = cells[celli];
210 
211  forAll(c, j)
212  {
213  const label facei = c[j];
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  label patchi = mesh.boundaryMesh().whichPatch(facei);
248 
249  if (internalCoeffs_[patchi].size())
250  {
251  label patchFacei =
252  mesh.boundaryMesh()[patchi].whichFace(facei);
253 
254  internalCoeffs_[patchi][patchFacei] =
255  Zero;
256 
257  boundaryCoeffs_[patchi][patchFacei] =
258  Zero;
259  }
260  }
261  }
262  }
263  }
264 }
265 
266 
267 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
268 
269 template<class Type>
271 (
273  const dimensionSet& ds
274 )
275 :
276  lduMatrix(psi.mesh()),
277  psi_(psi),
278  dimensions_(ds),
279  source_(psi.size(), Zero),
280  internalCoeffs_(psi.mesh().boundary().size()),
281  boundaryCoeffs_(psi.mesh().boundary().size()),
282  faceFluxCorrectionPtr_(nullptr)
283 {
284  if (debug)
285  {
287  << "Constructing fvMatrix<Type> for field " << psi_.name() << endl;
288  }
289 
290  // Initialise coupling coefficients
291  forAll(psi.mesh().boundary(), patchi)
292  {
293  internalCoeffs_.set
294  (
295  patchi,
296  new Field<Type>
297  (
298  psi.mesh().boundary()[patchi].size(),
299  Zero
300  )
301  );
302 
303  boundaryCoeffs_.set
304  (
305  patchi,
306  new Field<Type>
307  (
308  psi.mesh().boundary()[patchi].size(),
309  Zero
310  )
311  );
312  }
313 
314  // Update the boundary coefficients of psi without changing its event No.
317 
318  label currentStatePsi = psiRef.eventNo();
319  psiRef.boundaryFieldRef().updateCoeffs();
320  psiRef.eventNo() = currentStatePsi;
321 }
322 
323 
324 template<class Type>
326 :
327  refCount(),
328  lduMatrix(fvm),
329  psi_(fvm.psi_),
330  dimensions_(fvm.dimensions_),
331  source_(fvm.source_),
332  internalCoeffs_(fvm.internalCoeffs_),
333  boundaryCoeffs_(fvm.boundaryCoeffs_),
334  faceFluxCorrectionPtr_(nullptr)
335 {
336  if (debug)
337  {
339  << "Copying fvMatrix<Type> for field " << psi_.name() << endl;
340  }
341 
342  if (fvm.faceFluxCorrectionPtr_)
343  {
344  faceFluxCorrectionPtr_ = new
346  (
347  *(fvm.faceFluxCorrectionPtr_)
348  );
349  }
350 }
351 
352 
353 template<class Type>
355 :
356  lduMatrix
357  (
358  const_cast<fvMatrix<Type>&>(tfvm()),
359  tfvm.isTmp()
360  ),
361  psi_(tfvm().psi_),
362  dimensions_(tfvm().dimensions_),
363  source_
364  (
365  const_cast<fvMatrix<Type>&>(tfvm()).source_,
366  tfvm.isTmp()
367  ),
368  internalCoeffs_
369  (
370  const_cast<fvMatrix<Type>&>(tfvm()).internalCoeffs_,
371  tfvm.isTmp()
372  ),
373  boundaryCoeffs_
374  (
375  const_cast<fvMatrix<Type>&>(tfvm()).boundaryCoeffs_,
376  tfvm.isTmp()
377  ),
378  faceFluxCorrectionPtr_(nullptr)
379 {
380  if (debug)
381  {
383  << "Copying fvMatrix<Type> for field " << psi_.name() << endl;
384  }
385 
386  if (tfvm().faceFluxCorrectionPtr_)
387  {
388  if (tfvm.isTmp())
389  {
390  faceFluxCorrectionPtr_ = tfvm().faceFluxCorrectionPtr_;
391  tfvm().faceFluxCorrectionPtr_ = nullptr;
392  }
393  else
394  {
395  faceFluxCorrectionPtr_ = new
397  (
398  *(tfvm().faceFluxCorrectionPtr_)
399  );
400  }
401  }
402 
403  tfvm.clear();
404 }
405 
406 
407 template<class Type>
409 (
411  Istream& is
412 )
413 :
414  lduMatrix(psi.mesh()),
415  psi_(psi),
416  dimensions_(is),
417  source_(is),
418  internalCoeffs_(psi.mesh().boundary().size()),
419  boundaryCoeffs_(psi.mesh().boundary().size()),
420  faceFluxCorrectionPtr_(nullptr)
421 {
422  if (debug)
423  {
425  << "Constructing fvMatrix<Type> for field " << psi_.name() << endl;
426  }
427 
428  // Initialise coupling coefficients
429  forAll(psi.mesh().boundary(), patchi)
430  {
431  internalCoeffs_.set
432  (
433  patchi,
434  new Field<Type>
435  (
436  psi.mesh().boundary()[patchi].size(),
437  Zero
438  )
439  );
440 
441  boundaryCoeffs_.set
442  (
443  patchi,
444  new Field<Type>
445  (
446  psi.mesh().boundary()[patchi].size(),
447  Zero
448  )
449  );
450  }
451 
452 }
453 
454 
455 template<class Type>
457 {
458  return tmp<fvMatrix<Type>>
459  (
460  new fvMatrix<Type>(*this)
461  );
462 }
463 
464 
465 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * * //
466 
467 template<class Type>
469 {
470  if (debug)
471  {
473  << "Destroying fvMatrix<Type> for field " << psi_.name() << endl;
474  }
475 
476  if (faceFluxCorrectionPtr_)
477  {
478  delete faceFluxCorrectionPtr_;
479  }
480 }
481 
482 
483 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
484 
485 template<class Type>
487 (
488  const labelUList& cellLabels,
489  const UList<Type>& values
490 )
491 {
492  this->setValuesFromList(cellLabels, values);
493 }
494 
495 
496 template<class Type>
498 (
499  const labelUList& cellLabels,
501 )
502 {
503  this->setValuesFromList(cellLabels, values);
504 }
505 
506 
507 template<class Type>
509 (
510  const label celli,
511  const Type& value,
512  const bool forceReference
513 )
514 {
515  if ((forceReference || psi_.needReference()) && celli >= 0)
516  {
517  source()[celli] += diag()[celli]*value;
518  diag()[celli] += diag()[celli];
519  }
520 }
521 
522 
523 template<class Type>
525 (
526  const labelUList& cellLabels,
527  const Type& value,
528  const bool forceReference
529 )
530 {
531  const bool needRef = (forceReference || psi_.needReference());
532 
533  if (needRef)
534  {
535  forAll(cellLabels, celli)
536  {
537  const label cellId = cellLabels[celli];
538  if (cellId >= 0)
539  {
540  source()[cellId] += diag()[cellId]*value;
541  diag()[cellId] += diag()[cellId];
542  }
543  }
544  }
545 }
546 
547 
548 template<class Type>
550 (
551  const labelUList& cellLabels,
552  const UList<Type>& values,
553  const bool forceReference
554 )
555 {
556  const bool needRef = (forceReference || psi_.needReference());
557 
558  if (needRef)
559  {
560  forAll(cellLabels, celli)
561  {
562  const label cellId = cellLabels[celli];
563  if (cellId >= 0)
564  {
565  source()[cellId] += diag()[cellId]*values[celli];
566  diag()[cellId] += diag()[cellId];
567  }
568  }
569  }
570 }
571 
572 
573 template<class Type>
575 {
576  if (alpha <= 0)
577  {
578  return;
579  }
580 
581  if (debug)
582  {
584  << "Relaxing " << psi_.name() << " by " << alpha << endl;
585  }
586 
587  Field<Type>& S = source();
588  scalarField& D = diag();
589 
590  // Store the current unrelaxed diagonal for use in updating the source
591  scalarField D0(D);
592 
593  // Calculate the sum-mag off-diagonal from the interior faces
594  scalarField sumOff(D.size(), Zero);
595  sumMagOffDiag(sumOff);
596 
597  // Handle the boundary contributions to the diagonal
598  forAll(psi_.boundaryField(), patchi)
599  {
600  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
601 
602  if (ptf.size())
603  {
604  const labelUList& pa = lduAddr().patchAddr(patchi);
605  Field<Type>& iCoeffs = internalCoeffs_[patchi];
606 
607  if (ptf.coupled())
608  {
609  const Field<Type>& pCoeffs = boundaryCoeffs_[patchi];
610 
611  // For coupled boundaries add the diagonal and
612  // off-diagonal contributions
613  forAll(pa, face)
614  {
615  D[pa[face]] += component(iCoeffs[face], 0);
616  sumOff[pa[face]] += mag(component(pCoeffs[face], 0));
617  }
618  }
619  else
620  {
621  // For non-coupled boundaries add the maximum magnitude diagonal
622  // contribution to ensure stability
623  forAll(pa, face)
624  {
625  D[pa[face]] += cmptMax(cmptMag(iCoeffs[face]));
626  }
627  }
628  }
629  }
630 
631 
632  if (debug)
633  {
634  // Calculate amount of non-dominance.
635  label nNon = 0;
636  scalar maxNon = 0.0;
637  scalar sumNon = 0.0;
638  forAll(D, celli)
639  {
640  scalar d = (sumOff[celli] - D[celli])/mag(D[celli]);
641 
642  if (d > 0)
643  {
644  nNon++;
645  maxNon = max(maxNon, d);
646  sumNon += d;
647  }
648  }
649 
650  reduce(nNon, sumOp<label>(), UPstream::msgType(), psi_.mesh().comm());
651  reduce
652  (
653  maxNon,
654  maxOp<scalar>(),
656  psi_.mesh().comm()
657  );
658  reduce
659  (
660  sumNon,
661  sumOp<scalar>(),
663  psi_.mesh().comm()
664  );
665  sumNon /= returnReduce
666  (
667  D.size(),
668  sumOp<label>(),
670  psi_.mesh().comm()
671  );
672 
674  << "Matrix dominance test for " << psi_.name() << nl
675  << " number of non-dominant cells : " << nNon << nl
676  << " maximum relative non-dominance : " << maxNon << nl
677  << " average relative non-dominance : " << sumNon << nl
678  << endl;
679  }
680 
681 
682  // Ensure the matrix is diagonally dominant...
683  // Assumes that the central coefficient is positive and ensures it is
684  forAll(D, celli)
685  {
686  D[celli] = max(mag(D[celli]), sumOff[celli]);
687  }
688 
689  // ... then relax
690  D /= alpha;
691 
692  // Now remove the diagonal contribution from coupled boundaries
693  forAll(psi_.boundaryField(), patchi)
694  {
695  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
696 
697  if (ptf.size())
698  {
699  const labelUList& pa = lduAddr().patchAddr(patchi);
700  Field<Type>& iCoeffs = internalCoeffs_[patchi];
701 
702  if (ptf.coupled())
703  {
704  forAll(pa, face)
705  {
706  D[pa[face]] -= component(iCoeffs[face], 0);
707  }
708  }
709  else
710  {
711  forAll(pa, face)
712  {
713  D[pa[face]] -= cmptMin(iCoeffs[face]);
714  }
715  }
716  }
717  }
718 
719  // Finally add the relaxation contribution to the source.
720  S += (D - D0)*psi_.primitiveField();
721 }
722 
723 
724 template<class Type>
726 {
727  word name = psi_.select
728  (
729  psi_.mesh().data::template lookupOrDefault<bool>
730  ("finalIteration", false)
731  );
732 
733  if (psi_.mesh().relaxEquation(name))
734  {
735  relax(psi_.mesh().equationRelaxationFactor(name));
736  }
737 }
738 
739 
740 template<class Type>
742 (
744  Boundary& bFields
745 )
746 {
747  forAll(bFields, patchi)
748  {
749  bFields[patchi].manipulateMatrix(*this);
750  }
751 }
752 
753 
754 template<class Type>
756 {
757  tmp<scalarField> tdiag(new scalarField(diag()));
758  addCmptAvBoundaryDiag(tdiag.ref());
759  return tdiag;
760 }
761 
762 
763 template<class Type>
765 {
767 
768  forAll(psi_.boundaryField(), patchi)
769  {
770  const fvPatchField<Type>& ptf = psi_.boundaryField()[patchi];
771 
772  if (!ptf.coupled() && ptf.size())
773  {
774  addToInternalField
775  (
776  lduAddr().patchAddr(patchi),
777  internalCoeffs_[patchi],
778  tdiag.ref()
779  );
780  }
781  }
782 
783  return tdiag;
784 }
785 
786 
787 template<class Type>
789 {
790  tmp<volScalarField> tAphi
791  (
792  new volScalarField
793  (
794  IOobject
795  (
796  "A("+psi_.name()+')',
797  psi_.instance(),
798  psi_.mesh(),
801  ),
802  psi_.mesh(),
803  dimensions_/psi_.dimensions()/dimVol,
804  extrapolatedCalculatedFvPatchScalarField::typeName
805  )
806  );
807 
808  tAphi.ref().primitiveFieldRef() = D()/psi_.mesh().V();
809  tAphi.ref().correctBoundaryConditions();
810 
811  return tAphi;
812 }
813 
814 
815 template<class Type>
818 {
820  (
822  (
823  IOobject
824  (
825  "H("+psi_.name()+')',
826  psi_.instance(),
827  psi_.mesh(),
830  ),
831  psi_.mesh(),
832  dimensions_/dimVol,
833  extrapolatedCalculatedFvPatchScalarField::typeName
834  )
835  );
837 
838  // Loop over field components
839  for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
840  {
841  scalarField psiCmpt(psi_.primitiveField().component(cmpt));
842 
843  scalarField boundaryDiagCmpt(psi_.size(), Zero);
844  addBoundaryDiag(boundaryDiagCmpt, cmpt);
845  boundaryDiagCmpt.negate();
846  addCmptAvBoundaryDiag(boundaryDiagCmpt);
847 
848  Hphi.primitiveFieldRef().replace(cmpt, boundaryDiagCmpt*psiCmpt);
849  }
850 
851  Hphi.primitiveFieldRef() += lduMatrix::H(psi_.primitiveField()) + source_;
852  addBoundarySource(Hphi.primitiveFieldRef());
853 
854  Hphi.primitiveFieldRef() /= psi_.mesh().V();
856 
857  typename Type::labelType validComponents
858  (
859  psi_.mesh().template validComponents<Type>()
860  );
861 
862  for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
863  {
864  if (validComponents[cmpt] == -1)
865  {
866  Hphi.replace
867  (
868  cmpt,
869  dimensionedScalar(Hphi.dimensions(), Zero)
870  );
871  }
872  }
873 
874  return tHphi;
875 }
876 
877 
878 template<class Type>
880 {
882  (
883  new volScalarField
884  (
885  IOobject
886  (
887  "H(1)",
888  psi_.instance(),
889  psi_.mesh(),
892  ),
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  {
908  addToInternalField
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().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  IOobject
944  (
945  "flux("+psi_.name()+')',
946  psi_.instance(),
947  psi_.mesh(),
950  ),
951  psi_.mesh(),
952  dimensions()
953  )
954  );
956  tfieldFlux.ref();
957 
958  fieldFlux.setOriented();
959 
960  for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
961  {
962  fieldFlux.primitiveFieldRef().replace
963  (
964  cmpt,
965  lduMatrix::faceH(psi_.primitiveField().component(cmpt))
966  );
967  }
968 
969  FieldField<Field, Type> InternalContrib = internalCoeffs_;
970 
971  forAll(InternalContrib, patchi)
972  {
973  InternalContrib[patchi] =
975  (
976  InternalContrib[patchi],
977  psi_.boundaryField()[patchi].patchInternalField()
978  );
979  }
980 
981  FieldField<Field, Type> NeighbourContrib = boundaryCoeffs_;
982 
983  forAll(NeighbourContrib, patchi)
984  {
985  if (psi_.boundaryField()[patchi].coupled())
986  {
987  NeighbourContrib[patchi] =
989  (
990  NeighbourContrib[patchi],
991  psi_.boundaryField()[patchi].patchNeighbourField()
992  );
993  }
994  }
995 
997  Boundary& ffbf = fieldFlux.boundaryFieldRef();
998 
999  forAll(ffbf, patchi)
1000  {
1001  ffbf[patchi] = InternalContrib[patchi] - NeighbourContrib[patchi];
1002  }
1003 
1004  if (faceFluxCorrectionPtr_)
1005  {
1006  fieldFlux += *faceFluxCorrectionPtr_;
1007  }
1008 
1009  return tfieldFlux;
1010 }
1011 
1012 
1013 template<class Type>
1015 {
1016  return psi_.mesh().solverDict
1017  (
1018  psi_.select
1019  (
1020  psi_.mesh().data::template lookupOrDefault<bool>
1021  ("finalIteration", false)
1022  )
1023  );
1024 }
1025 
1026 
1027 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1028 
1029 template<class Type>
1031 {
1032  if (this == &fvmv)
1033  {
1034  return; // Self-assignment is a no-op
1035  }
1036 
1037  if (&psi_ != &(fvmv.psi_))
1038  {
1040  << "different fields"
1041  << abort(FatalError);
1042  }
1043 
1044  dimensions_ = fvmv.dimensions_;
1045  lduMatrix::operator=(fvmv);
1046  source_ = fvmv.source_;
1047  internalCoeffs_ = fvmv.internalCoeffs_;
1048  boundaryCoeffs_ = fvmv.boundaryCoeffs_;
1049 
1050  if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
1051  {
1052  *faceFluxCorrectionPtr_ = *fvmv.faceFluxCorrectionPtr_;
1053  }
1054  else if (fvmv.faceFluxCorrectionPtr_)
1055  {
1056  faceFluxCorrectionPtr_ =
1058  (*fvmv.faceFluxCorrectionPtr_);
1059  }
1060 }
1061 
1062 
1063 template<class Type>
1065 {
1066  operator=(tfvmv());
1067  tfvmv.clear();
1068 }
1069 
1070 
1071 template<class Type>
1073 {
1075  source_.negate();
1076  internalCoeffs_.negate();
1077  boundaryCoeffs_.negate();
1078 
1079  if (faceFluxCorrectionPtr_)
1080  {
1081  faceFluxCorrectionPtr_->negate();
1082  }
1083 }
1084 
1085 
1086 template<class Type>
1088 {
1089  checkMethod(*this, fvmv, "+=");
1090 
1091  dimensions_ += fvmv.dimensions_;
1092  lduMatrix::operator+=(fvmv);
1093  source_ += fvmv.source_;
1094  internalCoeffs_ += fvmv.internalCoeffs_;
1095  boundaryCoeffs_ += fvmv.boundaryCoeffs_;
1096 
1097  if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
1098  {
1099  *faceFluxCorrectionPtr_ += *fvmv.faceFluxCorrectionPtr_;
1100  }
1101  else if (fvmv.faceFluxCorrectionPtr_)
1102  {
1103  faceFluxCorrectionPtr_ = new
1105  (
1106  *fvmv.faceFluxCorrectionPtr_
1107  );
1108  }
1109 }
1110 
1111 
1112 template<class Type>
1114 {
1115  operator+=(tfvmv());
1116  tfvmv.clear();
1117 }
1118 
1119 
1120 template<class Type>
1122 {
1123  checkMethod(*this, fvmv, "-=");
1124 
1125  dimensions_ -= fvmv.dimensions_;
1126  lduMatrix::operator-=(fvmv);
1127  source_ -= fvmv.source_;
1128  internalCoeffs_ -= fvmv.internalCoeffs_;
1129  boundaryCoeffs_ -= fvmv.boundaryCoeffs_;
1130 
1131  if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)
1132  {
1133  *faceFluxCorrectionPtr_ -= *fvmv.faceFluxCorrectionPtr_;
1134  }
1135  else if (fvmv.faceFluxCorrectionPtr_)
1136  {
1137  faceFluxCorrectionPtr_ =
1139  (-*fvmv.faceFluxCorrectionPtr_);
1140  }
1141 }
1142 
1143 
1144 template<class Type>
1146 {
1147  operator-=(tfvmv());
1148  tfvmv.clear();
1149 }
1150 
1151 
1152 template<class Type>
1156 )
1157 {
1158  checkMethod(*this, su, "+=");
1159  source() -= su.mesh().V()*su.field();
1160 }
1161 
1162 
1163 template<class Type>
1167 )
1168 {
1169  operator+=(tsu());
1170  tsu.clear();
1171 }
1172 
1173 
1174 template<class Type>
1178 )
1179 {
1180  operator+=(tsu());
1181  tsu.clear();
1182 }
1183 
1184 
1185 template<class Type>
1189 )
1190 {
1191  checkMethod(*this, su, "-=");
1192  source() += su.mesh().V()*su.field();
1193 }
1194 
1195 
1196 template<class Type>
1200 )
1201 {
1202  operator-=(tsu());
1203  tsu.clear();
1204 }
1205 
1206 
1207 template<class Type>
1211 )
1212 {
1213  operator-=(tsu());
1214  tsu.clear();
1215 }
1216 
1217 
1218 template<class Type>
1221  const dimensioned<Type>& su
1222 )
1223 {
1224  source() -= psi().mesh().V()*su;
1225 }
1226 
1227 
1228 template<class Type>
1231  const dimensioned<Type>& su
1232 )
1233 {
1234  source() += psi().mesh().V()*su;
1235 }
1236 
1237 
1238 template<class Type>
1241  const zero&
1242 )
1243 {}
1244 
1245 
1246 template<class Type>
1249  const zero&
1250 )
1251 {}
1252 
1253 
1254 template<class Type>
1257  const volScalarField::Internal& dsf
1258 )
1259 {
1260  dimensions_ *= dsf.dimensions();
1261  lduMatrix::operator*=(dsf.field());
1262  source_ *= dsf.field();
1263 
1264  forAll(boundaryCoeffs_, patchi)
1265  {
1266  scalarField pisf
1267  (
1268  dsf.mesh().boundary()[patchi].patchInternalField(dsf.field())
1269  );
1270 
1271  internalCoeffs_[patchi] *= pisf;
1272  boundaryCoeffs_[patchi] *= pisf;
1273  }
1274 
1275  if (faceFluxCorrectionPtr_)
1276  {
1278  << "cannot scale a matrix containing a faceFluxCorrection"
1279  << abort(FatalError);
1280  }
1281 }
1282 
1283 
1284 template<class Type>
1287  const tmp<volScalarField::Internal>& tdsf
1288 )
1289 {
1290  operator*=(tdsf());
1291  tdsf.clear();
1292 }
1293 
1294 
1295 template<class Type>
1298  const tmp<volScalarField>& tvsf
1299 )
1300 {
1301  operator*=(tvsf());
1302  tvsf.clear();
1303 }
1304 
1305 
1306 template<class Type>
1309  const dimensioned<scalar>& ds
1310 )
1311 {
1312  dimensions_ *= ds.dimensions();
1313  lduMatrix::operator*=(ds.value());
1314  source_ *= ds.value();
1315  internalCoeffs_ *= ds.value();
1316  boundaryCoeffs_ *= ds.value();
1317 
1318  if (faceFluxCorrectionPtr_)
1319  {
1320  *faceFluxCorrectionPtr_ *= ds.value();
1321  }
1322 }
1323 
1324 
1325 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
1326 
1327 template<class Type>
1328 void Foam::checkMethod
1330  const fvMatrix<Type>& fvm1,
1331  const fvMatrix<Type>& fvm2,
1332  const char* op
1333 )
1334 {
1335  if (&fvm1.psi() != &fvm2.psi())
1336  {
1338  << "incompatible fields for operation "
1339  << endl << " "
1340  << "[" << fvm1.psi().name() << "] "
1341  << op
1342  << " [" << fvm2.psi().name() << "]"
1343  << abort(FatalError);
1344  }
1345 
1346  if (dimensionSet::debug && fvm1.dimensions() != fvm2.dimensions())
1347  {
1349  << "incompatible dimensions for operation "
1350  << endl << " "
1351  << "[" << fvm1.psi().name() << fvm1.dimensions()/dimVolume << " ] "
1352  << op
1353  << " [" << fvm2.psi().name() << fvm2.dimensions()/dimVolume << " ]"
1354  << abort(FatalError);
1355  }
1356 }
1357 
1358 
1359 template<class Type>
1360 void Foam::checkMethod
1362  const fvMatrix<Type>& fvm,
1364  const char* op
1365 )
1366 {
1367  if (dimensionSet::debug && fvm.dimensions()/dimVolume != df.dimensions())
1368  {
1370  << endl << " "
1371  << "[" << fvm.psi().name() << fvm.dimensions()/dimVolume << " ] "
1372  << op
1373  << " [" << df.name() << df.dimensions() << " ]"
1374  << abort(FatalError);
1375  }
1376 }
1377 
1378 
1379 template<class Type>
1380 void Foam::checkMethod
1382  const fvMatrix<Type>& fvm,
1383  const dimensioned<Type>& dt,
1384  const char* op
1385 )
1386 {
1387  if (dimensionSet::debug && fvm.dimensions()/dimVolume != dt.dimensions())
1388  {
1390  << "incompatible dimensions for operation "
1391  << endl << " "
1392  << "[" << fvm.psi().name() << fvm.dimensions()/dimVolume << " ] "
1393  << op
1394  << " [" << dt.name() << dt.dimensions() << " ]"
1395  << abort(FatalError);
1396  }
1397 }
1398 
1399 
1400 template<class Type>
1402 (
1403  fvMatrix<Type>& fvm,
1404  const dictionary& solverControls
1405 )
1406 {
1407  return fvm.solve(solverControls);
1408 }
1409 
1410 template<class Type>
1412 (
1413  const tmp<fvMatrix<Type>>& tfvm,
1414  const dictionary& solverControls
1415 )
1416 {
1417  SolverPerformance<Type> solverPerf =
1418  const_cast<fvMatrix<Type>&>(tfvm()).solve(solverControls);
1419 
1420  tfvm.clear();
1421 
1422  return solverPerf;
1423 }
1424 
1425 
1426 template<class Type>
1427 Foam::SolverPerformance<Type> Foam::solve(fvMatrix<Type>& fvm)
1428 {
1429  return fvm.solve();
1430 }
1431 
1432 template<class Type>
1433 Foam::SolverPerformance<Type> Foam::solve(const tmp<fvMatrix<Type>>& tfvm)
1434 {
1435  SolverPerformance<Type> solverPerf =
1436  const_cast<fvMatrix<Type>&>(tfvm()).solve();
1437 
1438  tfvm.clear();
1439 
1440  return solverPerf;
1441 }
1442 
1443 
1444 template<class Type>
1446 (
1447  const fvMatrix<Type>& A
1448 )
1449 {
1450  tmp<Foam::fvMatrix<Type>> tAcorr = A - (A & A.psi());
1451 
1452  // Delete the faceFluxCorrection from the correction matrix
1453  // as it does not have a clear meaning or purpose
1454  deleteDemandDrivenData(tAcorr.ref().faceFluxCorrectionPtr());
1455 
1456  return tAcorr;
1457 }
1458 
1459 
1460 template<class Type>
1462 (
1463  const tmp<fvMatrix<Type>>& tA
1464 )
1465 {
1466  tmp<Foam::fvMatrix<Type>> tAcorr = tA - (tA() & tA().psi());
1467 
1468  // Delete the faceFluxCorrection from the correction matrix
1469  // as it does not have a clear meaning or purpose
1470  deleteDemandDrivenData(tAcorr.ref().faceFluxCorrectionPtr());
1471 
1472  return tAcorr;
1473 }
1474 
1475 
1476 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
1477 
1478 template<class Type>
1479 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1480 (
1481  const fvMatrix<Type>& A,
1482  const fvMatrix<Type>& B
1483 )
1484 {
1485  checkMethod(A, B, "==");
1486  return (A - B);
1487 }
1488 
1489 template<class Type>
1490 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1491 (
1492  const tmp<fvMatrix<Type>>& tA,
1493  const fvMatrix<Type>& B
1494 )
1495 {
1496  checkMethod(tA(), B, "==");
1497  return (tA - B);
1498 }
1499 
1500 template<class Type>
1501 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1502 (
1503  const fvMatrix<Type>& A,
1504  const tmp<fvMatrix<Type>>& tB
1505 )
1506 {
1507  checkMethod(A, tB(), "==");
1508  return (A - tB);
1509 }
1510 
1511 template<class Type>
1512 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1513 (
1514  const tmp<fvMatrix<Type>>& tA,
1515  const tmp<fvMatrix<Type>>& tB
1516 )
1517 {
1518  checkMethod(tA(), tB(), "==");
1519  return (tA - tB);
1520 }
1521 
1522 template<class Type>
1523 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1524 (
1525  const fvMatrix<Type>& A,
1526  const DimensionedField<Type, volMesh>& su
1527 )
1528 {
1529  checkMethod(A, su, "==");
1530  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1531  tC.ref().source() += su.mesh().V()*su.field();
1532  return tC;
1533 }
1534 
1535 template<class Type>
1536 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1537 (
1538  const fvMatrix<Type>& A,
1539  const tmp<DimensionedField<Type, volMesh>>& tsu
1540 )
1541 {
1542  checkMethod(A, tsu(), "==");
1543  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1544  tC.ref().source() += tsu().mesh().V()*tsu().field();
1545  tsu.clear();
1546  return tC;
1547 }
1548 
1549 template<class Type>
1550 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1551 (
1552  const fvMatrix<Type>& A,
1553  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tsu
1554 )
1555 {
1556  checkMethod(A, tsu(), "==");
1557  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1558  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
1559  tsu.clear();
1560  return tC;
1561 }
1562 
1563 template<class Type>
1564 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1565 (
1566  const tmp<fvMatrix<Type>>& tA,
1567  const DimensionedField<Type, volMesh>& su
1568 )
1569 {
1570  checkMethod(tA(), su, "==");
1571  tmp<fvMatrix<Type>> tC(tA.ptr());
1572  tC.ref().source() += su.mesh().V()*su.field();
1573  return tC;
1574 }
1575 
1576 template<class Type>
1577 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1578 (
1579  const tmp<fvMatrix<Type>>& tA,
1580  const tmp<DimensionedField<Type, volMesh>>& tsu
1581 )
1582 {
1583  checkMethod(tA(), tsu(), "==");
1584  tmp<fvMatrix<Type>> tC(tA.ptr());
1585  tC.ref().source() += tsu().mesh().V()*tsu().field();
1586  tsu.clear();
1587  return tC;
1588 }
1589 
1590 template<class Type>
1591 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1592 (
1593  const tmp<fvMatrix<Type>>& tA,
1594  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tsu
1595 )
1596 {
1597  checkMethod(tA(), tsu(), "==");
1598  tmp<fvMatrix<Type>> tC(tA.ptr());
1599  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
1600  tsu.clear();
1601  return tC;
1602 }
1603 
1604 template<class Type>
1605 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1606 (
1607  const fvMatrix<Type>& A,
1608  const dimensioned<Type>& su
1609 )
1610 {
1611  checkMethod(A, su, "==");
1612  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1613  tC.ref().source() += A.psi().mesh().V()*su.value();
1614  return tC;
1615 }
1616 
1617 template<class Type>
1618 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1619 (
1620  const tmp<fvMatrix<Type>>& tA,
1621  const dimensioned<Type>& su
1622 )
1623 {
1624  checkMethod(tA(), su, "==");
1625  tmp<fvMatrix<Type>> tC(tA.ptr());
1626  tC.ref().source() += tC().psi().mesh().V()*su.value();
1627  return tC;
1628 }
1629 
1630 template<class Type>
1631 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1632 (
1633  const fvMatrix<Type>& A,
1634  const zero&
1635 )
1636 {
1637  return A;
1638 }
1639 
1640 
1641 template<class Type>
1642 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
1643 (
1644  const tmp<fvMatrix<Type>>& tA,
1645  const zero&
1646 )
1647 {
1648  return tA;
1649 }
1650 
1651 
1652 template<class Type>
1653 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1654 (
1655  const fvMatrix<Type>& A
1656 )
1657 {
1658  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1659  tC.ref().negate();
1660  return tC;
1661 }
1662 
1663 template<class Type>
1664 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1665 (
1666  const tmp<fvMatrix<Type>>& tA
1667 )
1668 {
1669  tmp<fvMatrix<Type>> tC(tA.ptr());
1670  tC.ref().negate();
1671  return tC;
1672 }
1673 
1674 
1675 template<class Type>
1676 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1677 (
1678  const fvMatrix<Type>& A,
1679  const fvMatrix<Type>& B
1680 )
1681 {
1682  checkMethod(A, B, "+");
1683  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1684  tC.ref() += B;
1685  return tC;
1686 }
1687 
1688 template<class Type>
1689 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1690 (
1691  const tmp<fvMatrix<Type>>& tA,
1692  const fvMatrix<Type>& B
1693 )
1694 {
1695  checkMethod(tA(), B, "+");
1696  tmp<fvMatrix<Type>> tC(tA.ptr());
1697  tC.ref() += B;
1698  return tC;
1699 }
1700 
1701 template<class Type>
1702 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1703 (
1704  const fvMatrix<Type>& A,
1705  const tmp<fvMatrix<Type>>& tB
1706 )
1707 {
1708  checkMethod(A, tB(), "+");
1709  tmp<fvMatrix<Type>> tC(tB.ptr());
1710  tC.ref() += A;
1711  return tC;
1712 }
1713 
1714 template<class Type>
1715 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1716 (
1717  const tmp<fvMatrix<Type>>& tA,
1718  const tmp<fvMatrix<Type>>& tB
1719 )
1720 {
1721  checkMethod(tA(), tB(), "+");
1722  tmp<fvMatrix<Type>> tC(tA.ptr());
1723  tC.ref() += tB();
1724  tB.clear();
1725  return tC;
1726 }
1727 
1728 template<class Type>
1729 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1730 (
1731  const fvMatrix<Type>& A,
1732  const DimensionedField<Type, volMesh>& su
1733 )
1734 {
1735  checkMethod(A, su, "+");
1736  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1737  tC.ref().source() -= su.mesh().V()*su.field();
1738  return tC;
1739 }
1740 
1741 template<class Type>
1742 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1743 (
1744  const fvMatrix<Type>& A,
1745  const tmp<DimensionedField<Type, volMesh>>& tsu
1746 )
1747 {
1748  checkMethod(A, tsu(), "+");
1749  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1750  tC.ref().source() -= tsu().mesh().V()*tsu().field();
1751  tsu.clear();
1752  return tC;
1753 }
1754 
1755 template<class Type>
1756 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1757 (
1758  const fvMatrix<Type>& A,
1759  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tsu
1760 )
1761 {
1762  checkMethod(A, tsu(), "+");
1763  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1764  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1765  tsu.clear();
1766  return tC;
1767 }
1768 
1769 template<class Type>
1770 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1771 (
1772  const tmp<fvMatrix<Type>>& tA,
1773  const DimensionedField<Type, volMesh>& su
1774 )
1775 {
1776  checkMethod(tA(), su, "+");
1777  tmp<fvMatrix<Type>> tC(tA.ptr());
1778  tC.ref().source() -= su.mesh().V()*su.field();
1779  return tC;
1780 }
1781 
1782 template<class Type>
1783 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1784 (
1785  const tmp<fvMatrix<Type>>& tA,
1786  const tmp<DimensionedField<Type, volMesh>>& tsu
1787 )
1788 {
1789  checkMethod(tA(), tsu(), "+");
1790  tmp<fvMatrix<Type>> tC(tA.ptr());
1791  tC.ref().source() -= tsu().mesh().V()*tsu().field();
1792  tsu.clear();
1793  return tC;
1794 }
1795 
1796 template<class Type>
1797 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1798 (
1799  const tmp<fvMatrix<Type>>& tA,
1800  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tsu
1801 )
1802 {
1803  checkMethod(tA(), tsu(), "+");
1804  tmp<fvMatrix<Type>> tC(tA.ptr());
1805  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1806  tsu.clear();
1807  return tC;
1808 }
1809 
1810 template<class Type>
1811 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1812 (
1813  const DimensionedField<Type, volMesh>& su,
1814  const fvMatrix<Type>& A
1815 )
1816 {
1817  checkMethod(A, su, "+");
1818  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1819  tC.ref().source() -= su.mesh().V()*su.field();
1820  return tC;
1821 }
1822 
1823 template<class Type>
1824 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1825 (
1826  const tmp<DimensionedField<Type, volMesh>>& tsu,
1827  const fvMatrix<Type>& A
1828 )
1829 {
1830  checkMethod(A, tsu(), "+");
1831  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1832  tC.ref().source() -= tsu().mesh().V()*tsu().field();
1833  tsu.clear();
1834  return tC;
1835 }
1836 
1837 template<class Type>
1838 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1839 (
1840  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tsu,
1841  const fvMatrix<Type>& A
1842 )
1843 {
1844  checkMethod(A, tsu(), "+");
1845  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1846  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1847  tsu.clear();
1848  return tC;
1849 }
1850 
1851 template<class Type>
1852 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1853 (
1854  const DimensionedField<Type, volMesh>& su,
1855  const tmp<fvMatrix<Type>>& tA
1856 )
1857 {
1858  checkMethod(tA(), su, "+");
1859  tmp<fvMatrix<Type>> tC(tA.ptr());
1860  tC.ref().source() -= su.mesh().V()*su.field();
1861  return tC;
1862 }
1863 
1864 template<class Type>
1865 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1866 (
1867  const tmp<DimensionedField<Type, volMesh>>& tsu,
1868  const tmp<fvMatrix<Type>>& tA
1869 )
1870 {
1871  checkMethod(tA(), tsu(), "+");
1872  tmp<fvMatrix<Type>> tC(tA.ptr());
1873  tC.ref().source() -= tsu().mesh().V()*tsu().field();
1874  tsu.clear();
1875  return tC;
1876 }
1877 
1878 template<class Type>
1879 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
1880 (
1881  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tsu,
1882  const tmp<fvMatrix<Type>>& tA
1883 )
1884 {
1885  checkMethod(tA(), tsu(), "+");
1886  tmp<fvMatrix<Type>> tC(tA.ptr());
1887  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
1888  tsu.clear();
1889  return tC;
1890 }
1891 
1892 
1893 template<class Type>
1894 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1895 (
1896  const fvMatrix<Type>& A,
1897  const fvMatrix<Type>& B
1898 )
1899 {
1900  checkMethod(A, B, "-");
1901  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1902  tC.ref() -= B;
1903  return tC;
1904 }
1905 
1906 template<class Type>
1907 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1908 (
1909  const tmp<fvMatrix<Type>>& tA,
1910  const fvMatrix<Type>& B
1911 )
1912 {
1913  checkMethod(tA(), B, "-");
1914  tmp<fvMatrix<Type>> tC(tA.ptr());
1915  tC.ref() -= B;
1916  return tC;
1917 }
1918 
1919 template<class Type>
1920 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1921 (
1922  const fvMatrix<Type>& A,
1923  const tmp<fvMatrix<Type>>& tB
1924 )
1925 {
1926  checkMethod(A, tB(), "-");
1927  tmp<fvMatrix<Type>> tC(tB.ptr());
1928  tC.ref() -= A;
1929  tC.ref().negate();
1930  return tC;
1931 }
1932 
1933 template<class Type>
1934 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1935 (
1936  const tmp<fvMatrix<Type>>& tA,
1937  const tmp<fvMatrix<Type>>& tB
1938 )
1939 {
1940  checkMethod(tA(), tB(), "-");
1941  tmp<fvMatrix<Type>> tC(tA.ptr());
1942  tC.ref() -= tB();
1943  tB.clear();
1944  return tC;
1945 }
1946 
1947 template<class Type>
1948 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1949 (
1950  const fvMatrix<Type>& A,
1951  const DimensionedField<Type, volMesh>& su
1952 )
1953 {
1954  checkMethod(A, su, "-");
1955  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1956  tC.ref().source() += su.mesh().V()*su.field();
1957  return tC;
1958 }
1959 
1960 template<class Type>
1961 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1962 (
1963  const fvMatrix<Type>& A,
1964  const tmp<DimensionedField<Type, volMesh>>& tsu
1965 )
1966 {
1967  checkMethod(A, tsu(), "-");
1968  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1969  tC.ref().source() += tsu().mesh().V()*tsu().field();
1970  tsu.clear();
1971  return tC;
1972 }
1973 
1974 template<class Type>
1975 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1976 (
1977  const fvMatrix<Type>& A,
1978  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tsu
1979 )
1980 {
1981  checkMethod(A, tsu(), "-");
1982  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
1983  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
1984  tsu.clear();
1985  return tC;
1986 }
1987 
1988 template<class Type>
1989 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
1990 (
1991  const tmp<fvMatrix<Type>>& tA,
1992  const DimensionedField<Type, volMesh>& su
1993 )
1994 {
1995  checkMethod(tA(), su, "-");
1996  tmp<fvMatrix<Type>> tC(tA.ptr());
1997  tC.ref().source() += su.mesh().V()*su.field();
1998  return tC;
1999 }
2000 
2001 template<class Type>
2002 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2003 (
2004  const tmp<fvMatrix<Type>>& tA,
2005  const tmp<DimensionedField<Type, volMesh>>& tsu
2006 )
2007 {
2008  checkMethod(tA(), tsu(), "-");
2009  tmp<fvMatrix<Type>> tC(tA.ptr());
2010  tC.ref().source() += tsu().mesh().V()*tsu().field();
2011  tsu.clear();
2012  return tC;
2013 }
2014 
2015 template<class Type>
2016 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2017 (
2018  const tmp<fvMatrix<Type>>& tA,
2019  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tsu
2020 )
2021 {
2022  checkMethod(tA(), tsu(), "-");
2023  tmp<fvMatrix<Type>> tC(tA.ptr());
2024  tC.ref().source() += tsu().mesh().V()*tsu().primitiveField();
2025  tsu.clear();
2026  return tC;
2027 }
2028 
2029 template<class Type>
2030 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2031 (
2032  const DimensionedField<Type, volMesh>& su,
2033  const fvMatrix<Type>& A
2034 )
2035 {
2036  checkMethod(A, su, "-");
2037  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2038  tC.ref().negate();
2039  tC.ref().source() -= su.mesh().V()*su.field();
2040  return tC;
2041 }
2042 
2043 template<class Type>
2044 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2045 (
2046  const tmp<DimensionedField<Type, volMesh>>& tsu,
2047  const fvMatrix<Type>& A
2048 )
2049 {
2050  checkMethod(A, tsu(), "-");
2051  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2052  tC.ref().negate();
2053  tC.ref().source() -= tsu().mesh().V()*tsu().field();
2054  tsu.clear();
2055  return tC;
2056 }
2057 
2058 template<class Type>
2059 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2060 (
2061  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tsu,
2062  const fvMatrix<Type>& A
2063 )
2064 {
2065  checkMethod(A, tsu(), "-");
2066  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2067  tC.ref().negate();
2068  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
2069  tsu.clear();
2070  return tC;
2071 }
2072 
2073 template<class Type>
2074 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2075 (
2076  const DimensionedField<Type, volMesh>& su,
2077  const tmp<fvMatrix<Type>>& tA
2078 )
2079 {
2080  checkMethod(tA(), su, "-");
2081  tmp<fvMatrix<Type>> tC(tA.ptr());
2082  tC.ref().negate();
2083  tC.ref().source() -= su.mesh().V()*su.field();
2084  return tC;
2085 }
2086 
2087 template<class Type>
2088 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2089 (
2090  const tmp<DimensionedField<Type, volMesh>>& tsu,
2091  const tmp<fvMatrix<Type>>& tA
2092 )
2093 {
2094  checkMethod(tA(), tsu(), "-");
2095  tmp<fvMatrix<Type>> tC(tA.ptr());
2096  tC.ref().negate();
2097  tC.ref().source() -= tsu().mesh().V()*tsu().field();
2098  tsu.clear();
2099  return tC;
2100 }
2101 
2102 template<class Type>
2103 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2104 (
2105  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tsu,
2106  const tmp<fvMatrix<Type>>& tA
2107 )
2108 {
2109  checkMethod(tA(), tsu(), "-");
2110  tmp<fvMatrix<Type>> tC(tA.ptr());
2111  tC.ref().negate();
2112  tC.ref().source() -= tsu().mesh().V()*tsu().primitiveField();
2113  tsu.clear();
2114  return tC;
2115 }
2116 
2117 template<class Type>
2118 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2119 (
2120  const fvMatrix<Type>& A,
2121  const dimensioned<Type>& su
2122 )
2123 {
2124  checkMethod(A, su, "+");
2125  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2126  tC.ref().source() -= su.value()*A.psi().mesh().V();
2127  return tC;
2128 }
2129 
2130 template<class Type>
2131 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2132 (
2133  const tmp<fvMatrix<Type>>& tA,
2134  const dimensioned<Type>& su
2135 )
2136 {
2137  checkMethod(tA(), su, "+");
2138  tmp<fvMatrix<Type>> tC(tA.ptr());
2139  tC.ref().source() -= su.value()*tC().psi().mesh().V();
2140  return tC;
2141 }
2142 
2143 template<class Type>
2144 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2145 (
2146  const dimensioned<Type>& su,
2147  const fvMatrix<Type>& A
2148 )
2149 {
2150  checkMethod(A, su, "+");
2151  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2152  tC.ref().source() -= su.value()*A.psi().mesh().V();
2153  return tC;
2154 }
2155 
2156 template<class Type>
2157 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator+
2158 (
2159  const dimensioned<Type>& su,
2160  const tmp<fvMatrix<Type>>& tA
2161 )
2162 {
2163  checkMethod(tA(), su, "+");
2164  tmp<fvMatrix<Type>> tC(tA.ptr());
2165  tC.ref().source() -= su.value()*tC().psi().mesh().V();
2166  return tC;
2167 }
2168 
2169 template<class Type>
2170 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2171 (
2172  const fvMatrix<Type>& A,
2173  const dimensioned<Type>& su
2174 )
2175 {
2176  checkMethod(A, su, "-");
2177  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2178  tC.ref().source() += su.value()*tC().psi().mesh().V();
2179  return tC;
2180 }
2181 
2182 template<class Type>
2183 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2184 (
2185  const tmp<fvMatrix<Type>>& tA,
2186  const dimensioned<Type>& su
2187 )
2188 {
2189  checkMethod(tA(), su, "-");
2190  tmp<fvMatrix<Type>> tC(tA.ptr());
2191  tC.ref().source() += su.value()*tC().psi().mesh().V();
2192  return tC;
2193 }
2194 
2195 template<class Type>
2196 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2197 (
2198  const dimensioned<Type>& su,
2199  const fvMatrix<Type>& A
2200 )
2201 {
2202  checkMethod(A, su, "-");
2203  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2204  tC.ref().negate();
2205  tC.ref().source() -= su.value()*A.psi().mesh().V();
2206  return tC;
2207 }
2208 
2209 template<class Type>
2210 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator-
2211 (
2212  const dimensioned<Type>& su,
2213  const tmp<fvMatrix<Type>>& tA
2214 )
2215 {
2216  checkMethod(tA(), su, "-");
2217  tmp<fvMatrix<Type>> tC(tA.ptr());
2218  tC.ref().negate();
2219  tC.ref().source() -= su.value()*tC().psi().mesh().V();
2220  return tC;
2221 }
2222 
2223 
2224 template<class Type>
2225 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2226 (
2227  const volScalarField::Internal& dsf,
2228  const fvMatrix<Type>& A
2229 )
2230 {
2231  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2232  tC.ref() *= dsf;
2233  return tC;
2234 }
2235 
2236 template<class Type>
2237 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2238 (
2239  const tmp<volScalarField::Internal>& tdsf,
2240  const fvMatrix<Type>& A
2241 )
2242 {
2243  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2244  tC.ref() *= tdsf;
2245  return tC;
2246 }
2247 
2248 template<class Type>
2249 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2250 (
2251  const tmp<volScalarField>& tvsf,
2252  const fvMatrix<Type>& A
2253 )
2254 {
2255  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2256  tC.ref() *= tvsf;
2257  return tC;
2258 }
2259 
2260 template<class Type>
2261 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2262 (
2263  const volScalarField::Internal& dsf,
2264  const tmp<fvMatrix<Type>>& tA
2265 )
2266 {
2267  tmp<fvMatrix<Type>> tC(tA.ptr());
2268  tC.ref() *= dsf;
2269  return tC;
2270 }
2271 
2272 template<class Type>
2273 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2274 (
2275  const tmp<volScalarField::Internal>& tdsf,
2276  const tmp<fvMatrix<Type>>& tA
2277 )
2278 {
2279  tmp<fvMatrix<Type>> tC(tA.ptr());
2280  tC.ref() *= tdsf;
2281  return tC;
2282 }
2283 
2284 template<class Type>
2285 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2286 (
2287  const tmp<volScalarField>& tvsf,
2288  const tmp<fvMatrix<Type>>& tA
2289 )
2290 {
2291  tmp<fvMatrix<Type>> tC(tA.ptr());
2292  tC.ref() *= tvsf;
2293  return tC;
2294 }
2295 
2296 template<class Type>
2297 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2298 (
2299  const dimensioned<scalar>& ds,
2300  const fvMatrix<Type>& A
2301 )
2302 {
2303  tmp<fvMatrix<Type>> tC(new fvMatrix<Type>(A));
2304  tC.ref() *= ds;
2305  return tC;
2306 }
2307 
2308 template<class Type>
2309 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator*
2310 (
2311  const dimensioned<scalar>& ds,
2312  const tmp<fvMatrix<Type>>& tA
2313 )
2314 {
2315  tmp<fvMatrix<Type>> tC(tA.ptr());
2316  tC.ref() *= ds;
2317  return tC;
2318 }
2319 
2320 
2321 template<class Type>
2323 Foam::operator&
2324 (
2325  const fvMatrix<Type>& M,
2326  const DimensionedField<Type, volMesh>& psi
2327 )
2328 {
2329  tmp<GeometricField<Type, fvPatchField, volMesh>> tMphi
2330  (
2331  new GeometricField<Type, fvPatchField, volMesh>
2332  (
2333  IOobject
2334  (
2335  "M&" + psi.name(),
2336  psi.instance(),
2337  psi.mesh(),
2340  ),
2341  psi.mesh(),
2342  M.dimensions()/dimVol,
2343  extrapolatedCalculatedFvPatchScalarField::typeName
2344  )
2345  );
2346  GeometricField<Type, fvPatchField, volMesh>& Mphi = tMphi.ref();
2347 
2348  // Loop over field components
2349  if (M.hasDiag())
2350  {
2351  for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
2352  {
2353  scalarField psiCmpt(psi.field().component(cmpt));
2354  scalarField boundaryDiagCmpt(M.diag());
2355  M.addBoundaryDiag(boundaryDiagCmpt, cmpt);
2356  Mphi.primitiveFieldRef().replace(cmpt, -boundaryDiagCmpt*psiCmpt);
2357  }
2358  }
2359  else
2360  {
2361  Mphi.primitiveFieldRef() = Zero;
2362  }
2363 
2364  Mphi.primitiveFieldRef() += M.lduMatrix::H(psi.field()) + M.source();
2365  M.addBoundarySource(Mphi.primitiveFieldRef());
2366 
2367  Mphi.primitiveFieldRef() /= -psi.mesh().V();
2369 
2370  return tMphi;
2371 }
2372 
2373 template<class Type>
2375 Foam::operator&
2376 (
2377  const fvMatrix<Type>& M,
2378  const tmp<DimensionedField<Type, volMesh>>& tpsi
2379 )
2380 {
2381  tmp<GeometricField<Type, fvPatchField, volMesh>> tMpsi = M & tpsi();
2382  tpsi.clear();
2383  return tMpsi;
2384 }
2385 
2386 template<class Type>
2388 Foam::operator&
2389 (
2390  const fvMatrix<Type>& M,
2391  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tpsi
2392 )
2393 {
2394  tmp<GeometricField<Type, fvPatchField, volMesh>> tMpsi = M & tpsi();
2395  tpsi.clear();
2396  return tMpsi;
2397 }
2398 
2399 template<class Type>
2401 Foam::operator&
2402 (
2403  const tmp<fvMatrix<Type>>& tM,
2404  const DimensionedField<Type, volMesh>& psi
2405 )
2406 {
2407  tmp<GeometricField<Type, fvPatchField, volMesh>> tMpsi = tM() & psi;
2408  tM.clear();
2409  return tMpsi;
2410 }
2411 
2412 template<class Type>
2414 Foam::operator&
2415 (
2416  const tmp<fvMatrix<Type>>& tM,
2417  const tmp<DimensionedField<Type, volMesh>>& tpsi
2418 )
2419 {
2420  tmp<GeometricField<Type, fvPatchField, volMesh>> tMpsi = tM() & tpsi();
2421  tM.clear();
2422  tpsi.clear();
2423  return tMpsi;
2424 }
2425 
2426 template<class Type>
2428 Foam::operator&
2429 (
2430  const tmp<fvMatrix<Type>>& tM,
2431  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tpsi
2432 )
2433 {
2434  tmp<GeometricField<Type, fvPatchField, volMesh>> tMpsi = tM() & tpsi();
2435  tM.clear();
2436  tpsi.clear();
2437  return tMpsi;
2438 }
2439 
2440 
2441 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
2442 
2443 template<class Type>
2444 Foam::Ostream& Foam::operator<<(Ostream& os, const fvMatrix<Type>& fvm)
2445 {
2446  os << static_cast<const lduMatrix&>(fvm) << nl
2447  << fvm.dimensions_ << nl
2448  << fvm.source_ << nl
2449  << fvm.internalCoeffs_ << nl
2450  << fvm.boundaryCoeffs_ << endl;
2451 
2452  os.check(FUNCTION_NAME);
2453 
2454  return os;
2455 }
2456 
2457 
2458 // * * * * * * * * * * * * * * * * Solvers * * * * * * * * * * * * * * * * * //
2459 
2460 #include "fvMatrixSolve.C"
2461 
2462 // ************************************************************************* //
Foam::checkMethod
void checkMethod(const faMatrix< Type > &, const faMatrix< Type > &, const char *)
Definition: faMatrix.C:957
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:817
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:148
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:742
InfoInFunction
#define InfoInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:316
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:132
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:325
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:59
Foam::lduMatrix::operator+=
void operator+=(const lduMatrix &)
Definition: lduMatrixOperations.C:144
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
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:755
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:78
calculatedFvPatchFields.H
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:1030
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:290
Foam::fvMatrix::relax
void relax()
Relax matrix (for steady-state solution).
Definition: fvMatrix.C:725
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:376
Foam::fvMatrix::negate
void negate()
Definition: fvMatrix.C:1072
A
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
surfaceFields.H
Foam::surfaceFields.
Foam::correction
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Return the correction form of the given matrix.
Foam::dimensioned::value
const Type & value() const
Return const reference to value.
Definition: dimensionedType.C:404
Foam::fvMatrix::addBoundaryDiag
void addBoundaryDiag(scalarField &diag, const direction cmpt) const
Definition: fvMatrix.C:114
Foam::stringOps::lower
string lower(const std::string &str)
Return string transformed with std::tolower on each character.
Definition: stringOps.C:1199
Foam::fvMatrix::setReference
void setReference(const label celli, const Type &value, const bool forceReference=false)
Set reference level for solution.
Definition: fvMatrix.C:509
Foam::dimensionSet
Dimension set for the base types.
Definition: dimensionSet.H:65
primitiveFieldRef
conserve primitiveFieldRef()+
Foam::fvMatrix::setReferences
void setReferences(const labelUList &cells, const Type &value, const bool forceReference=false)
Set references level for solution.
Definition: fvMatrix.C:525
Foam::fvMatrix::psi
const GeometricField< Type, fvPatchField, volMesh > & psi() const
Definition: fvMatrix.H:285
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
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::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::fvMatrix::setValues
void setValues(const labelUList &cells, const UList< Type > &values)
Set solution in given cells to the specified values.
Definition: fvMatrix.C:487
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:258
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::fvMatrix::operator-=
void operator-=(const fvMatrix< Type > &)
Definition: fvMatrix.C:1121
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
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:879
Foam::fvMatrix::~fvMatrix
virtual ~fvMatrix()
Destructor.
Definition: fvMatrix.C:468
Foam::cmptAv
tmp< DimensionedField< typename DimensionedField< Type, GeoMesh >::cmptType, GeoMesh >> cmptAv(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:246
Foam::stringOps::upper
string upper(const std::string &str)
Return string transformed with std::toupper on each character.
Definition: stringOps.C:1219
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::Field::replace
void replace(const direction, const UList< cmptType > &)
Replace a component field of the field.
Definition: Field.C:574
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:297
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:764
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:788
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:84
Foam::lduMatrix::negate
void negate()
Definition: lduMatrixOperations.C:125
Foam::tmp::ptr
T * ptr() const
Definition: tmpI.H:296
Foam::lduMatrix::H
tmp< Field< Type > > H(const Field< Type > &) const
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
Foam::DimensionedField::dimensions
const dimensionSet & dimensions() const
Return dimensions.
Definition: DimensionedFieldI.H:49
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:735
Foam::GeometricField::correctBoundaryConditions
void correctBoundaryConditions()
Correct boundary field.
Definition: GeometricField.C:909
Foam::UPstream::msgType
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:491
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::fvMatrix::setValuesFromList
void setValuesFromList(const labelUList &cells, const ListType< Type > &values)
Set solution in given cells to the specified values.
Definition: fvMatrix.C:181
Foam::nl
constexpr char nl
Definition: Ostream.H:372
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:718
Foam::GeometricField::boundaryFieldRef
Boundary & boundaryFieldRef(const bool updateAccessTime=true)
Return a reference to the boundary field.
Definition: GeometricField.C:752
Foam::fvMatrix::operator+=
void operator+=(const fvMatrix< Type > &)
Definition: fvMatrix.C:1087
Foam::List< cell >
Foam::pTraits
Traits class for primitives.
Definition: pTraits.H:52
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:1014
M
#define M(I)
Foam::UList< label >
D
const dimensionedScalar & D
Definition: solveBulkSurfactant.H:4
Foam::direction
uint8_t direction
Definition: direction.H:47
Foam::fvMatrix::clone
tmp< fvMatrix< Type > > clone() const
Clone.
Definition: fvMatrix.C:456
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:261
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
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: fvMatrix.H:109
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:74
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::dimensioned::dimensions
const dimensionSet & dimensions() const
Return const reference to dimensions.
Definition: dimensionedType.C:390
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:41
Foam::SolverPerformance
SolverPerformance is the class returned by the LduMatrix solver containing performance statistics.
Definition: SolverPerformance.H:51
Foam::cell
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:54
Foam::fvMatrix::flux
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > flux() const
Return the face-flux field from the matrix.
Definition: fvMatrix.C:927
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &)
Definition: boundaryPatch.C:102
Foam::fvMatrix::fvMatrix
fvMatrix(const GeometricField< Type, fvPatchField, volMesh > &, const dimensionSet &)
Construct given a field to solve for.
Definition: fvMatrix.C:271
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), which can be used to avoid manipulating objects that ar...
Definition: zero.H:61
relax
UEqn relax()