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