faMatrix.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) 2016-2017 Wikki Ltd
9  Copyright (C) 2019-2021 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 "areaFields.H"
30 #include "edgeFields.H"
33 #include "UIndirectList.H"
34 #include "UniformList.H"
35 #include "demandDrivenData.H"
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 template<class Type>
40 template<class Type2>
42 (
43  const labelUList& addr,
44  const Field<Type2>& pf,
45  Field<Type2>& intf
46 ) const
47 {
48  if (addr.size() != pf.size())
49  {
51  << "addressing (" << addr.size()
52  << ") and field (" << pf.size() << ") are different sizes" << endl
53  << abort(FatalError);
54  }
55 
56  forAll(addr, faceI)
57  {
58  intf[addr[faceI]] += pf[faceI];
59  }
60 }
61 
62 
63 template<class Type>
64 template<class Type2>
66 (
67  const labelUList& addr,
68  const tmp<Field<Type2>>& tpf,
69  Field<Type2>& intf
70 ) const
71 {
72  addToInternalField(addr, tpf(), intf);
73  tpf.clear();
74 }
75 
76 
77 template<class Type>
78 template<class Type2>
80 (
81  const labelUList& addr,
82  const Field<Type2>& pf,
83  Field<Type2>& intf
84 ) const
85 {
86  if (addr.size() != pf.size())
87  {
89  << "addressing (" << addr.size()
90  << ") and field (" << pf.size() << ") are different sizes" << endl
91  << abort(FatalError);
92  }
93 
94  forAll(addr, faceI)
95  {
96  intf[addr[faceI]] -= pf[faceI];
97  }
98 }
99 
100 
101 template<class Type>
102 template<class Type2>
104 (
105  const labelUList& addr,
106  const tmp<Field<Type2>>& tpf,
107  Field<Type2>& intf
108 ) const
109 {
110  subtractFromInternalField(addr, tpf(), intf);
111  tpf.clear();
112 }
113 
114 
115 template<class Type>
117 (
118  scalarField& diag,
119  const direction solveCmpt
120 ) const
121 {
122  forAll(internalCoeffs_, patchI)
123  {
124  addToInternalField
125  (
126  lduAddr().patchAddr(patchI),
127  internalCoeffs_[patchI].component(solveCmpt),
128  diag
129  );
130  }
131 }
132 
133 
134 template<class Type>
136 {
137  forAll(internalCoeffs_, patchI)
138  {
139  addToInternalField
140  (
141  lduAddr().patchAddr(patchI),
142  cmptAv(internalCoeffs_[patchI]),
143  diag
144  );
145  }
146 }
147 
148 
149 template<class Type>
151 (
152  Field<Type>& source,
153  const bool couples
154 ) const
155 {
156  forAll(psi_.boundaryField(), patchI)
157  {
158  const faPatchField<Type>& ptf = psi_.boundaryField()[patchI];
159  const Field<Type>& pbc = boundaryCoeffs_[patchI];
160 
161  if (!ptf.coupled())
162  {
163  addToInternalField(lduAddr().patchAddr(patchI), pbc, source);
164  }
165  else if (couples)
166  {
167  tmp<Field<Type>> tpnf = ptf.patchNeighbourField();
168  const Field<Type>& pnf = tpnf();
169 
170  const labelUList& addr = lduAddr().patchAddr(patchI);
171 
172  forAll(addr, facei)
173  {
174  source[addr[facei]] += cmptMultiply(pbc[facei], pnf[facei]);
175  }
176  }
177  }
178 }
179 
180 
181 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
182 
183 template<class Type>
185 (
187  const dimensionSet& ds
188 )
189 :
190  lduMatrix(psi.mesh()),
191  psi_(psi),
192  dimensions_(ds),
193  source_(psi.size(), Zero),
194  internalCoeffs_(psi.mesh().boundary().size()),
195  boundaryCoeffs_(psi.mesh().boundary().size()),
196  faceFluxCorrectionPtr_(nullptr)
197 {
199  << "constructing faMatrix<Type> for field " << psi_.name()
200  << endl;
201 
202  // Initialise coupling coefficients
203  forAll(psi.mesh().boundary(), patchI)
204  {
205  internalCoeffs_.set
206  (
207  patchI,
208  new Field<Type>
209  (
210  psi.mesh().boundary()[patchI].size(),
211  Zero
212  )
213  );
214 
215  boundaryCoeffs_.set
216  (
217  patchI,
218  new Field<Type>
219  (
220  psi.mesh().boundary()[patchI].size(),
221  Zero
222  )
223  );
224  }
225 
226  // Update the boundary coefficients of psi without changing its event No.
227  auto& psiRef =
229 
230  const label currentStatePsi = psiRef.eventNo();
231  psiRef.boundaryFieldRef().updateCoeffs();
232  psiRef.eventNo() = currentStatePsi;
233 }
234 
235 
236 template<class Type>
238 :
239  refCount(),
240  lduMatrix(fam),
241  psi_(fam.psi_),
242  dimensions_(fam.dimensions_),
243  source_(fam.source_),
244  internalCoeffs_(fam.internalCoeffs_),
245  boundaryCoeffs_(fam.boundaryCoeffs_),
246  faceFluxCorrectionPtr_(nullptr)
247 {
249  << "copying faMatrix<Type> for field " << psi_.name()
250  << endl;
251 
252  if (fam.faceFluxCorrectionPtr_)
253  {
254  faceFluxCorrectionPtr_ = new
256  (
257  *(fam.faceFluxCorrectionPtr_)
258  );
259  }
260 }
261 
262 
263 template<class Type>
265 (
267  Istream& is
268 )
269 :
270  lduMatrix(psi.mesh()),
271  psi_(psi),
272  dimensions_(is),
273  source_(is),
274  internalCoeffs_(psi.mesh().boundary().size()),
275  boundaryCoeffs_(psi.mesh().boundary().size()),
276  faceFluxCorrectionPtr_(nullptr)
277 {
279  << "constructing faMatrix<Type> for field " << psi_.name()
280  << endl;
281 
282  // Initialise coupling coefficients
283  forAll(psi.mesh().boundary(), patchI)
284  {
285  internalCoeffs_.set
286  (
287  patchI,
288  new Field<Type>
289  (
290  psi.mesh().boundary()[patchI].size(),
291  Zero
292  )
293  );
294 
295  boundaryCoeffs_.set
296  (
297  patchI,
298  new Field<Type>
299  (
300  psi.mesh().boundary()[patchI].size(),
301  Zero
302  )
303  );
304  }
305 }
306 
307 
308 template<class Type>
310 {
311  return tmp<faMatrix<Type>>::New(*this);
312 }
313 
314 
315 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * * //
316 
317 
318 template<class Type>
320 {
322  << "Destroying faMatrix<Type> for field " << psi_.name() << endl;
323 
324  deleteDemandDrivenData(faceFluxCorrectionPtr_);
325 }
326 
327 
328 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
329 
330 template<class Type>
331 template<template<class> class ListType>
333 (
334  const labelUList& faceLabels,
335  const ListType<Type>& values
336 )
337 {
338 #if 0 /* Specific to foam-extend */
339  // Record face labels of eliminated equations
340  for (const label i : faceLabels)
341  {
342  this->eliminatedEqns().insert(i);
343  }
344 #endif
345 
346  const faMesh& mesh = psi_.mesh();
347 
348  const labelListList& edges = mesh.patch().faceEdges();
349  const labelUList& own = mesh.owner();
350  const labelUList& nei = mesh.neighbour();
351 
352  scalarField& Diag = diag();
353  Field<Type>& psi =
354  const_cast
355  <
357  >(psi_).primitiveFieldRef();
358 
359  forAll(faceLabels, i)
360  {
361  const label facei = faceLabels[i];
362  const Type& value = values[i];
363 
364  psi[facei] = value;
365  source_[facei] = value*Diag[facei];
366 
367  if (symmetric() || asymmetric())
368  {
369  for (const label edgei : edges[facei])
370  {
371  if (mesh.isInternalEdge(edgei))
372  {
373  if (symmetric())
374  {
375  if (facei == own[edgei])
376  {
377  source_[nei[edgei]] -= upper()[edgei]*value;
378  }
379  else
380  {
381  source_[own[edgei]] -= upper()[edgei]*value;
382  }
383 
384  upper()[edgei] = 0.0;
385  }
386  else
387  {
388  if (facei == own[edgei])
389  {
390  source_[nei[edgei]] -= lower()[edgei]*value;
391  }
392  else
393  {
394  source_[own[edgei]] -= upper()[edgei]*value;
395  }
396 
397  upper()[edgei] = 0.0;
398  lower()[edgei] = 0.0;
399  }
400  }
401  else
402  {
403  const label patchi = mesh.boundary().whichPatch(edgei);
404 
405  if (internalCoeffs_[patchi].size())
406  {
407  const label patchEdgei =
408  mesh.boundary()[patchi].whichEdge(edgei);
409 
410  internalCoeffs_[patchi][patchEdgei] = Zero;
411  boundaryCoeffs_[patchi][patchEdgei] = Zero;
412  }
413  }
414  }
415  }
416  }
417 }
418 
419 
420 template<class Type>
422 (
423  const labelUList& faceLabels,
424  const Type& value
425 )
426 {
427  this->setValuesFromList(faceLabels, UniformList<Type>(value));
428 }
429 
430 
431 template<class Type>
433 (
434  const labelUList& faceLabels,
435  const UList<Type>& values
436 )
437 {
438  this->setValuesFromList(faceLabels, values);
439 }
440 
441 
442 template<class Type>
444 (
445  const labelUList& faceLabels,
447 )
448 {
449  this->setValuesFromList(faceLabels, values);
450 }
451 
452 
453 template<class Type>
455 (
456  const label facei,
457  const Type& value,
458  const bool forceReference
459 )
460 {
461  if ((forceReference || psi_.needReference()) && facei >= 0)
462  {
463  if (Pstream::master())
464  {
465  source()[facei] += diag()[facei]*value;
466  diag()[facei] += diag()[facei];
467  }
468  }
469 }
470 
471 
472 template<class Type>
474 (
475  const labelUList& faceLabels,
476  const Type& value,
477  const bool forceReference
478 )
479 {
480  if (forceReference || psi_.needReference())
481  {
482  forAll(faceLabels, facei)
483  {
484  const label faceId = faceLabels[facei];
485  if (faceId >= 0)
486  {
487  source()[faceId] += diag()[faceId]*value;
488  diag()[faceId] += diag()[faceId];
489  }
490  }
491  }
492 }
493 
494 
495 template<class Type>
497 (
498  const labelUList& faceLabels,
499  const UList<Type>& values,
500  const bool forceReference
501 )
502 {
503  if (forceReference || psi_.needReference())
504  {
505  forAll(faceLabels, facei)
506  {
507  const label faceId = faceLabels[facei];
508  if (faceId >= 0)
509  {
510  source()[faceId] += diag()[faceId]*values[facei];
511  diag()[faceId] += diag()[faceId];
512  }
513  }
514  }
515 }
516 
517 
518 template<class Type>
520 {
521  if (alpha <= 0)
522  {
523  return;
524  }
525 
526  Field<Type>& S = source();
527  scalarField& D = diag();
528 
529  // Store the current unrelaxed diagonal for use in updating the source
530  scalarField D0(D);
531 
532  // Calculate the sum-mag off-diagonal from the interior faces
533  scalarField sumOff(D.size(), Zero);
534  sumMagOffDiag(sumOff);
535 
536  // Handle the boundary contributions to the diagonal
537  forAll(psi_.boundaryField(), patchI)
538  {
539  const faPatchField<Type>& ptf = psi_.boundaryField()[patchI];
540 
541  if (ptf.size())
542  {
543  const labelUList& pa = lduAddr().patchAddr(patchI);
544  Field<Type>& iCoeffs = internalCoeffs_[patchI];
545 
546  if (ptf.coupled())
547  {
548  const Field<Type>& pCoeffs = boundaryCoeffs_[patchI];
549 
550  // For coupled boundaries add the diagonal and
551  // off-diagonal contributions
552  forAll(pa, face)
553  {
554  D[pa[face]] += component(iCoeffs[face], 0);
555  sumOff[pa[face]] += mag(component(pCoeffs[face], 0));
556  }
557  }
558  else
559  {
560  // For non-coupled boundaries subtract the diagonal
561  // contribution off-diagonal sum which avoids having to remove
562  // it from the diagonal later.
563  // Also add the source contribution from the relaxation
564  forAll(pa, face)
565  {
566  Type iCoeff0 = iCoeffs[face];
567  iCoeffs[face] = cmptMag(iCoeffs[face]);
568  sumOff[pa[face]] -= cmptMin(iCoeffs[face]);
569  iCoeffs[face] /= alpha;
570  S[pa[face]] +=
571  cmptMultiply(iCoeffs[face] - iCoeff0, psi_[pa[face]]);
572  }
573  }
574  }
575  }
576 
577  // Ensure the matrix is diagonally dominant...
578  max(D, D, sumOff);
579 
580  // ... then relax
581  D /= alpha;
582 
583  // Now remove the diagonal contribution from coupled boundaries
584  forAll(psi_.boundaryField(), patchI)
585  {
586  const faPatchField<Type>& ptf = psi_.boundaryField()[patchI];
587 
588  if (ptf.size())
589  {
590  const labelUList& pa = lduAddr().patchAddr(patchI);
591  Field<Type>& iCoeffs = internalCoeffs_[patchI];
592 
593  if (ptf.coupled())
594  {
595  forAll(pa, face)
596  {
597  D[pa[face]] -= component(iCoeffs[face], 0);
598  }
599  }
600  }
601  }
602 
603  // Finally add the relaxation contribution to the source.
604  S += (D - D0)*psi_.internalField();
605 }
606 
607 
608 template<class Type>
610 {
611  if (psi_.mesh().relaxEquation(psi_.name()))
612  {
613  relax(psi_.mesh().equationRelaxationFactor(psi_.name()));
614  }
615  else
616  {
618  << "Relaxation factor for field " << psi_.name()
619  << " not found. Relaxation will not be used." << endl;
620  }
621 }
622 
623 
624 template<class Type>
626 {
627  tmp<scalarField> tdiag(new scalarField(diag()));
628  addCmptAvBoundaryDiag(tdiag.ref());
629  return tdiag;
630 }
631 
632 
633 template<class Type>
635 {
637  (
638  new areaScalarField
639  (
640  IOobject
641  (
642  "A("+psi_.name()+')',
643  psi_.instance(),
644  psi_.db()
645  ),
646  psi_.mesh(),
647  dimensions_/psi_.dimensions()/dimArea,
648  zeroGradientFaPatchScalarField::typeName
649  )
650  );
651 
652  tAphi.ref().primitiveFieldRef() = D()/psi_.mesh().S();
653  tAphi.ref().correctBoundaryConditions();
654 
655  return tAphi;
656 }
657 
658 
659 template<class Type>
662 {
664  (
666  (
667  IOobject
668  (
669  "H("+psi_.name()+')',
670  psi_.instance(),
671  psi_.db()
672  ),
673  psi_.mesh(),
674  dimensions_/dimArea,
675  zeroGradientFaPatchScalarField::typeName
676  )
677  );
679 
680  // Loop over field components
681  for (direction cmpt=0; cmpt<Type::nComponents; ++cmpt)
682  {
683  scalarField psiCmpt(psi_.primitiveField().component(cmpt));
684 
685  scalarField boundaryDiagCmpt(psi_.size(), Zero);
686  addBoundaryDiag(boundaryDiagCmpt, cmpt);
687  boundaryDiagCmpt.negate();
688  addCmptAvBoundaryDiag(boundaryDiagCmpt);
689 
690  Hphi.primitiveFieldRef().replace(cmpt, boundaryDiagCmpt*psiCmpt);
691  }
692 
693  Hphi.primitiveFieldRef() += lduMatrix::H(psi_.internalField()) + source_;
694  addBoundarySource(Hphi.primitiveFieldRef());
695 
696  Hphi.primitiveFieldRef() /= psi_.mesh().S();
698 
699  return tHphi;
700 }
701 
702 
703 template<class Type>
706 {
707  if (!psi_.mesh().fluxRequired(psi_.name()))
708  {
710  << "flux requested but " << psi_.name()
711  << " not specified in the fluxRequired sub-dictionary of faSchemes"
712  << abort(FatalError);
713  }
714 
715  // construct GeometricField<Type, faePatchField, edgeMesh>
717  (
719  (
720  IOobject
721  (
722  "flux("+psi_.name()+')',
723  psi_.instance(),
724  psi_.db()
725  ),
726  psi_.mesh(),
727  dimensions()
728  )
729  );
731  tfieldFlux.ref();
732 
733  for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; ++cmpt)
734  {
735  fieldFlux.primitiveFieldRef().replace
736  (
737  cmpt,
738  lduMatrix::faceH(psi_.primitiveField().component(cmpt))
739  );
740  }
741 
742  FieldField<Field, Type> InternalContrib = internalCoeffs_;
743 
744  forAll(InternalContrib, patchI)
745  {
746  InternalContrib[patchI] =
748  (
749  InternalContrib[patchI],
750  psi_.boundaryField()[patchI].patchInternalField()
751  );
752  }
753 
754  FieldField<Field, Type> NeighbourContrib = boundaryCoeffs_;
755 
756  forAll(NeighbourContrib, patchI)
757  {
758  if (psi_.boundaryField()[patchI].coupled())
759  {
760  NeighbourContrib[patchI] =
762  (
763  NeighbourContrib[patchI],
764  psi_.boundaryField()[patchI].patchNeighbourField()
765  );
766  }
767  }
768 
769  forAll(fieldFlux.boundaryField(), patchI)
770  {
771  fieldFlux.boundaryFieldRef()[patchI] =
772  InternalContrib[patchI] - NeighbourContrib[patchI];
773  }
774 
775  if (faceFluxCorrectionPtr_)
776  {
777  fieldFlux += *faceFluxCorrectionPtr_;
778  }
779 
780  return tfieldFlux;
781 }
782 
783 
784 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
785 
786 template<class Type>
788 {
789  if (this == &famv)
790  {
791  return; // Self-assignment is a no-op
792  }
793 
794  if (&psi_ != &(famv.psi_))
795  {
797  << "different fields"
798  << abort(FatalError);
799  }
800 
801  lduMatrix::operator=(famv);
802  source_ = famv.source_;
803  internalCoeffs_ = famv.internalCoeffs_;
804  boundaryCoeffs_ = famv.boundaryCoeffs_;
805 
806  if (faceFluxCorrectionPtr_ && famv.faceFluxCorrectionPtr_)
807  {
808  *faceFluxCorrectionPtr_ = *famv.faceFluxCorrectionPtr_;
809  }
810  else if (famv.faceFluxCorrectionPtr_)
811  {
812  faceFluxCorrectionPtr_ =
814  (*famv.faceFluxCorrectionPtr_);
815  }
816 }
817 
818 
819 template<class Type>
821 {
822  operator=(tfamv());
823  tfamv.clear();
824 }
825 
826 
827 template<class Type>
829 {
831  source_.negate();
832  internalCoeffs_.negate();
833  boundaryCoeffs_.negate();
834 
835  if (faceFluxCorrectionPtr_)
836  {
837  faceFluxCorrectionPtr_->negate();
838  }
839 }
840 
841 
842 template<class Type>
844 {
845  checkMethod(*this, famv, "+=");
846 
847  dimensions_ += famv.dimensions_;
848  lduMatrix::operator+=(famv);
849  source_ += famv.source_;
850  internalCoeffs_ += famv.internalCoeffs_;
851  boundaryCoeffs_ += famv.boundaryCoeffs_;
852 
853  if (faceFluxCorrectionPtr_ && famv.faceFluxCorrectionPtr_)
854  {
855  *faceFluxCorrectionPtr_ += *famv.faceFluxCorrectionPtr_;
856  }
857  else if (famv.faceFluxCorrectionPtr_)
858  {
859  faceFluxCorrectionPtr_ = new
861  (
862  *famv.faceFluxCorrectionPtr_
863  );
864  }
865 }
866 
867 
868 template<class Type>
870 {
871  operator+=(tfamv());
872  tfamv.clear();
873 }
874 
875 
876 template<class Type>
878 {
879  checkMethod(*this, famv, "+=");
880 
881  dimensions_ -= famv.dimensions_;
882  lduMatrix::operator-=(famv);
883  source_ -= famv.source_;
884  internalCoeffs_ -= famv.internalCoeffs_;
885  boundaryCoeffs_ -= famv.boundaryCoeffs_;
886 
887  if (faceFluxCorrectionPtr_ && famv.faceFluxCorrectionPtr_)
888  {
889  *faceFluxCorrectionPtr_ -= *famv.faceFluxCorrectionPtr_;
890  }
891  else if (famv.faceFluxCorrectionPtr_)
892  {
893  faceFluxCorrectionPtr_ =
895  (-*famv.faceFluxCorrectionPtr_);
896  }
897 }
898 
899 
900 template<class Type>
902 {
903  operator-=(tfamv());
904  tfamv.clear();
905 }
906 
907 
908 template<class Type>
910 (
912 )
913 {
914  checkMethod(*this, su, "+=");
915  source() -= su.mesh().S()*su.internalField();
916 }
917 
918 
919 template<class Type>
921 (
923 )
924 {
925  operator+=(tsu());
926  tsu.clear();
927 }
928 
929 
930 template<class Type>
932 (
934 )
935 {
936  checkMethod(*this, su, "-=");
937  source() += su.mesh().S()*su.internalField();
938 }
939 
940 
941 template<class Type>
943 (
945 )
946 {
947  operator-=(tsu());
948  tsu.clear();
949 }
950 
951 
952 template<class Type>
954 (
955  const dimensioned<Type>& su
956 )
957 {
958  source() -= su.mesh().S()*su;
959 }
960 
961 
962 template<class Type>
964 (
965  const dimensioned<Type>& su
966 )
967 {
968  source() += su.mesh().S()*su;
969 }
970 
971 
972 template<class Type>
974 (
975  const areaScalarField& vsf
976 )
977 {
978  dimensions_ *= vsf.dimensions();
979  lduMatrix::operator*=(vsf.internalField());
980  source_ *= vsf.internalField();
981 
982  forAll(boundaryCoeffs_, patchI)
983  {
984  const scalarField psf(vsf.boundaryField()[patchI].patchInternalField());
985  internalCoeffs_[patchI] *= psf;
986  boundaryCoeffs_[patchI] *= psf;
987  }
988 
989  if (faceFluxCorrectionPtr_)
990  {
992  << "cannot scale a matrix containing a faceFluxCorrection"
993  << abort(FatalError);
994  }
995 }
996 
997 
998 template<class Type>
1001  const tmp<areaScalarField>& tvsf
1002 )
1003 {
1004  operator*=(tvsf());
1005  tvsf.clear();
1006 }
1007 
1008 
1009 template<class Type>
1012  const dimensioned<scalar>& ds
1013 )
1014 {
1015  dimensions_ *= ds.dimensions();
1016  lduMatrix::operator*=(ds.value());
1017  source_ *= ds.value();
1018  internalCoeffs_ *= ds.value();
1019  boundaryCoeffs_ *= ds.value();
1020 
1021  if (faceFluxCorrectionPtr_)
1022  {
1023  *faceFluxCorrectionPtr_ *= ds.value();
1024  }
1025 }
1026 
1027 
1028 // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
1029 
1030 template<class Type>
1031 void Foam::checkMethod
1033  const faMatrix<Type>& fam1,
1034  const faMatrix<Type>& fam2,
1035  const char* op
1036 )
1037 {
1038  if (&fam1.psi() != &fam2.psi())
1039  {
1041  << "incompatible fields for operation "
1042  << endl << " "
1043  << "[" << fam1.psi().name() << "] "
1044  << op
1045  << " [" << fam2.psi().name() << "]"
1046  << abort(FatalError);
1047  }
1048 
1049  if
1050  (
1052  && fam1.dimensions() != fam2.dimensions()
1053  )
1054  {
1056  << "incompatible dimensions for operation "
1057  << endl << " "
1058  << "[" << fam1.psi().name() << fam1.dimensions()/dimArea << " ] "
1059  << op
1060  << " [" << fam2.psi().name() << fam2.dimensions()/dimArea << " ]"
1061  << abort(FatalError);
1062  }
1063 }
1064 
1065 
1066 template<class Type>
1067 void Foam::checkMethod
1069  const faMatrix<Type>& fam,
1071  const char* op
1072 )
1073 {
1074  if
1075  (
1077  && fam.dimensions()/dimArea != vf.dimensions()
1078  )
1079  {
1081  << "incompatible dimensions for operation "
1082  << endl << " "
1083  << "[" << fam.psi().name() << fam.dimensions()/dimArea << " ] "
1084  << op
1085  << " [" << vf.name() << vf.dimensions() << " ]"
1086  << abort(FatalError);
1087  }
1088 }
1089 
1090 
1091 template<class Type>
1092 void Foam::checkMethod
1094  const faMatrix<Type>& fam,
1095  const dimensioned<Type>& dt,
1096  const char* op
1097 )
1098 {
1099  if
1100  (
1102  && fam.dimensions()/dimArea != dt.dimensions()
1103  )
1104  {
1106  << "incompatible dimensions for operation "
1107  << endl << " "
1108  << "[" << fam.psi().name() << fam.dimensions()/dimArea << " ] "
1109  << op
1110  << " [" << dt.name() << dt.dimensions() << " ]"
1111  << abort(FatalError);
1112  }
1113 }
1114 
1115 
1116 template<class Type>
1118 (
1119  faMatrix<Type>& fam,
1120  Istream& solverControls
1121 )
1122 {
1123  return fam.solve(solverControls);
1124 }
1125 
1126 
1127 template<class Type>
1129 (
1130  const tmp<faMatrix<Type>>& tfam,
1131  Istream& solverControls
1132 )
1133 {
1134  SolverPerformance<Type> solverPerf =
1135  const_cast<faMatrix<Type>&>(tfam()).solve(solverControls);
1136 
1137  tfam.clear();
1138  return solverPerf;
1139 }
1140 
1141 
1142 template<class Type>
1144 {
1145  return fam.solve();
1146 }
1147 
1148 
1149 template<class Type>
1150 Foam::SolverPerformance<Type> Foam::solve(const tmp<faMatrix<Type>>& tfam)
1151 {
1152  SolverPerformance<Type> solverPerf =
1153  const_cast<faMatrix<Type>&>(tfam()).solve();
1154 
1155  tfam.clear();
1156  return solverPerf;
1157 }
1158 
1159 
1160 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
1161 
1162 template<class Type>
1163 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1164 (
1165  const faMatrix<Type>& A,
1166  const faMatrix<Type>& B
1167 )
1168 {
1169  checkMethod(A, B, "+");
1170  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1171  tC.ref() += B;
1172  return tC;
1173 }
1174 
1175 
1176 template<class Type>
1177 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1178 (
1179  const tmp<faMatrix<Type>>& tA,
1180  const faMatrix<Type>& B
1181 )
1182 {
1183  checkMethod(tA(), B, "+");
1184  tmp<faMatrix<Type>> tC(tA.ptr());
1185  tC.ref() += B;
1186  return tC;
1187 }
1188 
1189 
1190 template<class Type>
1191 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1192 (
1193  const faMatrix<Type>& A,
1194  const tmp<faMatrix<Type>>& tB
1195 )
1196 {
1197  checkMethod(A, tB(), "+");
1198  tmp<faMatrix<Type>> tC(tB.ptr());
1199  tC.ref() += A;
1200  return tC;
1201 }
1202 
1203 
1204 template<class Type>
1205 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1206 (
1207  const tmp<faMatrix<Type>>& tA,
1208  const tmp<faMatrix<Type>>& tB
1209 )
1210 {
1211  checkMethod(tA(), tB(), "+");
1212  tmp<faMatrix<Type>> tC(tA.ptr());
1213  tC.ref() += tB();
1214  tB.clear();
1215  return tC;
1216 }
1217 
1218 
1219 template<class Type>
1220 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1221 (
1222  const faMatrix<Type>& A
1223 )
1224 {
1225  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1226  tC.ref().negate();
1227  return tC;
1228 }
1229 
1230 
1231 template<class Type>
1232 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1233 (
1234  const tmp<faMatrix<Type>>& tA
1235 )
1236 {
1237  tmp<faMatrix<Type>> tC(tA.ptr());
1238  tC.ref().negate();
1239  return tC;
1240 }
1241 
1242 
1243 template<class Type>
1244 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1245 (
1246  const faMatrix<Type>& A,
1247  const faMatrix<Type>& B
1248 )
1249 {
1250  checkMethod(A, B, "-");
1251  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1252  tC.ref() -= B;
1253  return tC;
1254 }
1255 
1256 
1257 template<class Type>
1258 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1259 (
1260  const tmp<faMatrix<Type>>& tA,
1261  const faMatrix<Type>& B
1262 )
1263 {
1264  checkMethod(tA(), B, "-");
1265  tmp<faMatrix<Type>> tC(tA.ptr());
1266  tC.ref() -= B;
1267  return tC;
1268 }
1269 
1270 
1271 template<class Type>
1272 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1273 (
1274  const faMatrix<Type>& A,
1275  const tmp<faMatrix<Type>>& tB
1276 )
1277 {
1278  checkMethod(A, tB(), "-");
1279  tmp<faMatrix<Type>> tC(tB.ptr());
1280  tC.ref() -= A;
1281  tC.ref().negate();
1282  return tC;
1283 }
1284 
1285 
1286 template<class Type>
1287 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1288 (
1289  const tmp<faMatrix<Type>>& tA,
1290  const tmp<faMatrix<Type>>& tB
1291 )
1292 {
1293  checkMethod(tA(), tB(), "-");
1294  tmp<faMatrix<Type>> tC(tA.ptr());
1295  tC.ref() -= tB();
1296  tB.clear();
1297  return tC;
1298 }
1299 
1300 
1301 template<class Type>
1302 Foam::tmp<Foam::faMatrix<Type>> Foam::operator==
1303 (
1304  const faMatrix<Type>& A,
1305  const faMatrix<Type>& B
1306 )
1307 {
1308  checkMethod(A, B, "==");
1309  return (A - B);
1310 }
1311 
1312 
1313 template<class Type>
1314 Foam::tmp<Foam::faMatrix<Type>> Foam::operator==
1315 (
1316  const tmp<faMatrix<Type>>& tA,
1317  const faMatrix<Type>& B
1318 )
1319 {
1320  checkMethod(tA(), B, "==");
1321  return (tA - B);
1322 }
1323 
1324 
1325 template<class Type>
1326 Foam::tmp<Foam::faMatrix<Type>> Foam::operator==
1327 (
1328  const faMatrix<Type>& A,
1329  const tmp<faMatrix<Type>>& tB
1330 )
1331 {
1332  checkMethod(A, tB(), "==");
1333  return (A - tB);
1334 }
1335 
1336 
1337 template<class Type>
1338 Foam::tmp<Foam::faMatrix<Type>> Foam::operator==
1339 (
1340  const tmp<faMatrix<Type>>& tA,
1341  const tmp<faMatrix<Type>>& tB
1342 )
1343 {
1344  checkMethod(tA(), tB(), "==");
1345  return (tA - tB);
1346 }
1347 
1348 
1349 template<class Type>
1350 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1351 (
1352  const faMatrix<Type>& A,
1353  const GeometricField<Type, faPatchField, areaMesh>& su
1354 )
1355 {
1356  checkMethod(A, su, "+");
1357  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1358  tC.ref().source() -= su.mesh().S()*su.internalField();
1359  return tC;
1360 }
1361 
1362 
1363 template<class Type>
1364 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1365 (
1366  const tmp<faMatrix<Type>>& tA,
1367  const GeometricField<Type, faPatchField, areaMesh>& su
1368 )
1369 {
1370  checkMethod(tA(), su, "+");
1371  tmp<faMatrix<Type>> tC(tA.ptr());
1372  tC.ref().source() -= su.mesh().S()*su.internalField();
1373  return tC;
1374 }
1375 
1376 
1377 template<class Type>
1378 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1379 (
1380  const faMatrix<Type>& A,
1381  const tmp<GeometricField<Type, faPatchField, areaMesh>>& tsu
1382 )
1383 {
1384  checkMethod(A, tsu(), "+");
1385  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1386  tC.ref().source() -= tsu().mesh().S()*tsu().internalField();
1387  tsu.clear();
1388  return tC;
1389 }
1390 
1391 
1392 template<class Type>
1393 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1394 (
1395  const tmp<faMatrix<Type>>& tA,
1396  const tmp<GeometricField<Type, faPatchField, areaMesh>>& tsu
1397 )
1398 {
1399  checkMethod(tA(), tsu(), "+");
1400  tmp<faMatrix<Type>> tC(tA.ptr());
1401  tC.ref().source() -= tsu().mesh().S()*tsu().internalField();
1402  tsu.clear();
1403  return tC;
1404 }
1405 
1406 
1407 template<class Type>
1408 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1409 (
1410  const GeometricField<Type, faPatchField, areaMesh>& su,
1411  const faMatrix<Type>& A
1412 )
1413 {
1414  checkMethod(A, su, "+");
1415  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1416  tC.ref().source() -= su.mesh().S()*su.internalField();
1417  return tC;
1418 }
1419 
1420 
1421 template<class Type>
1422 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1423 (
1424  const GeometricField<Type, faPatchField, areaMesh>& su,
1425  const tmp<faMatrix<Type>>& tA
1426 )
1427 {
1428  checkMethod(tA(), su, "+");
1429  tmp<faMatrix<Type>> tC(tA.ptr());
1430  tC.ref().source() -= su.mesh().S()*su.internalField();
1431  return tC;
1432 }
1433 
1434 
1435 template<class Type>
1436 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1437 (
1438  const tmp<GeometricField<Type, faPatchField, areaMesh>>& tsu,
1439  const faMatrix<Type>& A
1440 )
1441 {
1442  checkMethod(A, tsu(), "+");
1443  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1444  tC.ref().source() -= tsu().mesh().S()*tsu().internalField();
1445  tsu.clear();
1446  return tC;
1447 }
1448 
1449 
1450 template<class Type>
1451 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1452 (
1453  const tmp<GeometricField<Type, faPatchField, areaMesh>>& tsu,
1454  const tmp<faMatrix<Type>>& tA
1455 )
1456 {
1457  checkMethod(tA(), tsu(), "+");
1458  tmp<faMatrix<Type>> tC(tA.ptr());
1459  tC.ref().source() -= tsu().mesh().S()*tsu().internalField();
1460  tsu.clear();
1461  return tC;
1462 }
1463 
1464 
1465 template<class Type>
1466 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1467 (
1468  const faMatrix<Type>& A,
1469  const GeometricField<Type, faPatchField, areaMesh>& su
1470 )
1471 {
1472  checkMethod(A, su, "-");
1473  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1474  tC.ref().source() += su.mesh().S()*su.internalField();
1475  return tC;
1476 }
1477 
1478 
1479 template<class Type>
1480 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1481 (
1482  const tmp<faMatrix<Type>>& tA,
1483  const GeometricField<Type, faPatchField, areaMesh>& su
1484 )
1485 {
1486  checkMethod(tA(), su, "-");
1487  tmp<faMatrix<Type>> tC(tA.ptr());
1488  tC.ref().source() += su.mesh().S()*su.internalField();
1489  return tC;
1490 }
1491 
1492 
1493 template<class Type>
1494 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1495 (
1496  const faMatrix<Type>& A,
1497  const tmp<GeometricField<Type, faPatchField, areaMesh>>& tsu
1498 )
1499 {
1500  checkMethod(A, tsu(), "-");
1501  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1502  tC.ref().source() += tsu().mesh().S()*tsu().internalField();
1503  tsu.clear();
1504  return tC;
1505 }
1506 
1507 
1508 template<class Type>
1509 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1510 (
1511  const tmp<faMatrix<Type>>& tA,
1512  const tmp<GeometricField<Type, faPatchField, areaMesh>>& tsu
1513 )
1514 {
1515  checkMethod(tA(), tsu(), "-");
1516  tmp<faMatrix<Type>> tC(tA.ptr());
1517  tC.ref().source() += tsu().mesh().S()*tsu().internalField();
1518  tsu.clear();
1519  return tC;
1520 }
1521 
1522 
1523 template<class Type>
1524 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1525 (
1526  const GeometricField<Type, faPatchField, areaMesh>& su,
1527  const faMatrix<Type>& A
1528 )
1529 {
1530  checkMethod(A, su, "-");
1531  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1532  tC.ref().negate();
1533  tC.ref().source() -= su.mesh().S()*su.internalField();
1534  return tC;
1535 }
1536 
1537 
1538 template<class Type>
1539 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1540 (
1541  const GeometricField<Type, faPatchField, areaMesh>& su,
1542  const tmp<faMatrix<Type>>& tA
1543 )
1544 {
1545  checkMethod(tA(), su, "-");
1546  tmp<faMatrix<Type>> tC(tA.ptr());
1547  tC.ref().negate();
1548  tC.ref().source() -= su.mesh().S()*su.internalField();
1549  return tC;
1550 }
1551 
1552 
1553 template<class Type>
1554 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1555 (
1556  const tmp<GeometricField<Type, faPatchField, areaMesh>>& tsu,
1557  const faMatrix<Type>& A
1558 )
1559 {
1560  checkMethod(A, tsu(), "-");
1561  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1562  tC.ref().negate();
1563  tC.ref().source() -= tsu().mesh().S()*tsu().internalField();
1564  tsu.clear();
1565  return tC;
1566 }
1567 
1568 
1569 template<class Type>
1570 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1571 (
1572  const tmp<GeometricField<Type, faPatchField, areaMesh>>& tsu,
1573  const tmp<faMatrix<Type>>& tA
1574 )
1575 {
1576  checkMethod(tA(), tsu(), "-");
1577  tmp<faMatrix<Type>> tC(tA.ptr());
1578  tC.ref().negate();
1579  tC.ref().source() -= tsu().mesh().S()*tsu().internalField();
1580  tsu.clear();
1581  return tC;
1582 }
1583 
1584 
1585 template<class Type>
1586 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1587 (
1588  const faMatrix<Type>& A,
1589  const dimensioned<Type>& su
1590 )
1591 {
1592  checkMethod(A, su, "+");
1593  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1594  tC.ref().source() -= su.value()*A.psi().mesh().S();
1595  return tC;
1596 }
1597 
1598 
1599 template<class Type>
1600 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1601 (
1602  const tmp<faMatrix<Type>>& tA,
1603  const dimensioned<Type>& su
1604 )
1605 {
1606  checkMethod(tA(), su, "+");
1607  tmp<faMatrix<Type>> tC(tA.ptr());
1608  tC.ref().source() -= su.value()*tC().psi().mesh().S();
1609  return tC;
1610 }
1611 
1612 
1613 template<class Type>
1614 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1615 (
1616  const dimensioned<Type>& su,
1617  const faMatrix<Type>& A
1618 )
1619 {
1620  checkMethod(A, su, "+");
1621  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1622  tC.ref().source() -= su.value()*A.psi().mesh().S();
1623  return tC;
1624 }
1625 
1626 
1627 template<class Type>
1628 Foam::tmp<Foam::faMatrix<Type>> Foam::operator+
1629 (
1630  const dimensioned<Type>& su,
1631  const tmp<faMatrix<Type>>& tA
1632 )
1633 {
1634  checkMethod(tA(), su, "+");
1635  tmp<faMatrix<Type>> tC(tA.ptr());
1636  tC.ref().source() -= su.value()*tC().psi().mesh().S();
1637  return tC;
1638 }
1639 
1640 
1641 template<class Type>
1642 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1643 (
1644  const faMatrix<Type>& A,
1645  const dimensioned<Type>& su
1646 )
1647 {
1648  checkMethod(A, su, "-");
1649  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1650  tC.ref().source() += su.value()*tC().psi().mesh().S();
1651  return tC;
1652 }
1653 
1654 
1655 template<class Type>
1656 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1657 (
1658  const tmp<faMatrix<Type>>& tA,
1659  const dimensioned<Type>& su
1660 )
1661 {
1662  checkMethod(tA(), su, "-");
1663  tmp<faMatrix<Type>> tC(tA.ptr());
1664  tC.ref().source() += su.value()*tC().psi().mesh().S();
1665  return tC;
1666 }
1667 
1668 
1669 template<class Type>
1670 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1671 (
1672  const dimensioned<Type>& su,
1673  const faMatrix<Type>& A
1674 )
1675 {
1676  checkMethod(A, su, "-");
1677  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1678  tC.ref().negate();
1679  tC.ref().source() -= su.value()*A.psi().mesh().S();
1680  return tC;
1681 }
1682 
1683 
1684 template<class Type>
1685 Foam::tmp<Foam::faMatrix<Type>> Foam::operator-
1686 (
1687  const dimensioned<Type>& su,
1688  const tmp<faMatrix<Type>>& tA
1689 )
1690 {
1691  checkMethod(tA(), su, "-");
1692  tmp<faMatrix<Type>> tC(tA.ptr());
1693  tC.ref().negate();
1694  tC.ref().source() -= su.value()*tC().psi().mesh().S();
1695  return tC;
1696 }
1697 
1698 
1699 template<class Type>
1700 Foam::tmp<Foam::faMatrix<Type>> Foam::operator==
1701 (
1702  const faMatrix<Type>& A,
1703  const GeometricField<Type, faPatchField, areaMesh>& su
1704 )
1705 {
1706  checkMethod(A, su, "==");
1707  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1708  tC.ref().source() += su.mesh().S()*su.internalField();
1709  return tC;
1710 }
1711 
1712 
1713 template<class Type>
1714 Foam::tmp<Foam::faMatrix<Type>> Foam::operator==
1715 (
1716  const tmp<faMatrix<Type>>& tA,
1717  const GeometricField<Type, faPatchField, areaMesh>& su
1718 )
1719 {
1720  checkMethod(tA(), su, "==");
1721  tmp<faMatrix<Type>> tC(tA.ptr());
1722  tC.ref().source() += su.mesh().S()*su.internalField();
1723  return tC;
1724 }
1725 
1726 
1727 template<class Type>
1728 Foam::tmp<Foam::faMatrix<Type>> Foam::operator==
1729 (
1730  const faMatrix<Type>& A,
1731  const tmp<GeometricField<Type, faPatchField, areaMesh>>& tsu
1732 )
1733 {
1734  checkMethod(A, tsu(), "==");
1735  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1736  tC.ref().source() += tsu().mesh().S()*tsu().internalField();
1737  tsu.clear();
1738  return tC;
1739 }
1740 
1741 
1742 template<class Type>
1743 Foam::tmp<Foam::faMatrix<Type>> Foam::operator==
1744 (
1745  const tmp<faMatrix<Type>>& tA,
1746  const tmp<GeometricField<Type, faPatchField, areaMesh>>& tsu
1747 )
1748 {
1749  checkMethod(tA(), tsu(), "==");
1750  tmp<faMatrix<Type>> tC(tA.ptr());
1751  tC.ref().source() += tsu().mesh().S()*tsu().internalField();
1752  tsu.clear();
1753  return tC;
1754 }
1755 
1756 
1757 template<class Type>
1758 Foam::tmp<Foam::faMatrix<Type>> Foam::operator==
1759 (
1760  const faMatrix<Type>& A,
1761  const dimensioned<Type>& su
1762 )
1763 {
1764  checkMethod(A, su, "==");
1765  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1766  tC.ref().source() += A.psi().mesh().S()*su.value();
1767  return tC;
1768 }
1769 
1770 
1771 template<class Type>
1772 Foam::tmp<Foam::faMatrix<Type>> Foam::operator==
1773 (
1774  const tmp<faMatrix<Type>>& tA,
1775  const dimensioned<Type>& su
1776 )
1777 {
1778  checkMethod(tA(), su, "==");
1779  tmp<faMatrix<Type>> tC(tA.ptr());
1780  tC.ref().source() += tC().psi().mesh().S()*su.value();
1781  return tC;
1782 }
1783 
1784 
1785 template<class Type>
1786 Foam::tmp<Foam::faMatrix<Type>> Foam::operator*
1787 (
1788  const areaScalarField& vsf,
1789  const faMatrix<Type>& A
1790 )
1791 {
1792  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1793  tC.ref() *= vsf;
1794  return tC;
1795 }
1796 
1797 
1798 template<class Type>
1799 Foam::tmp<Foam::faMatrix<Type>> Foam::operator*
1800 (
1801  const tmp<areaScalarField>& tvsf,
1802  const faMatrix<Type>& A
1803 )
1804 {
1805  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1806  tC.ref() *= tvsf;
1807  return tC;
1808 }
1809 
1810 
1811 template<class Type>
1812 Foam::tmp<Foam::faMatrix<Type>> Foam::operator*
1813 (
1814  const areaScalarField& vsf,
1815  const tmp<faMatrix<Type>>& tA
1816 )
1817 {
1818  tmp<faMatrix<Type>> tC(tA.ptr());
1819  tC.ref() *= vsf;
1820  return tC;
1821 }
1822 
1823 
1824 template<class Type>
1825 Foam::tmp<Foam::faMatrix<Type>> Foam::operator*
1826 (
1827  const tmp<areaScalarField>& tvsf,
1828  const tmp<faMatrix<Type>>& tA
1829 )
1830 {
1831  tmp<faMatrix<Type>> tC(tA.ptr());
1832  tC.ref() *= tvsf;
1833  return tC;
1834 }
1835 
1836 
1837 template<class Type>
1838 Foam::tmp<Foam::faMatrix<Type>> Foam::operator*
1839 (
1840  const dimensioned<scalar>& ds,
1841  const faMatrix<Type>& A
1842 )
1843 {
1844  tmp<faMatrix<Type>> tC(new faMatrix<Type>(A));
1845  tC.ref() *= ds;
1846  return tC;
1847 }
1848 
1849 
1850 template<class Type>
1851 Foam::tmp<Foam::faMatrix<Type>> Foam::operator*
1852 (
1853  const dimensioned<scalar>& ds,
1854  const tmp<faMatrix<Type>>& tA
1855 )
1856 {
1857  tmp<faMatrix<Type>> tC(tA.ptr());
1858  tC.ref() *= ds;
1859  return tC;
1860 }
1861 
1862 
1863 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1864 
1865 template<class Type>
1866 Foam::Ostream& Foam::operator<<(Ostream& os, const faMatrix<Type>& fam)
1867 {
1868  os << static_cast<const lduMatrix&>(fam) << nl
1869  << fam.dimensions_ << nl
1870  << fam.source_ << nl
1871  << fam.internalCoeffs_ << nl
1872  << fam.boundaryCoeffs_ << endl;
1873 
1875 
1876  return os;
1877 }
1878 
1879 
1880 // * * * * * * * * * * * * * * * * Solvers * * * * * * * * * * * * * * * * * //
1881 
1882 #include "faMatrixSolve.C"
1883 
1884 // ************************************************************************* //
Foam::checkMethod
void checkMethod(const faMatrix< Type > &, const faMatrix< Type > &, const char *)
Definition: faMatrix.C:1032
Foam::faMatrix::operator+=
void operator+=(const faMatrix< Type > &)
Definition: faMatrix.C:843
Foam::lduMatrix::operator-=
void operator-=(const lduMatrix &)
Definition: lduMatrixOperations.C:223
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::faMatrix::addToInternalField
void addToInternalField(const labelUList &addr, const Field< Type2 > &pf, Field< Type2 > &intf) const
Add patch contribution to internal field.
Definition: faMatrix.C:42
Foam::faMatrix::dimensions
const dimensionSet & dimensions() const
Definition: faMatrix.H:260
Foam::faPatchField
faPatchField<Type> abstract base class. This class gives a fat-interface to all derived classes cover...
Definition: areaFieldsFwd.H:50
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::faMatrix
A special matrix type and solver, designed for finite area solutions of scalar equations....
Definition: faMatricesFwd.H:43
UIndirectList.H
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:287
Foam::faMatrix::negate
void negate()
Definition: faMatrix.C:828
Foam::cmptMultiply
dimensioned< Type > cmptMultiply(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::faMatrix::setValues
void setValues(const labelUList &faceLabels, const Type &value)
Definition: faMatrix.C:422
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::lduMatrix::operator+=
void operator+=(const lduMatrix &)
Definition: lduMatrixOperations.C:144
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::faMatrix::operator-=
void operator-=(const faMatrix< Type > &)
Definition: faMatrix.C:877
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
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::constant::atomic::alpha
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
Definition: readThermalProperties.H:212
Foam::lduMatrix
lduMatrix is a general matrix class in which the coefficients are stored as three arrays,...
Definition: lduMatrix.H:83
B
static const Foam::dimensionedScalar B("", Foam::dimless, 18.678)
Foam::dimensioned::name
const word & name() const
Return const reference to name.
Definition: dimensionedType.C:406
A
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::faMatrix::flux
tmp< GeometricField< Type, faePatchField, edgeMesh > > flux() const
Return the face-flux field from the matrix.
Definition: faMatrix.C:705
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::faMatrix::faMatrix
faMatrix(const GeometricField< Type, faPatchField, areaMesh > &psi, const dimensionSet &ds)
Construct given a field to solve for.
Definition: faMatrix.C:185
Foam::dimensionSet
Dimension set for the base types, which can be used to implement rigorous dimension checking for alge...
Definition: dimensionSet.H:108
primitiveFieldRef
conserve primitiveFieldRef()+
Foam::faMatrix::subtractFromInternalField
void subtractFromInternalField(const labelUList &addr, const Field< Type2 > &pf, Field< Type2 > &intf) const
Subtract patch contribution from internal field.
Definition: faMatrix.C:80
Foam::GeometricField::Boundary::updateCoeffs
void updateCoeffs()
Update the boundary condition coefficients.
Definition: GeometricBoundaryField.C:395
faMatrixSolve.C
Finite-Area matrix basic solvers.
Foam::faMatrix::setReferences
void setReferences(const labelUList &faceLabels, const Type &value, const bool forceReference=false)
Set reference level for solution.
Definition: faMatrix.C:474
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::UniformList< Type >
Foam::cmptMin
void cmptMin(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:302
Foam::cmptMag
void cmptMag(FieldField< Field, Type > &cf, const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:400
Foam::deleteDemandDrivenData
void deleteDemandDrivenData(DataPtr &dataPtr)
Definition: demandDrivenData.H:42
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
Foam::faMatrix::addBoundaryDiag
void addBoundaryDiag(scalarField &diag, const direction cmpt) const
Definition: faMatrix.C:117
Foam::faMatrix::operator=
void operator=(const faMatrix< Type > &)
Definition: faMatrix.C:787
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:227
Foam::faPatchField::coupled
virtual bool coupled() const
Return true if this patch field is coupled.
Definition: faPatchField.H:320
Foam::stringOps::lower
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
Definition: stringOps.C:1184
Foam::dimArea
const dimensionSet dimArea(sqr(dimLength))
Definition: dimensionSets.H:59
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:388
edgeFields.H
calculatedFaPatchFields.H
faceId
label faceId(-1)
Foam::primitiveMesh::faceEdges
const labelListList & faceEdges() const
Definition: primitiveMeshEdges.C:528
Foam::cmptAv
tmp< DimensionedField< typename DimensionedField< Type, GeoMesh >::cmptType, GeoMesh >> cmptAv(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:246
Foam::faMatrix::setValuesFromList
void setValuesFromList(const labelUList &faceLabels, const ListType< Type > &values)
Set solution in given faces to the specified values.
Definition: faMatrix.C:333
Foam::solve
SolverPerformance< Type > solve(faMatrix< Type > &, Istream &)
Solve returning the solution statistics given convergence tolerance.
Foam::faMatrix::addBoundarySource
void addBoundarySource(Field< Type > &source, const bool couples=true) const
Definition: faMatrix.C:151
Foam::faMatrix::relax
void relax()
Relax matrix (for steady-state solution).
Definition: faMatrix.C:609
UniformList.H
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
areaFields.H
Foam::IOstream::check
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:58
Foam::FatalError
error FatalError
Foam::fvMesh::neighbour
const labelUList & neighbour() const
Internal face neighbour.
Definition: fvMesh.H:413
Foam::faMatrix::H
tmp< GeometricField< Type, faPatchField, areaMesh > > H() const
Return the H operation source.
Definition: faMatrix.C:661
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::dimensioned
Generic dimensioned Type class.
Definition: dimensionedScalarFwd.H:42
Foam::lduMatrix::negate
void negate()
Definition: lduMatrixOperations.C:125
Foam::tmp::ptr
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition: tmpI.H:255
Foam::areaScalarField
GeometricField< scalar, faPatchField, areaMesh > areaScalarField
Definition: areaFieldsFwd.H:53
Foam::lduMatrix::H
tmp< Field< Type > > H(const Field< Type > &) const
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::fvMesh::owner
const labelUList & owner() const
Internal face owner. Note bypassing virtual mechanism so.
Definition: fvMesh.H:407
Foam::faMatrix::setReference
void setReference(const label facei, const Type &value, const bool forceReference=false)
Set reference level for solution.
Definition: faMatrix.C:455
Foam::GeometricField::primitiveFieldRef
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field.
Definition: GeometricField.C:766
zeroGradientFaPatchFields.H
Foam::GeometricField::correctBoundaryConditions
void correctBoundaryConditions()
Correct boundary field.
Definition: GeometricField.C:940
Foam::faPatchField::patchNeighbourField
virtual tmp< Field< Type > > patchNeighbourField() const
Return patchField on the opposite patch of a coupled patch.
Definition: faPatchField.H:364
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
Foam::fvMesh::boundary
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:685
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::lduMatrix::operator=
void operator=(const lduMatrix &)
Definition: lduMatrixOperations.C:91
Foam::faMatrix::psi
const GeometricField< Type, faPatchField, areaMesh > & psi() const
Definition: faMatrix.H:255
Foam::GeometricField::boundaryFieldRef
Boundary & boundaryFieldRef(const bool updateAccessTime=true)
Return a reference to the boundary field.
Definition: GeometricField.C:783
Foam::List< labelList >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::lduMatrix::operator*=
void operator*=(const scalarField &)
Definition: lduMatrixOperations.C:302
Foam::faMatrix::addCmptAvBoundaryDiag
void addCmptAvBoundaryDiag(scalarField &diag) const
Definition: faMatrix.C:135
Foam::lduMatrix::faceH
tmp< Field< Type > > faceH(const Field< Type > &) const
Foam::UList< label >
D
const dimensionedScalar & D
Definition: solveBulkSurfactant.H:4
Foam::direction
uint8_t direction
Definition: direction.H:52
Foam::faMatrix::~faMatrix
virtual ~faMatrix()
Destructor.
Definition: faMatrix.C:319
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::faMesh
Finite area mesh. Used for 2-D non-Euclidian finite area method.
Definition: faMesh.H:82
Foam::UIndirectList
A List with indirect addressing.
Definition: faMatrix.H:60
Foam::faMatrix::D
tmp< scalarField > D() const
Return the matrix diagonal.
Definition: faMatrix.C:625
Foam::faMatrix::A
tmp< areaScalarField > A() const
Return the central coefficient.
Definition: faMatrix.C:634
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
fam
Calculate the matrix for the second temporal derivative.
Foam::stringOps::upper
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
Definition: stringOps.C:1200
Foam::faMatrix::clone
tmp< faMatrix< Type > > clone() const
Clone.
Definition: faMatrix.C:309
Foam::dimensioned::dimensions
const dimensionSet & dimensions() const
Return const reference to dimensions.
Definition: dimensionedType.C:420
Foam::GeometricField
Generic GeometricField class.
Definition: areaFieldsFwd.H:53
psi
const volScalarField & psi
Definition: createFieldRefs.H:1
Foam::SolverPerformance
SolverPerformance is the class returned by the LduMatrix solver containing performance statistics.
Definition: SolverPerformance.H:52
Foam::dimensionSet::checking
static bool checking() noexcept
True if dimension checking is enabled (the usual default)
Definition: dimensionSet.H:229
Foam::GeometricField::boundaryField
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Definition: GeometricFieldI.H:62
relax
UEqn relax()