fvcSurfaceOps.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) 2024 M.Janssens
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "fvcSurfaceOps.H"
29 #include "fvMesh.H"
31 // #include "emptyFvPatchField.H"
32 
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 
40 namespace fvc
41 {
42 
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 
45 template<class Type, class ResultType, class CellToFaceOp>
46 void surfaceSum
47 (
48  const surfaceScalarField& lambdas,
50  const CellToFaceOp& cop,
53 )
54 {
55  const fvMesh& mesh = vf.mesh();
56  const auto& Sf = mesh.Sf();
57  const auto& P = mesh.owner();
58  const auto& N = mesh.neighbour();
59  const auto& pbm = mesh.boundaryMesh();
60 
61  const auto& vfi = vf.primitiveField();
62  auto& sfi = result.primitiveFieldRef();
63 
64  // See e.g. surfaceInterpolationScheme<Type>::dotInterpolate
65 
66  // Fetch patchNeighbourField or value onto end of vf
67  bitSet isCoupled(vf.boundaryField().size());
68 
69  const label oldSize = vf.constCast().boundaryEvaluate
70  (
71  [&](const auto& pfld, UList<Type>& slice)
72  {
73  if (pfld.coupled())
74  {
75  pfld.patchNeighbourField(slice);
76  isCoupled.set(pfld.patch().index());
77  }
78  // else if (isA<emptyFvPatchField<Type>>(pfld))
79  // {
80  // // Needed for cell-based loop approach, but not for
81  // // face-based loop approach
82  // slice = Zero;
83  // }
84  else
85  {
86  SubList<Type>(slice, pfld.size()) = pfld;
87  }
88  }
89  );
90 
91  // Internal field
92  const auto& Sfi = Sf.primitiveField();
93  const auto& lambda = lambdas.primitiveField();
94 
95  #if 0
96  {
97  //- Example of cell-loop instead of face-loop
98  const auto& cells = mesh.cells();
99  const label nCells = mesh.nCells();
100  const label nIntFaces = mesh.nInternalFaces();
101  const auto& patchID = pbm.patchID();
102  for (label celli = 0; celli < nCells; celli++)
103  {
104  const auto& cFaces = cells[celli];
105  auto& res = sfi[celli];
106  res = Zero;
107  for (const label facei : cFaces)
108  {
109  if (facei < nIntFaces)
110  {
111  ResultType faceVal
112  (
113  cop
114  (
115  Sfi[facei],
116  lambda[facei],
117  vfi[P[facei]],
118  vfi[N[facei]]
119  )
120  );
121  if (P[facei] != celli)
122  {
123  faceVal = -faceVal;
124  }
125  sfi[celli] += faceVal;
126  }
127  else
128  {
129  const label patchi = patchID[facei-nIntFaces];
130  const label patchFacei = facei-pbm[patchi].start();
131  const label offset = nCells+pbm[patchi].offset();
132  const auto& pSf = Sf.boundaryField()[patchi];
133  const auto& pLambda = lambdas.boundaryField()[patchi];
134 
135  if (isCoupled(patchi))
136  {
137  // Interpolate between owner-side and neighbour-side values
138  const ResultType faceVal
139  (
140  cop
141  (
142  pSf[patchFacei],
143  pLambda[patchFacei],
144  vfi[celli],
145  vfi[offset+patchFacei]
146  )
147  );
148  sfi[celli] += faceVal;
149  }
150  else if (pSf.size())
151  {
152  // Use patch value only
153  const ResultType faceVal
154  (
155  cop
156  (
157  pSf[patchFacei],
158  scalar(1.0),
159  vfi[offset+patchFacei],
160  pTraits<Type>::zero // not used
161  )
162  );
163  sfi[celli] += faceVal;
164  }
165  }
166  }
167  }
168  }
169  #else
170  {
171  for (label facei=0; facei<P.size(); facei++)
172  {
173  const label ownCelli = P[facei];
174  const label neiCelli = N[facei];
175 
176  const ResultType faceVal
177  (
178  cop
179  (
180  Sfi[facei],
181  lambda[facei],
182  vfi[ownCelli],
183  vfi[neiCelli]
184  )
185  );
186  sfi[ownCelli] += faceVal;
187  sfi[neiCelli] -= faceVal;
188  }
189 
190  // Boundary field
191  forAll(mesh.boundary(), patchi)
192  {
193  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
194  const label offset = mesh.nCells()+pbm[patchi].offset();
195  const auto& pSf = Sf.boundaryField()[patchi];
196  const auto& pLambda = lambdas.boundaryField()[patchi];
197 
198  if (isCoupled(patchi))
199  {
200  //auto tpnf(pvf.patchNeighbourField());
201  //auto& pnf = tpnf();
202 
203  for (label facei=0; facei<pFaceCells.size(); facei++)
204  {
205  // Interpolate between owner-side and neighbour-side values
206  const ResultType faceVal
207  (
208  cop
209  (
210  pSf[facei],
211  pLambda[facei],
212  vfi[pFaceCells[facei]],
213  //pnf[facei]
214  vfi[offset+facei]
215  )
216  );
217  sfi[pFaceCells[facei]] += faceVal;
218  }
219  }
220  else
221  {
222  for (label facei=0; facei<pFaceCells.size(); facei++)
223  {
224  // Use patch value only
225  const ResultType faceVal
226  (
227  cop
228  (
229  pSf[facei],
230  scalar(1.0),
231  vfi[offset+facei],
232  pTraits<Type>::zero // not used
233  )
234  );
235  sfi[pFaceCells[facei]] += faceVal;
236  }
237  }
238  }
239  }
240  #endif
241 
242  // Restore original size
243  vf.constCast().resize(oldSize);
244 
246  {
247  result.correctBoundaryConditions();
248  }
249 }
250 
251 
252 template<class Type, class FType, class ResultType, class CellToFaceOp>
253 void surfaceSum
254 (
255  const surfaceScalarField& lambdas,
258  const CellToFaceOp& cop,
260  const bool doCorrectBoundaryConditions
261 )
262 {
263  const fvMesh& mesh = vf.mesh();
264  const auto& Sf = mesh.Sf();
265  const auto& P = mesh.owner();
266  const auto& N = mesh.neighbour();
267 
268  const auto& vfi = vf.primitiveField();
269  auto& sfi = result.primitiveFieldRef();
270 
271  // See e.g. surfaceInterpolationScheme<Type>::dotInterpolate
272 
273  // Internal field
274  {
275  const auto& Sfi = Sf.primitiveField();
276  const auto& lambda = lambdas.primitiveField();
277  const auto& saddi = sadd.primitiveField();
278 
279  for (label facei=0; facei<P.size(); facei++)
280  {
281  const label ownCelli = P[facei];
282  const label neiCelli = N[facei];
283 
284  const ResultType faceVal
285  (
286  cop
287  (
288  Sfi[facei],
289  lambda[facei],
290  vfi[ownCelli],
291  vfi[neiCelli],
292 
293  saddi[facei] // additional face value
294  )
295  );
296  sfi[ownCelli] += faceVal;
297  sfi[neiCelli] -= faceVal;
298  }
299  }
300 
301 
302  // Boundary field
303  {
304  // Fetch patchNeighbourField onto end of GeoField
305  const label oldSize = vf.constCast().boundaryEvaluate
306  (
307  [](const auto& pfld, UList<Type>& slice)
308  {
309  if (pfld.coupled())
310  {
311  pfld.patchNeighbourField(slice);
312  }
313  }
314  );
315 
316  forAll(mesh.boundary(), patchi)
317  {
318  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
319  const auto& pSf = Sf.boundaryField()[patchi];
320  const auto& pvf = vf.boundaryField()[patchi];
321  const auto& pLambda = lambdas.boundaryField()[patchi];
322  const auto& psadd = sadd.boundaryField()[patchi];
323 
324  if (pvf.coupled())
325  {
326  //auto tpnf(pvf.patchNeighbourField());
327  //auto& pnf = tpnf();
328 
329  const label offset = mesh.nCells()+pvf.patch().offset();
330 
331  for (label facei=0; facei<pFaceCells.size(); facei++)
332  {
333  // Interpolate between owner-side and neighbour-side values
334  const ResultType faceVal
335  (
336  cop
337  (
338  pSf[facei],
339  pLambda[facei],
340  vfi[pFaceCells[facei]],
341  //pnf[facei],
342  vfi[offset+facei],
343  psadd[facei]
344  )
345  );
346  sfi[pFaceCells[facei]] += faceVal;
347  }
348  }
349  else
350  {
351  for (label facei=0; facei<pFaceCells.size(); facei++)
352  {
353  // Use patch value only
354  const ResultType faceVal
355  (
356  cop
357  (
358  pSf[facei],
359  scalar(1.0),
360  pvf[facei],
361  pTraits<Type>::zero, // not used
362 
363  psadd[facei]
364  )
365  );
366  sfi[pFaceCells[facei]] += faceVal;
367  }
368  }
369  }
370 
371  // Restore original size
372  vf.constCast().resize(oldSize);
373  }
374 
376  {
377  result.correctBoundaryConditions();
378  }
379 }
380 
381 
382 template
383 <
384  class Type,
385  class FType0,
386  class FType1,
387  class ResultType,
388  class CellToFaceOp
389 >
390 void surfaceSum
391 (
392  const surfaceScalarField& lambdas,
394 
397 
398  const CellToFaceOp& cop,
400  const bool doCorrectBoundaryConditions
401 )
402 {
403  const fvMesh& mesh = vf.mesh();
404  const auto& Sf = mesh.Sf();
405  const auto& P = mesh.owner();
406  const auto& N = mesh.neighbour();
407 
408  const auto& vfi = vf.primitiveField();
409  auto& resulti = result.primitiveFieldRef();
410 
411  // See e.g. surfaceInterpolationScheme<Type>::dotInterpolate
412 
413  // Internal field
414  {
415  const auto& Sfi = Sf.primitiveField();
416  const auto& lambda = lambdas.primitiveField();
417  const auto& sf0i = sf0.primitiveField();
418  const auto& sf1i = sf1.primitiveField();
419 
420  for (label facei=0; facei<P.size(); facei++)
421  {
422  const label ownCelli = P[facei];
423  const label neiCelli = N[facei];
424 
425  const ResultType faceVal
426  (
427  cop
428  (
429  Sfi[facei],
430 
431  lambda[facei],
432  vfi[ownCelli],
433  vfi[neiCelli],
434 
435  sf0i[facei], // additional face value
436  sf1i[facei] // additional face value
437  )
438  );
439  resulti[ownCelli] += faceVal;
440  resulti[neiCelli] -= faceVal;
441  }
442  }
443 
444 
445  // Boundary field
446  {
447  // Fetch patchNeighbourField onto end of GeoField
448  const label oldSize = vf.constCast().boundaryEvaluate
449  (
450  [](const auto& pfld, UList<Type>& slice)
451  {
452  if (pfld.coupled())
453  {
454  pfld.patchNeighbourField(slice);
455  }
456  }
457  );
458 
459  forAll(mesh.boundary(), patchi)
460  {
461  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
462  const auto& pSf = Sf.boundaryField()[patchi];
463  const auto& pvf = vf.boundaryField()[patchi];
464  const auto& pLambda = lambdas.boundaryField()[patchi];
465  const auto& psf0 = sf0.boundaryField()[patchi];
466  const auto& psf1 = sf1.boundaryField()[patchi];
467 
468  if (pvf.coupled())
469  {
470  //auto tpnf(pvf.patchNeighbourField());
471  //auto& pnf = tpnf();
472 
473  const label offset = mesh.nCells()+pvf.patch().offset();
474 
475  for (label facei=0; facei<pFaceCells.size(); facei++)
476  {
477  // Interpolate between owner-side and neighbour-side values
478  const ResultType faceVal
479  (
480  cop
481  (
482  pSf[facei],
483 
484  pLambda[facei],
485  vfi[pFaceCells[facei]],
486  //pnf[facei],
487  vfi[offset+facei],
488 
489  psf0[facei],
490  psf1[facei]
491  )
492  );
493 
494  resulti[pFaceCells[facei]] += faceVal;
495  }
496  }
497  else
498  {
499  for (label facei=0; facei<pFaceCells.size(); facei++)
500  {
501  // Use patch value only
502  const ResultType faceVal
503  (
504  cop
505  (
506  pSf[facei],
507  scalar(1.0),
508  pvf[facei],
509  pTraits<Type>::zero, // not used
510 
511  psf0[facei],
512  psf1[facei]
513  )
514  );
515 
516  resulti[pFaceCells[facei]] += faceVal;
517  }
518  }
519  }
520 
521  // Restore original size
522  vf.constCast().resize(oldSize);
523  }
524 
526  {
527  result.correctBoundaryConditions();
528  }
529 }
530 
531 
532 template<class Type, class ResultType, class CombineOp>
533 void GaussOp
534 (
535  const surfaceScalarField& lambdas,
537  const CombineOp& cop,
539 )
540 {
541  const fvMesh& mesh = vf.mesh();
542 
543  // Sum contributions
544  surfaceSum(lambdas, vf, cop, result, false);
545 
546  auto& sfi = result.primitiveFieldRef();
547  sfi /= mesh.V();
548 
549  result.correctBoundaryConditions();
550 }
551 
552 
553 template<class Type, class ResultType, class CombineOp>
554 void surfaceOp
555 (
557  const surfaceVectorField& ownLs,
558  const surfaceVectorField& neiLs,
559  const CombineOp& cop,
561 )
562 {
563  const fvMesh& mesh = vf.mesh();
564  const auto& Sf = mesh.Sf();
565  const auto& P = mesh.owner();
566  const auto& N = mesh.neighbour();
567 
568  const auto& vfi = vf.primitiveField();
569  auto& sfi = result.primitiveFieldRef();
570 
571  // Internal field
572  {
573  const auto& Sfi = Sf.primitiveField();
574 
575  for (label facei=0; facei<P.size(); facei++)
576  {
577  const label ownCelli = P[facei];
578  const label neiCelli = N[facei];
579 
580  const Type faceVal
581  (
582  cop
583  (
584  Sfi[facei], // needed?
585  vfi[ownCelli],
586  vfi[neiCelli]
587  )
588  );
589  sfi[ownCelli] += ownLs[facei]*faceVal;
590  sfi[neiCelli] -= neiLs[facei]*faceVal;
591  }
592  }
593 
594 
595  // Boundary field
596  {
597  // Fetch patchNeighbourField onto end of GeoField
598  const label oldSize = vf.constCast().boundaryEvaluate
599  (
600  [](const auto& pfld, UList<Type>& slice)
601  {
602  if (pfld.coupled())
603  {
604  pfld.patchNeighbourField(slice);
605  }
606  }
607  );
608 
609  forAll(mesh.boundary(), patchi)
610  {
611  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
612  const auto& pSf = Sf.boundaryField()[patchi];
613  const auto& pvf = vf.boundaryField()[patchi];
614  const auto& pOwnLs = ownLs.boundaryField()[patchi];
615 
616  if (pvf.coupled())
617  {
618  //auto tpnf(pvf.patchNeighbourField());
619  //auto& pnf = tpnf();
620 
621  const label offset = mesh.nCells()+pvf.patch().offset();
622 
623  for (label facei=0; facei<pFaceCells.size(); facei++)
624  {
625  const Type faceVal
626  (
627  cop
628  (
629  pSf[facei], // needed?
630  vfi[pFaceCells[facei]],
631  //pnf[facei]
632  vfi[offset+facei]
633  )
634  );
635  sfi[pFaceCells[facei]] += pOwnLs[facei]*faceVal;
636  }
637  }
638  else
639  {
640  for (label facei=0; facei<pFaceCells.size(); facei++)
641  {
642  const Type faceVal
643  (
644  cop
645  (
646  pSf[facei],
647  vfi[pFaceCells[facei]],
648  pvf[facei]
649  )
650  );
651  sfi[pFaceCells[facei]] += pOwnLs[facei]*faceVal;
652  }
653  }
654  }
655 
656  // Restore original size
657  vf.constCast().resize(oldSize);
658  }
659 
660  result.correctBoundaryConditions();
661 }
662 
663 
664 template<class Type, class ResultType, class CellToFaceOp>
665 void surfaceSnSum
666 (
667  const surfaceScalarField& deltaCoeffs,
669 
670  const CellToFaceOp& cop,
671 
673  const bool doCorrectBoundaryConditions
674 )
675 {
676  const fvMesh& mesh = vf.mesh();
677  const auto& Sf = mesh.Sf();
678  const auto& P = mesh.owner();
679  const auto& N = mesh.neighbour();
680 
681  const auto& vfi = vf.primitiveField();
682  auto& sfi = result.primitiveFieldRef();
683 
684  // Internal field
685  {
686  const auto& Sfi = Sf.primitiveField();
687  const auto& dc = deltaCoeffs.primitiveField();
688 
689  for (label facei=0; facei<P.size(); facei++)
690  {
691  const label ownCelli = P[facei];
692  const label neiCelli = N[facei];
693 
694  const ResultType faceVal
695  (
696  cop
697  (
698  Sfi[facei], // area vector
699  dc[facei], // delta coefficients
700  vfi[ownCelli],
701  vfi[neiCelli]
702  )
703  );
704  sfi[ownCelli] += faceVal;
705  sfi[neiCelli] -= faceVal;
706  }
707  }
708 
709 
710  // Boundary field
711  {
712  const label oldSize = vf.constCast().boundaryEvaluate
713  (
714  [](const auto& pfld, UList<Type>& slice)
715  {
716  if (pfld.coupled())
717  {
718  pfld.patchNeighbourField(slice);
719  }
720  // else if (isA<emptyFvPatchField<Type>>(pfld))
721  // {
722  // slice = Zero;
723  // }
724  else
725  {
726  pfld.snGrad(slice);
727  }
728  }
729  );
730 
731  forAll(mesh.boundary(), patchi)
732  {
733  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
734  const auto& pSf = Sf.boundaryField()[patchi];
735  const auto& pvf = vf.boundaryField()[patchi];
736  const auto& pdc = deltaCoeffs.boundaryField()[patchi];
737 
738  const label offset = mesh.nCells()+pvf.patch().offset();
739 
740  if (pvf.coupled())
741  {
742  //auto tpnf(pvf.patchNeighbourField());
743  //auto& pnf = tpnf();
744 
745  for (label facei=0; facei<pFaceCells.size(); facei++)
746  {
747  const label ownCelli = pFaceCells[facei];
748 
749  // Interpolate between owner-side and neighbour-side values
750  const ResultType faceVal
751  (
752  cop
753  (
754  pSf[facei], // area vector
755  pdc[facei],
756  vfi[ownCelli],
757  //pnf[facei]
758  vfi[offset+facei]
759  )
760  );
761  sfi[ownCelli] += faceVal;
762  }
763  }
764  else
765  {
766  //auto tpnf(pvf.snGrad());
767  //auto& pnf = tpnf();
768 
769  for (label facei=0; facei<pFaceCells.size(); facei++)
770  {
771  const label ownCelli = pFaceCells[facei];
772 
773  // Use patch value only
774  const ResultType faceVal
775  (
776  cop
777  (
778  pSf[facei], // area vector
779  scalar(1.0), // use 100% of pnf
780  pTraits<Type>::zero,
781  //pnf[facei]
782  vfi[offset+facei]
783  )
784  );
785  sfi[ownCelli] += faceVal;
786  }
787  }
788  }
789 
790  // Restore original size
791  vf.constCast().resize(oldSize);
792  }
793 
795  {
796  result.correctBoundaryConditions();
797  }
798 }
799 
800 
801 template<class Type, class ResultType, class CellToFaceOp>
802 void surfaceSnSum
803 (
804  const surfaceScalarField& deltaCoeffs,
807 
808  const CellToFaceOp& cop,
809 
811  const bool doCorrectBoundaryConditions
812 )
813 {
814  const fvMesh& mesh = vf.mesh();
815  const auto& Sf = mesh.Sf();
816  const auto& P = mesh.owner();
817  const auto& N = mesh.neighbour();
818 
819  const auto& vfi = vf.primitiveField();
820  auto& sfi = result.primitiveFieldRef();
821 
822  // Internal field
823  {
824  const auto& Sfi = Sf.primitiveField();
825  const auto& dc = deltaCoeffs.primitiveField();
826  const auto& saddi = sadd.primitiveField();
827 
828  for (label facei=0; facei<P.size(); facei++)
829  {
830  const label ownCelli = P[facei];
831  const label neiCelli = N[facei];
832 
833  const ResultType faceVal
834  (
835  cop
836  (
837  Sfi[facei], // area vector
838  dc[facei], // delta coefficients
839  vfi[ownCelli],
840  vfi[neiCelli],
841  saddi[facei] // face addition value
842  )
843  );
844  sfi[ownCelli] += faceVal;
845  sfi[neiCelli] -= faceVal;
846  }
847  }
848 
849 
850  // Boundary field
851  {
852  // Fetch patchNeighbourField onto end of GeoField
853  const label oldSize = vf.constCast().boundaryEvaluate
854  (
855  [](const auto& pfld, UList<Type>& slice)
856  {
857  if (pfld.coupled())
858  {
859  pfld.patchNeighbourField(slice);
860  }
861  // else if (isA<emptyFvPatchField<Type>>(pfld))
862  // {
863  // slice = Zero;
864  // }
865  else
866  {
867  pfld.snGrad(slice);
868  }
869  }
870  );
871 
872  forAll(mesh.boundary(), patchi)
873  {
874  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
875  const auto& pSf = Sf.boundaryField()[patchi];
876  const auto& pvf = vf.boundaryField()[patchi];
877  const auto& pdc = deltaCoeffs.boundaryField()[patchi];
878  const auto& psadd = sadd.boundaryField()[patchi];
879 
880  const label offset = mesh.nCells()+pvf.patch().offset();
881 
882  if (pvf.coupled())
883  {
884  //auto tpnf(pvf.patchNeighbourField());
885  //auto& pnf = tpnf();
886 
887  for (label facei=0; facei<pFaceCells.size(); facei++)
888  {
889  const label ownCelli = pFaceCells[facei];
890 
891  // Interpolate between owner-side and neighbour-side values
892  const ResultType faceVal
893  (
894  cop
895  (
896  pSf[facei], // area vector
897  pdc[facei],
898  vfi[ownCelli],
899  //pnf[facei],
900  vfi[offset+facei],
901  psadd[facei]
902  )
903  );
904  sfi[ownCelli] += faceVal;
905  }
906  }
907  else
908  {
909  //auto tpnf(pvf.snGrad());
910  //auto& pnf = tpnf();
911 
912  for (label facei=0; facei<pFaceCells.size(); facei++)
913  {
914  const label ownCelli = pFaceCells[facei];
915 
916  // Use patch value only
917  const ResultType faceVal
918  (
919  cop
920  (
921  pSf[facei], // area vector
922  scalar(1.0), // use 100% of pnf
923  pTraits<Type>::zero,
924  //pnf[facei],
925  vfi[offset+facei],
926  psadd[facei]
927  )
928  );
929  sfi[ownCelli] += faceVal;
930  }
931  }
932  }
933 
934  // Restore original size
935  vf.constCast().resize(oldSize);
936  }
937 
939  {
940  result.correctBoundaryConditions();
941  }
942 }
943 
944 
945 template<class Type, class GType, class ResultType, class CellToFaceOp>
946 void surfaceSnSum
947 (
948  const surfaceScalarField& gammaWeights,
950 
951  const surfaceScalarField& deltaCoeffs,
953 
954  const CellToFaceOp& cop,
955 
957  const bool doCorrectBoundaryConditions
958 )
959 {
960  const fvMesh& mesh = vf.mesh();
961  const auto& Sf = mesh.Sf();
962  const auto& P = mesh.owner();
963  const auto& N = mesh.neighbour();
964 
965  const auto& gammai = gamma.primitiveField();
966  const auto& vfi = vf.primitiveField();
967  auto& sfi = result.primitiveFieldRef();
968 
969  // Internal field
970  {
971  const auto& Sfi = Sf.primitiveField();
972  const auto& weights = gammaWeights.primitiveField();
973  const auto& dc = deltaCoeffs.primitiveField();
974 
975  for (label facei=0; facei<P.size(); facei++)
976  {
977  const label ownCelli = P[facei];
978  const label neiCelli = N[facei];
979 
980  const ResultType faceVal
981  (
982  cop
983  (
984  Sfi[facei], // area vector
985 
986  weights[facei], // interpolation weights
987  gammai[ownCelli],
988  gammai[neiCelli],
989 
990  dc[facei], // delta coefficients
991  vfi[ownCelli],
992  vfi[neiCelli]
993  )
994  );
995  sfi[ownCelli] += faceVal;
996  sfi[neiCelli] -= faceVal;
997  }
998  }
999 
1000 
1001  // Boundary field
1002  {
1003  // Fetch patchNeighbourField onto end of GeoField
1004  const label oldSize = vf.constCast().boundaryEvaluate
1005  (
1006  [](const auto& pfld, UList<Type>& slice)
1007  {
1008  if (pfld.coupled())
1009  {
1010  pfld.patchNeighbourField(slice);
1011  }
1012  // else if (isA<emptyFvPatchField<Type>>(pfld))
1013  // {
1014  // slice = Zero;
1015  // }
1016  else
1017  {
1018  pfld.snGrad(slice);
1019  }
1020  }
1021  );
1022 
1023  (void) gamma.constCast().boundaryEvaluate
1024  (
1025  [](const auto& pfld, UList<GType>& slice)
1026  {
1027  if (pfld.coupled())
1028  {
1029  pfld.patchNeighbourField(slice);
1030  }
1031  }
1032  );
1033 
1034  forAll(mesh.boundary(), patchi)
1035  {
1036  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
1037  const auto& pSf = Sf.boundaryField()[patchi];
1038  const auto& pvf = vf.boundaryField()[patchi];
1039  const auto& pdc = deltaCoeffs.boundaryField()[patchi];
1040  const auto& pweights = gammaWeights.boundaryField()[patchi];
1041  const auto& pgamma = gamma.boundaryField()[patchi];
1042 
1043  const label offset = mesh.nCells()+pvf.patch().offset();
1044 
1045  if (pvf.coupled())
1046  {
1047  //auto tpnf(pvf.patchNeighbourField());
1048  //auto& pnf = tpnf();
1049  //auto tgammanf(pgamma.patchNeighbourField());
1050  //auto& gammanf = tgammanf();
1051 
1052  for (label facei=0; facei<pFaceCells.size(); facei++)
1053  {
1054  const label ownCelli = pFaceCells[facei];
1055 
1056  // Interpolate between owner-side and neighbour-side values
1057  const ResultType faceVal
1058  (
1059  cop
1060  (
1061  pSf[facei], // area vector
1062 
1063  pweights[facei],
1064  gammai[ownCelli],
1065  //gammanf[facei],
1066  gammai[offset+facei],
1067 
1068  pdc[facei],
1069  vfi[ownCelli],
1070  //pnf[facei]
1071  vfi[offset+facei]
1072  )
1073  );
1074  sfi[ownCelli] += faceVal;
1075  }
1076  }
1077  else
1078  {
1079  //auto tpnf(pvf.snGrad());
1080  //auto& pnf = tpnf();
1081 
1082  for (label facei=0; facei<pFaceCells.size(); facei++)
1083  {
1084  const label ownCelli = pFaceCells[facei];
1085 
1086  // Use patch value only
1087  const ResultType faceVal
1088  (
1089  cop
1090  (
1091  pSf[facei], // area vector
1092 
1093  scalar(1.0),
1094  pgamma[facei],
1095  pTraits<GType>::zero, // not used
1096 
1097 
1098  scalar(1.0), // use 100% of pnf
1099  pTraits<Type>::zero,
1100  //pnf[facei]
1101  vfi[offset+facei]
1102  )
1103  );
1104  sfi[ownCelli] += faceVal;
1105  }
1106  }
1107  }
1108 
1109  // Restore original size
1110  vf.constCast().resize(oldSize);
1111  gamma.constCast().resize(oldSize);
1112  }
1113 
1115  {
1116  result.correctBoundaryConditions();
1117  }
1119 
1120 
1121 template<class Type, class GType, class ResultType, class CellToFaceOp>
1122 void surfaceSnSum
1123 (
1124  const surfaceScalarField& gammaWeights,
1126 
1127  const surfaceScalarField& deltaCoeffs,
1129 
1131 
1132  const CellToFaceOp& cop,
1133 
1135  const bool doCorrectBoundaryConditions
1136 )
1137 {
1138  const fvMesh& mesh = vf.mesh();
1139  const auto& Sf = mesh.Sf();
1140  const auto& P = mesh.owner();
1141  const auto& N = mesh.neighbour();
1142 
1143  const auto& gammai = gamma.primitiveField();
1144  const auto& vfi = vf.primitiveField();
1145  auto& sfi = result.primitiveFieldRef();
1146 
1147  // Internal field
1148  {
1149  const auto& Sfi = Sf.primitiveField();
1150  const auto& weights = gammaWeights.primitiveField();
1151  const auto& dc = deltaCoeffs.primitiveField();
1152  const auto& saddi = sadd.primitiveField();
1153 
1154  for (label facei=0; facei<P.size(); facei++)
1155  {
1156  const label ownCelli = P[facei];
1157  const label neiCelli = N[facei];
1158 
1159  const ResultType faceVal
1160  (
1161  cop
1162  (
1163  Sfi[facei], // area vector
1164 
1165  weights[facei], // interpolation weights
1166  gammai[ownCelli],
1167  gammai[neiCelli],
1168 
1169  dc[facei], // delta coefficients
1170  vfi[ownCelli],
1171  vfi[neiCelli],
1172 
1173  saddi[facei] // face addition value
1174  )
1175  );
1176  sfi[ownCelli] += faceVal;
1177  sfi[neiCelli] -= faceVal;
1178  }
1179  }
1180 
1181 
1182  // Boundary field
1183  {
1184  // Fetch patchNeighbourField onto end of GeoField
1185  const label oldSize = vf.constCast().boundaryEvaluate
1186  (
1187  [](const auto& pfld, UList<Type>& slice)
1188  {
1189  if (pfld.coupled())
1190  {
1191  pfld.patchNeighbourField(slice);
1192  }
1193  // else if (isA<emptyFvPatchField<Type>>(pfld))
1194  // {
1195  // slice = Zero;
1196  // }
1197  else
1198  {
1199  pfld.snGrad(slice);
1200  }
1201  }
1202  );
1203 
1204  (void) gamma.constCast().boundaryEvaluate
1205  (
1206  [](const auto& pfld, UList<GType>& slice)
1207  {
1208  if (pfld.coupled())
1209  {
1210  pfld.patchNeighbourField(slice);
1211  }
1212  }
1213  );
1214 
1215  forAll(mesh.boundary(), patchi)
1216  {
1217  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
1218  const auto& pSf = Sf.boundaryField()[patchi];
1219  const auto& pvf = vf.boundaryField()[patchi];
1220  const auto& pdc = deltaCoeffs.boundaryField()[patchi];
1221  const auto& pweights = gammaWeights.boundaryField()[patchi];
1222  const auto& pgamma = gamma.boundaryField()[patchi];
1223  const auto& psadd = sadd.boundaryField()[patchi];
1224 
1225  const label offset = mesh.nCells()+pvf.patch().offset();
1226 
1227  if (pvf.coupled())
1228  {
1229  for (label facei=0; facei<pFaceCells.size(); facei++)
1230  {
1231  const label ownCelli = pFaceCells[facei];
1232 
1233  // Interpolate between owner-side and neighbour-side values
1234  const ResultType faceVal
1235  (
1236  cop
1237  (
1238  pSf[facei], // area vector
1239 
1240  pweights[facei],
1241  gammai[ownCelli],
1242  //gammanf[facei],
1243  gammai[offset+facei],
1244 
1245  pdc[facei],
1246  vfi[ownCelli],
1247  //pnf[facei],
1248  vfi[offset+facei],
1249 
1250  psadd[facei]
1251  )
1252  );
1253  sfi[ownCelli] += faceVal;
1254  }
1255  }
1256  else
1257  {
1258  //auto tpnf(pvf.snGrad());
1259  //auto& pnf = tpnf();
1260 
1261  for (label facei=0; facei<pFaceCells.size(); facei++)
1262  {
1263  const label ownCelli = pFaceCells[facei];
1264 
1265  // Use patch value only
1266  const ResultType faceVal
1267  (
1268  cop
1269  (
1270  pSf[facei], // area vector
1271 
1272  scalar(1.0),
1273  pgamma[facei],
1274  pTraits<GType>::zero, // not used
1275 
1276 
1277  scalar(1.0), // use 100% of pnf
1278  pTraits<Type>::zero,
1279  //pnf[facei],
1280  vfi[offset+facei],
1281 
1282  psadd[facei]
1283  )
1284  );
1285  sfi[ownCelli] += faceVal;
1286  }
1287  }
1288  }
1289 
1290  // Restore original size
1291  vf.constCast().resize(oldSize);
1292  gamma.constCast().resize(oldSize);
1293  }
1294 
1296  {
1297  result.correctBoundaryConditions();
1298  }
1299 }
1300 
1301 
1302 template
1303 <
1304  class Type,
1305  class GType0,
1306  class GType1,
1307  class ResultType,
1308  class CellToFaceOp
1309 >
1310 void surfaceSnSum
1311 (
1312  const surfaceScalarField& gammaWeights,
1315 
1316  const surfaceScalarField& deltaCoeffs,
1318 
1319  const CellToFaceOp& cop,
1320 
1322  const bool doCorrectBoundaryConditions
1323 )
1324 {
1325  const fvMesh& mesh = vf.mesh();
1326  const auto& Sf = mesh.Sf();
1327  const auto& P = mesh.owner();
1328  const auto& N = mesh.neighbour();
1329 
1330  const auto& gamma0i = gamma0.primitiveField();
1331  const auto& gamma1i = gamma1.primitiveField();
1332  const auto& vfi = vf.primitiveField();
1333  auto& sfi = result.primitiveFieldRef();
1334 
1335  // Internal field
1336  {
1337  const auto& Sfi = Sf.primitiveField();
1338  const auto& weights = gammaWeights.primitiveField();
1339  const auto& dc = deltaCoeffs.primitiveField();
1340 
1341  for (label facei=0; facei<P.size(); facei++)
1342  {
1343  const label ownCelli = P[facei];
1344  const label neiCelli = N[facei];
1345 
1346  const ResultType faceVal
1347  (
1348  cop
1349  (
1350  Sfi[facei], // area vector
1351 
1352  weights[facei], // interpolation weights
1353 
1354  gamma0i[ownCelli],
1355  gamma0i[neiCelli],
1356 
1357  gamma1i[ownCelli],
1358  gamma1i[neiCelli],
1359 
1360  dc[facei], // delta coefficients
1361  vfi[ownCelli],
1362  vfi[neiCelli]
1363  )
1364  );
1365  sfi[ownCelli] += faceVal;
1366  sfi[neiCelli] -= faceVal;
1367  }
1368  }
1369 
1370 
1371  // Boundary field
1372  {
1373  // Fetch patchNeighbourField onto end of GeoField
1374  const label oldSize = vf.constCast().boundaryEvaluate
1375  (
1376  [](const auto& pfld, UList<Type>& slice)
1377  {
1378  if (pfld.coupled())
1379  {
1380  pfld.patchNeighbourField(slice);
1381  }
1382  // else if (isA<emptyFvPatchField<Type>>(pfld))
1383  // {
1384  // slice = Zero;
1385  // }
1386  else
1387  {
1388  pfld.snGrad(slice);
1389  }
1390  }
1391  );
1392 
1393  (void) gamma0.constCast().boundaryEvaluate
1394  (
1395  [](const auto& pfld, UList<GType0>& slice)
1396  {
1397  if (pfld.coupled())
1398  {
1399  pfld.patchNeighbourField(slice);
1400  }
1401  }
1402  );
1403 
1404  (void) gamma1.constCast().boundaryEvaluate
1405  (
1406  [](const auto& pfld, UList<GType1>& slice)
1407  {
1408  if (pfld.coupled())
1409  {
1410  pfld.patchNeighbourField(slice);
1411  }
1412  }
1413  );
1414 
1415  forAll(mesh.boundary(), patchi)
1416  {
1417  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
1418  const auto& pSf = Sf.boundaryField()[patchi];
1419  const auto& pvf = vf.boundaryField()[patchi];
1420  const auto& pdc = deltaCoeffs.boundaryField()[patchi];
1421  const auto& pweights = gammaWeights.boundaryField()[patchi];
1422  const auto& pgamma0 = gamma0.boundaryField()[patchi];
1423  const auto& pgamma1 = gamma1.boundaryField()[patchi];
1424 
1425  const label offset = mesh.nCells()+pvf.patch().offset();
1426 
1427  if (pvf.coupled())
1428  {
1429  //auto tpnf(pvf.patchNeighbourField());
1430  //auto& pnf = tpnf();
1431  //auto tgamma0nf(pgamma0.patchNeighbourField());
1432  //auto& gamma0nf = tgamma0nf();
1433  //auto tgamma1nf(pgamma1.patchNeighbourField());
1434  //auto& gamma1nf = tgamma1nf();
1435 
1436  for (label facei=0; facei<pFaceCells.size(); facei++)
1437  {
1438  const label ownCelli = pFaceCells[facei];
1439 
1440  // Interpolate between owner-side and neighbour-side values
1441  const ResultType faceVal
1442  (
1443  cop
1444  (
1445  pSf[facei], // area vector
1446 
1447  pweights[facei],
1448 
1449  gamma0i[ownCelli],
1450  gamma0i[offset+facei], //gamma0nf[facei],
1451 
1452  gamma1i[ownCelli],
1453  gamma1i[offset+facei], //gamma1nf[facei],
1454 
1455  pdc[facei],
1456  vfi[ownCelli],
1457  vfi[offset+facei] //pnf[facei]
1458  )
1459  );
1460  sfi[ownCelli] += faceVal;
1461  }
1462  }
1463  else
1464  {
1465  //auto tpnf(pvf.snGrad());
1466  //auto& pnf = tpnf();
1467  for (label facei=0; facei<pFaceCells.size(); facei++)
1468  {
1469  const label ownCelli = pFaceCells[facei];
1470 
1471  // Use patch value only
1472  const ResultType faceVal
1473  (
1474  cop
1475  (
1476  pSf[facei], // area vector
1477 
1478  scalar(1.0),
1479 
1480  pgamma0[facei],
1481  pTraits<GType0>::zero, // not used
1482 
1483  pgamma1[facei],
1484  pTraits<GType1>::zero, // not used
1485 
1486  scalar(1.0), // use 100% of pnf
1488  vfi[offset+facei] //pnf[facei]
1489  )
1490  );
1491  sfi[ownCelli] += faceVal;
1492  }
1493  }
1494  }
1495 
1496  // Restore original size
1497  vf.constCast().resize(oldSize);
1498  gamma0.constCast().resize(oldSize);
1499  gamma1.constCast().resize(oldSize);
1500  }
1501 
1503  {
1504  result.correctBoundaryConditions();
1505  }
1507 
1508 
1509 template<class Type, class FType, class ResultType, class CellToFaceOp>
1510 void interpolate
1511 (
1512  const surfaceScalarField& weights,
1515  const CellToFaceOp& cop,
1517 )
1518 {
1519  const fvMesh& mesh = vf.mesh();
1520  const auto& Sf = mesh.Sf();
1521  const auto& P = mesh.owner();
1522  const auto& N = mesh.neighbour();
1523 
1524  const auto& vfi = vf.primitiveField();
1525 
1526  // Internal field
1527  {
1528  const auto& Sfi = Sf.primitiveField();
1529  const auto& weight = weights.primitiveField();
1530  const auto& sfi = sf.primitiveField();
1531 
1532  auto& resulti = result.primitiveFieldRef();
1533 
1534  for (label facei=0; facei<P.size(); facei++)
1535  {
1536  const label ownCelli = P[facei];
1537  const label neiCelli = N[facei];
1538 
1539  cop
1540  (
1541  Sfi[facei],
1542 
1543  weight[facei],
1544  vfi[ownCelli],
1545  vfi[neiCelli],
1546 
1547  sfi[facei],
1548 
1549  resulti[facei]
1550  );
1551  }
1552  }
1553 
1554 
1555  // Boundary field
1556  {
1557  // Fetch patchNeighbourField onto end of GeoField
1558  const label oldSize = vf.constCast().boundaryEvaluate
1559  (
1560  [](const auto& pfld, UList<Type>& slice)
1561  {
1562  if (pfld.coupled())
1563  {
1564  pfld.patchNeighbourField(slice);
1565  }
1566  }
1567  );
1568 
1569  forAll(mesh.boundary(), patchi)
1570  {
1571  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
1572  const auto& pSf = Sf.boundaryField()[patchi];
1573  const auto& pvf = vf.boundaryField()[patchi];
1574  const auto& pweight = weights.boundaryField()[patchi];
1575  const auto& psf = sf.boundaryField()[patchi];
1576  auto& presult = result.boundaryFieldRef()[patchi];
1577 
1578  const label offset = mesh.nCells()+pvf.patch().offset();
1579 
1580  if (pvf.coupled())
1581  {
1582  //auto tpnf(pvf.patchNeighbourField());
1583  //auto& pnf = tpnf();
1584 
1585  for (label facei=0; facei<pFaceCells.size(); facei++)
1586  {
1587  // Interpolate between owner-side and neighbour-side values
1588  cop
1589  (
1590  pSf[facei],
1591 
1592  pweight[facei],
1593  vfi[pFaceCells[facei]],
1594  vfi[offset+facei], //pnf[facei],
1595 
1596  psf[facei],
1597 
1598  presult[facei]
1599  );
1600  }
1601  }
1602  else
1603  {
1604  for (label facei=0; facei<pFaceCells.size(); facei++)
1605  {
1606  // Use patch value only
1607  cop
1608  (
1609  pSf[facei],
1610 
1611  scalar(1.0),
1612  pvf[facei],
1613  pTraits<Type>::zero, // not used
1614 
1615  psf[facei],
1616 
1617  presult[facei]
1618  );
1619  }
1620  }
1621  }
1622 
1623  // Restore original size
1624  vf.constCast().resize(oldSize);
1625  }
1626 }
1627 
1628 
1629 template
1630 <
1631  class Type0,
1632  class Type1,
1633  class ResultType,
1634  class CellToFaceOp
1635 >
1636 void interpolate
1637 (
1638  const surfaceScalarField& weights,
1641  const CellToFaceOp& cop,
1643 )
1644 {
1645  const fvMesh& mesh = vf0.mesh();
1646  const auto& Sf = mesh.Sf();
1647  const auto& P = mesh.owner();
1648  const auto& N = mesh.neighbour();
1649 
1650  const auto& vf0i = vf0.primitiveField();
1651  const auto& vf1i = vf1.primitiveField();
1652 
1653  // Internal field
1654  {
1655  const auto& Sfi = Sf.primitiveField();
1656  const auto& weight = weights.primitiveField();
1657 
1658  auto& resulti = result.primitiveFieldRef();
1659 
1660  for (label facei=0; facei<P.size(); facei++)
1661  {
1662  const label ownCelli = P[facei];
1663  const label neiCelli = N[facei];
1664 
1665  cop
1666  (
1667  Sfi[facei],
1668 
1669  weight[facei],
1670 
1671  vf0i[ownCelli],
1672  vf0i[neiCelli],
1673 
1674  vf1i[ownCelli],
1675  vf1i[neiCelli],
1676 
1677  resulti[facei]
1678  );
1679  }
1680  }
1681 
1682 
1683  // Boundary field
1684  {
1685  // Fetch patchNeighbourField onto end of GeoField
1686  const label oldSize = vf0.constCast().boundaryEvaluate
1687  (
1688  [](const auto& pfld, UList<Type0>& slice)
1689  {
1690  if (pfld.coupled())
1691  {
1692  pfld.patchNeighbourField(slice);
1693  }
1694  }
1695  );
1696 
1697  // Fetch patchNeighbourField onto end of GeoField
1698  (void) vf1.constCast().boundaryEvaluate
1699  (
1700  [](const auto& pfld, UList<Type1>& slice)
1701  {
1702  if (pfld.coupled())
1703  {
1704  pfld.patchNeighbourField(slice);
1705  }
1706  }
1707  );
1708 
1709  forAll(mesh.boundary(), patchi)
1710  {
1711  const auto& pFaceCells = mesh.boundary()[patchi].faceCells();
1712  const auto& pSf = Sf.boundaryField()[patchi];
1713  const auto& pvf0 = vf0.boundaryField()[patchi];
1714  const auto& pvf1 = vf1.boundaryField()[patchi];
1715  const auto& pweight = weights.boundaryField()[patchi];
1716  auto& presult = result.boundaryFieldRef()[patchi];
1717 
1718  const label offset = mesh.nCells()+pvf0.patch().offset();
1719 
1720  if (pvf0.coupled() || pvf1.coupled())
1721  {
1722  //auto tpnf0(pvf0.patchNeighbourField());
1723  //auto& pnf0 = tpnf0();
1724  //auto tpnf1(pvf1.patchNeighbourField());
1725  //auto& pnf1 = tpnf1();
1726 
1727  for (label facei=0; facei<pFaceCells.size(); facei++)
1728  {
1729  // Interpolate between owner-side and neighbour-side values
1730  cop
1731  (
1732  pSf[facei],
1733 
1734  pweight[facei],
1735 
1736  vf0i[pFaceCells[facei]],
1737  vf0i[offset+facei], //pnf0[facei],
1738 
1739  vf1i[pFaceCells[facei]],
1740  vf1i[offset+facei], //pnf1[facei],
1741 
1742  presult[facei]
1743  );
1744  }
1745  }
1746  else
1747  {
1748  for (label facei=0; facei<pFaceCells.size(); facei++)
1749  {
1750  // Use patch value only
1751  cop
1752  (
1753  pSf[facei],
1754 
1755  scalar(1.0),
1756 
1757  pvf0[facei],
1758  pTraits<Type0>::zero, // not used
1759 
1760  pvf1[facei],
1761  pTraits<Type1>::zero, // not used
1762 
1763  presult[facei]
1764  );
1765  }
1766  }
1767  }
1768 
1769  // Restore original size
1770  vf0.constCast().resize(oldSize);
1771  vf1.constCast().resize(oldSize);
1772  }
1773 }
1774 
1775 
1776 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1777 
1778 } // End namespace fvc
1779 
1780 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1781 
1782 } // End namespace Foam
1783 
1784 // ************************************************************************* //
const polyBoundaryMesh & pbm
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:119
const Internal::FieldType & primitiveField() const noexcept
Return a const-reference to the internal field values.
A traits class, which is primarily used for primitives and vector-space.
Definition: pTraits.H:63
static void doCorrectBoundaryConditions(bool correctBCs, VolumeField< Type > &field)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:400
dynamicFvMesh & mesh
const cellShapeList & cells
dimensionedScalar lambda("lambda", dimTime/sqr(dimLength), laminarTransport)
void surfaceSnSum(const surfaceScalarField &deltaCoeffs, const GeometricField< Type, fvPatchField, volMesh > &vf, const CellToFaceOp &cop, GeometricField< ResultType, fvPatchField, volMesh > &result, const bool doCorrectBoundaryConditions)
sum of snGrad
this_type & constCast() const noexcept
Return non-const reference to this field.
void surfaceOp(const GeometricField< Type, fvPatchField, volMesh > &vf, const surfaceVectorField &ownLs, const surfaceVectorField &neiLs, const CombineOp &cop, GeometricField< ResultType, fvPatchField, volMesh > &result)
static tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
const Vector< label > N(dict.get< Vector< label >>("N"))
Surface integrate surfaceField creating a volField. Surface sum a surfaceField creating a volField...
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field values.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:58
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
const Mesh & mesh() const noexcept
Return const reference to mesh.
Boundary & boundaryFieldRef(const bool updateAccessTime=true)
Return a reference to the boundary field.
void correctBoundaryConditions()
Correct boundary field.
tmp< GeometricField< Type, fvPatchField, volMesh > > surfaceSum(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
const scalar gamma
Definition: EEqn.H:9
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
void GaussOp(const surfaceScalarField &lambdas, const GeometricField< Type, fvPatchField, volMesh > &vf, const CombineOp &cop, GeometricField< ResultType, fvPatchField, volMesh > &result)
Namespace for OpenFOAM.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127