cutLayerAverage.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "cutLayerAverage.H"
27 #include "cutPolyIntegral.H"
28 #include "OSspecific.H"
29 #include "volPointInterpolation.H"
30 #include "writeFile.H"
31 #include "polyTopoChangeMap.H"
32 #include "polyMeshMap.H"
33 #include "polyDistributionMap.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40 namespace functionObjects
41 {
44  (
48  );
49 }
50 }
51 
52 
53 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
54 
55 namespace Foam
56 {
57 
58 //- Allocate and return a pair of fields
59 template<class Type>
61 {
62  return
64  (
65  new Pair<Field<Type>>(Field<Type>(size), Field<Type>(size))
66  );
67 }
68 
69 
70 //- Allocate and return a pair of a pair of fields
71 template<class Type>
73 {
74  return
76  (
78  (
81  )
82  );
83 }
84 
85 
86 //- Base class for classes which manage incomplete sets of face data
87 class faceData
88 {
89 protected:
90 
91  const cellList& cells_;
92 
94 
96 
97  const faceList& faces_;
98 
100 
102 
104 
106 
108 
110 
112 
113  inline label activeLayeri(const label layeri) const
114  {
115  return layeri % faceis_.size();
116  }
117 
118 public:
119 
121  (
122  const fvMesh& mesh,
123  const label nActiveLayers,
124  const scalarField& pointXs,
125  const scalarField& plotXs
126  )
127  :
128  cells_(mesh.cells()),
130  cellVolumes_(mesh.cellVolumes()),
131  faces_(mesh.faces()),
132  faceAreas_(mesh.faceAreas()),
133  faceCentres_(mesh.faceCentres()),
134  points_(mesh.points()),
135  pointXs_(pointXs),
136  plotXs_(plotXs),
137  faceis_(nActiveLayers),
138  haveFaces_(nActiveLayers)
139  {
140  forAll(faceis_, i)
141  {
142  faceis_.set(i, new DynamicList<label>(mesh.nFaces()));
143  haveFaces_.set(i, new boolList(mesh.nFaces(), false));
144  }
145  }
146 
147  void clear(const label layeri)
148  {
150  (
151  haveFaces_[activeLayeri(layeri)],
152  faceis_[activeLayeri(layeri)]
153  ) = false;
154 
155  faceis_[activeLayeri(layeri)].clear();
156  }
157 };
158 
159 
160 //- Class to manage face cut data
162 :
163  public faceData
164 {
165 private:
166 
167  PtrList<List<List<labelPair>>> faceCuts_;
168 
169  PtrList<Pair<vectorField>> faceCutAreas_;
170 
171 public:
172 
174  (
175  const fvMesh& mesh,
176  const label nActiveLayers,
177  const scalarField& pointXs,
178  const scalarField& plotXs
179  )
180  :
181  faceData(mesh, nActiveLayers, pointXs, plotXs),
182  faceCuts_(nActiveLayers),
183  faceCutAreas_(nActiveLayers)
184  {
185  forAll(faceis_, i)
186  {
187  faceCuts_.set(i, new List<List<labelPair>>(mesh.nFaces()));
188  faceCutAreas_.set(i, fieldPairPtr<vector>(mesh.nFaces()));
189  }
190  }
191 
192  void cache(const label celli, const label layeri)
193  {
194  forAll(cells_[celli], cellFacei)
195  {
196  const label facei = cells_[celli][cellFacei];
197 
198  if (haveFaces_[activeLayeri(layeri)][facei]) continue;
199 
200  faceis_[activeLayeri(layeri)].append(facei);
201 
202  haveFaces_[activeLayeri(layeri)][facei] = true;
203 
204  faceCuts_[activeLayeri(layeri)][facei] =
206  (
207  faces_[facei],
208  pointXs_,
209  plotXs_[layeri]
210  );
211 
212  for (label sidei = 0; sidei <= 1; ++ sidei)
213  {
214  faceCutAreas_[activeLayeri(layeri)][sidei][facei] =
216  (
217  faces_[facei],
218  faceAreas_[facei],
219  faceCuts_[activeLayeri(layeri)][facei],
220  points_,
221  pointXs_,
222  plotXs_[layeri],
223  sidei == 0
224  );
225  }
226  }
227  }
228 
229  const List<List<labelPair>>& faceCuts(const label layeri) const
230  {
231  return faceCuts_[activeLayeri(layeri)];
232  }
233 
234  const Pair<vectorField>& faceCutAreas(const label layeri) const
235  {
236  return faceCutAreas_[activeLayeri(layeri)];
237  }
238 };
239 
240 
241 //- Class to manage face basis function data
243 :
244  public faceData
245 {
246 private:
247 
248  const faceCutData& fcd_;
249 
250  PtrList<Pair<scalarField>> pointFs_;
251 
252  PtrList<Pair<scalarField>> faceFs_;
253 
254  PtrList<Pair<Pair<scalarField>>> faceCutFs_;
255 
256 
257 public:
258 
260  (
261  const faceCutData& fcd,
262  const fvMesh& mesh,
263  const label nActiveLayers,
264  const scalarField& pointXs,
265  const scalarField& plotXs
266  )
267  :
268  faceData(mesh, nActiveLayers, pointXs, plotXs),
269  fcd_(fcd),
270  pointFs_(nActiveLayers),
271  faceFs_(nActiveLayers),
272  faceCutFs_(nActiveLayers)
273  {
274  forAll(faceis_, i)
275  {
276  pointFs_.set(i, fieldPairPtr<scalar>(mesh.nPoints()));
277  faceFs_.set(i, fieldPairPtr<scalar>(mesh.nFaces()));
278  faceCutFs_.set(i, fieldPairPairPtr<scalar>(mesh.nFaces()));
279  }
280  }
281 
282  void cache(const label celli, const label layeri)
283  {
284  forAll(cells_[celli], cellFacei)
285  {
286  const label facei = cells_[celli][cellFacei];
287 
288  if (haveFaces_[activeLayeri(layeri)][facei]) continue;
289 
290  faceis_[activeLayeri(layeri)].append(facei);
291 
292  haveFaces_[activeLayeri(layeri)][facei] = true;
293 
294  forAll(faces_[facei], facePointi)
295  {
296  const label pointi = faces_[facei][facePointi];
297 
298  if (layeri > 0)
299  {
300  pointFs_[activeLayeri(layeri)][0][pointi] =
301  (pointXs_[pointi] - plotXs_[layeri - 1])
302  /(plotXs_[layeri] - plotXs_[layeri - 1]);
303  }
304 
305  if (layeri < plotXs_.size() - 1)
306  {
307  pointFs_[activeLayeri(layeri)][1][pointi] =
308  (plotXs_[layeri + 1] - pointXs_[pointi])
309  /(plotXs_[layeri + 1] - plotXs_[layeri]);
310  }
311  }
312 
313  for
314  (
315  label fi = (layeri > 0 ? 0 : 1);
316  fi <= (layeri < plotXs_.size() - 1 ? 1 : 0);
317  fi ++
318  )
319  {
320  faceFs_[activeLayeri(layeri)][fi][facei] =
322  (
323  faces_[facei],
324  points_,
325  pointFs_[activeLayeri(layeri)][fi]
326  ).second();
327  }
328 
329  for
330  (
331  label fi = (layeri > 0 ? 0 : 1);
332  fi <= (layeri < plotXs_.size() - 1 ? 1 : 0);
333  fi ++
334  )
335  {
336  for (label sidei = 0; sidei <= 1; ++ sidei)
337  {
338  const label layerj =
339  fi == 0 && sidei == 0 ? layeri - 1
340  : fi == 1 && sidei == 1 ? layeri + 1
341  : layeri;
342 
343  if (layerj < 0 || layerj > plotXs_.size() - 1) continue;
344 
345  Tuple2<vector, vector> integral =
347  (
348  faces_[facei],
349  faceAreas_[facei],
350  faceFs_[activeLayeri(layeri)][fi][facei],
351  fcd_.faceCuts(layerj)[facei],
352  points_,
353  pointFs_[activeLayeri(layeri)][fi],
354  pointXs_,
355  plotXs_[layerj],
356  sidei == 0
357  );
358 
359  const scalar magSqrArea = magSqr(integral.first());
360 
361  faceCutFs_[activeLayeri(layeri)][fi][sidei][facei] =
362  magSqrArea > vSmall
363  ? integral.second() & integral.first()/magSqrArea
364  : faceFs_[activeLayeri(layeri)][fi][facei];
365  }
366  }
367  }
368  }
369 
370  const Pair<scalarField>& pointFs(const label layeri) const
371  {
372  return pointFs_[activeLayeri(layeri)];
373  }
374 
375  const Pair<scalarField>& faceFs(const label layeri) const
376  {
377  return faceFs_[activeLayeri(layeri)];
378  }
379 
380  const Pair<Pair<scalarField>>& faceCutFs(const label layeri) const
381  {
382  return faceCutFs_[activeLayeri(layeri)];
383  }
384 };
385 
386 }
387 
388 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
389 
390 Foam::fileName Foam::functionObjects::cutLayerAverage::outputPath() const
391 {
392  return
393  time_.globalPath()
395  /(mesh_.name() != polyMesh::defaultRegion ? mesh_.name() : word())
396  /name()
397  /time_.name();
398 }
399 
400 
402 Foam::functionObjects::cutLayerAverage::calcNonInterpolatingWeights
403 (
404  const scalarField& pointXs,
405  const scalarField& zoneCellMinXs,
406  const scalarField& zoneCellMaxXs,
407  const labelList& zoneCellMinOrder,
408  const scalarField& plotXs,
409  const bool normalise
410 ) const
411 {
412  const cellList& cells = mesh_.cells();
413  const cellEdgeAddressingList& cAddrs = cellEdgeAddressingList::New(mesh_);
414  const scalarField& cellVolumes = mesh_.cellVolumes();
415  const faceList& faces = mesh_.faces();
416  const vectorField& faceAreas = mesh_.faceAreas();
417  const pointField& faceCentres = mesh_.faceCentres();
418  const pointField& points = mesh_.points();
419 
420  // Determine the largest number of layers spanned by a single cell, and
421  // therefore the number for which data must be simultaneously maintained
422  label nActiveLayers = 0;
423  {
424  label layeri = 0;
425  forAll(zoneCellMinOrder, zoneCellMinOrderi)
426  {
427  const label zoneCelli = zoneCellMinOrder[zoneCellMinOrderi];
428 
429  // Find the next relevant layer
430  while (zoneCellMinXs[zoneCelli] > plotXs[layeri + 1]) layeri ++;
431 
432  // Find the first irrelevant layer
433  label layerj = layeri;
434  while (zoneCellMaxXs[zoneCelli] > plotXs[layerj]) layerj ++;
435 
436  nActiveLayers = max(nActiveLayers, layerj - layeri);
437  }
438  }
439 
440  // Storage for face cut data
441  faceCutData fcd(mesh_, nActiveLayers, pointXs, plotXs);
442 
443  // Generate weights for each cell in turn
444  DynamicList<weight> dynWeights(zone_.nCells()*2);
445  label layeri = 0;
446  forAll(zoneCellMinOrder, zoneCellMinOrderi)
447  {
448  const label zoneCelli = zoneCellMinOrder[zoneCellMinOrderi];
449  const label celli = zone_.celli(zoneCelli);
450 
451  // Find the next relevant layer and remove all data relating to
452  // layers now behind the spans of the remaining cells
453  while (zoneCellMinXs[zoneCelli] > plotXs[layeri + 1])
454  {
455  fcd.clear(layeri);
456  layeri ++;
457  }
458 
459  // Loop over all relevant layer intervals
460  label layerj = layeri;
461  while (zoneCellMaxXs[zoneCelli] > plotXs[layerj])
462  {
463  // Compute the face data as necessary
464  fcd.cache(celli, layerj);
465  fcd.cache(celli, layerj + 1);
466 
467  // Add a new weight
468  dynWeights.append({celli, layerj, cellVolumes[celli]});
469 
470  // Left interval
471  if (zoneCellMinXs[zoneCelli] < plotXs[layerj])
472  {
473  dynWeights.last().value -=
475  (
476  cells[celli],
477  cAddrs[celli],
478  cellVolumes[celli],
480  (
481  cells[celli],
482  cAddrs[celli],
483  faces,
484  fcd.faceCuts(layerj),
485  pointXs,
486  plotXs[layerj]
487  ),
488  faces,
489  faceAreas,
490  faceCentres,
491  fcd.faceCutAreas(layerj)[0],
492  points,
493  pointXs,
494  plotXs[layerj],
495  true
496  );
497  }
498 
499  // Right interval
500  if (zoneCellMaxXs[zoneCelli] > plotXs[layerj + 1])
501  {
502  dynWeights.last().value -=
504  (
505  cells[celli],
506  cAddrs[celli],
507  cellVolumes[celli],
509  (
510  cells[celli],
511  cAddrs[celli],
512  faces,
513  fcd.faceCuts(layerj + 1),
514  pointXs,
515  plotXs[layerj + 1]
516  ),
517  faces,
518  faceAreas,
519  faceCentres,
520  fcd.faceCutAreas(layerj + 1)[1],
521  points,
522  pointXs,
523  plotXs[layerj + 1],
524  false
525  );
526  }
527 
528  layerj ++;
529  }
530  }
531 
532  // Transfer to non-dynamic storage
533  List<weight> weights;
534  weights.transfer(dynWeights);
535 
536  // Normalise, if requested
537  if (normalise)
538  {
539  scalarField layerWeightSums(nLayers_, scalar(0));
540  forAll(weights, weighti)
541  {
542  layerWeightSums[weights[weighti].layeri] += weights[weighti].value;
543  }
544 
545  Pstream::listCombineGather(layerWeightSums, plusEqOp<scalar>());
546  Pstream::listCombineScatter(layerWeightSums);
547 
548  forAll(weights, weighti)
549  {
550  weights[weighti].value /=
551  (layerWeightSums[weights[weighti].layeri] + vSmall);
552  }
553  }
554 
555  return weights;
556 }
557 
558 
560 Foam::functionObjects::cutLayerAverage::calcInterpolatingWeights
561 (
562  const scalarField& pointXs,
563  const scalarField& zoneCellMinXs,
564  const scalarField& zoneCellMaxXs,
565  const labelList& zoneCellMinOrder,
566  const scalarField& plotXs,
567  const bool normalise
568 ) const
569 {
570  const cellList& cells = mesh_.cells();
571  const cellEdgeAddressingList& cAddrs = cellEdgeAddressingList::New(mesh_);
572  const scalarField& cellVolumes = mesh_.cellVolumes();
573  const faceList& faces = mesh_.faces();
574  const vectorField& faceAreas = mesh_.faceAreas();
575  const pointField& faceCentres = mesh_.faceCentres();
576  const pointField& points = mesh_.points();
577 
578  // Determine the largest number of layers spanned by a single cell, and
579  // therefore the number for which data must be simultaneously maintained
580  label nActiveLayers = 0;
581  {
582  label layeri = 0;
583  forAll(zoneCellMinOrder, zoneCellMinOrderi)
584  {
585  const label zoneCelli = zoneCellMinOrder[zoneCellMinOrderi];
586 
587  // Find the next relevant layer
588  while (zoneCellMinXs[zoneCelli] > plotXs[layeri + 1])
589  {
590  layeri ++;
591  }
592 
593  // Find the first irrelevant layer
594  label layerj = layeri;
595  while (zoneCellMaxXs[zoneCelli] > plotXs[max(layerj - 1, 0)])
596  {
597  layerj ++;
598  }
599 
600  nActiveLayers = max(nActiveLayers, layerj - layeri + 1);
601  }
602  }
603 
604  // Storage for face cut and face functions data
605  faceCutData fcd(mesh_, nActiveLayers, pointXs, plotXs);
606  faceFsData ffs(fcd, mesh_, nActiveLayers, pointXs, plotXs);
607 
608  // Generate weights for each cell in turn
609  DynamicList<weight> dynWeights(zone_.nCells()*2);
610  label layeri = 0;
611  forAll(zoneCellMinOrder, zoneCellMinOrderi)
612  {
613  const label zoneCelli = zoneCellMinOrder[zoneCellMinOrderi];
614  const label celli = zone_.celli(zoneCelli);
615 
616  // Find the next relevant layer and remove all data relating to
617  // layers now behind the spans of the remaining cells
618  while (zoneCellMinXs[zoneCelli] > plotXs[layeri + 1])
619  {
620  if (layeri != 0) fcd.clear(layeri - 1);
621  ffs.clear(layeri);
622  layeri ++;
623  }
624 
625  // Loop over all relevant layers
626  label layerj = layeri;
627  while (zoneCellMaxXs[zoneCelli] > plotXs[max(layerj - 1, 0)])
628  {
629  // Compute the connected face data as necessary
630  if (layerj != 0) fcd.cache(celli, layerj - 1);
631  fcd.cache(celli, layerj);
632  if (layerj != nLayers_ - 1) fcd.cache(celli, layerj + 1);
633  ffs.cache(celli, layerj);
634 
635  // Add a new weight
636  dynWeights.append({celli, layerj, 0});
637 
638  // Get the cell cuts for the middle of the layer. These will be
639  // used twice. The cuts for the left and right will only be used
640  // once and hence don't need to be stored. They are evaluated
641  // inline below.
642  const labelListList cCutsMid =
644  (
645  cells[celli],
646  cAddrs[celli],
647  faces,
648  fcd.faceCuts(layerj),
649  pointXs,
650  plotXs[layerj]
651  );
652 
653  // Left interval
654  if
655  (
656  layerj > 0
657  && zoneCellMinXs[zoneCelli] < plotXs[layerj]
658  )
659  {
660  const scalar cellVF =
662  (
663  cells[celli],
664  cAddrs[celli],
665  faceAreas,
666  faceCentres,
667  ffs.faceFs(layerj)[0]
668  ).second();
669 
670  // Add the whole cell's contribution
671  dynWeights.last().value += cellVF;
672 
673  // Cut off anything before the left point
674  if (zoneCellMinXs[zoneCelli] < plotXs[layerj - 1])
675  {
676  dynWeights.last().value -=
678  (
679  cells[celli],
680  cAddrs[celli],
681  cellVolumes[celli],
682  cellVF/cellVolumes[celli],
684  (
685  cells[celli],
686  cAddrs[celli],
687  faces,
688  fcd.faceCuts(layerj - 1),
689  pointXs,
690  plotXs[layerj - 1]
691  ),
692  faces,
693  faceAreas,
694  faceCentres,
695  ffs.faceFs(layerj)[0],
696  fcd.faceCutAreas(layerj - 1)[0],
697  ffs.faceCutFs(layerj)[0][0],
698  points,
699  ffs.pointFs(layerj)[0],
700  pointXs,
701  plotXs[layerj - 1],
702  true
703  ).second();
704  }
705 
706  // Cut off anything after the middle point
707  if (zoneCellMaxXs[zoneCelli] > plotXs[layerj])
708  {
709  dynWeights.last().value -=
711  (
712  cells[celli],
713  cAddrs[celli],
714  cellVolumes[celli],
715  cellVF/cellVolumes[celli],
716  cCutsMid,
717  faces,
718  faceAreas,
719  faceCentres,
720  ffs.faceFs(layerj)[0],
721  fcd.faceCutAreas(layerj)[1],
722  ffs.faceCutFs(layerj)[0][1],
723  points,
724  ffs.pointFs(layerj)[0],
725  pointXs,
726  plotXs[layerj],
727  false
728  ).second();
729  }
730  }
731 
732  // Right interval
733  if
734  (
735  layerj < nLayers_ - 1
736  && zoneCellMaxXs[zoneCelli] > plotXs[layerj]
737  )
738  {
739  const scalar cellVF =
741  (
742  cells[celli],
743  cAddrs[celli],
744  faceAreas,
745  faceCentres,
746  ffs.faceFs(layerj)[1]
747  ).second();
748 
749  // Add the whole cell's contribution
750  dynWeights.last().value += cellVF;
751 
752  // Cut off anything before the middle point
753  if (zoneCellMinXs[zoneCelli] < plotXs[layerj])
754  {
755  dynWeights.last().value -=
757  (
758  cells[celli],
759  cAddrs[celli],
760  cellVolumes[celli],
761  cellVF/cellVolumes[celli],
762  cCutsMid,
763  faces,
764  faceAreas,
765  faceCentres,
766  ffs.faceFs(layerj)[1],
767  fcd.faceCutAreas(layerj)[0],
768  ffs.faceCutFs(layerj)[1][0],
769  points,
770  ffs.pointFs(layerj)[1],
771  pointXs,
772  plotXs[layerj],
773  true
774  ).second();
775  }
776 
777  // Cut off anything after the right point
778  if (zoneCellMaxXs[zoneCelli] > plotXs[layerj + 1])
779  {
780  dynWeights.last().value -=
782  (
783  cells[celli],
784  cAddrs[celli],
785  cellVolumes[celli],
786  cellVF/cellVolumes[celli],
788  (
789  cells[celli],
790  cAddrs[celli],
791  faces,
792  fcd.faceCuts(layerj + 1),
793  pointXs,
794  plotXs[layerj + 1]
795  ),
796  faces,
797  faceAreas,
798  faceCentres,
799  ffs.faceFs(layerj)[1],
800  fcd.faceCutAreas(layerj + 1)[1],
801  ffs.faceCutFs(layerj)[1][1],
802  points,
803  ffs.pointFs(layerj)[1],
804  pointXs,
805  plotXs[layerj + 1],
806  false
807  ).second();
808  }
809  }
810 
811  layerj ++;
812  }
813  }
814 
815  // Transfer to non-dynamic storage
816  List<weight> weights;
817  weights.transfer(dynWeights);
818 
819  // Normalise, if requested. Otherwise, double the weight values on the ends
820  // to account for the fact that these points only have half a basis function
821  // contributing to their sums.
822  if (normalise)
823  {
824  scalarField layerWeightSums(nLayers_, scalar(0));
825  forAll(weights, weighti)
826  {
827  layerWeightSums[weights[weighti].layeri] += weights[weighti].value;
828  }
829 
830  Pstream::listCombineGather(layerWeightSums, plusEqOp<scalar>());
831  Pstream::listCombineScatter(layerWeightSums);
832 
833  forAll(weights, weighti)
834  {
835  weights[weighti].value /=
836  (layerWeightSums[weights[weighti].layeri] + vSmall);
837  }
838  }
839  else
840  {
841  forAll(weights, weighti)
842  {
843  if
844  (
845  weights[weighti].layeri == 0
846  || weights[weighti].layeri == nLayers_ - 1
847  )
848  {
849  weights[weighti].value *= 2;
850  }
851  }
852  }
853 
854  return weights;
855 }
856 
857 
859 Foam::functionObjects::cutLayerAverage::calcWeights
860 (
861  const scalarField& pointXs,
862  const scalarField& zoneCellMinXs,
863  const scalarField& zoneCellMaxXs,
864  const labelList& zoneCellMinOrder,
865  const scalarField& plotXs,
866  const bool normalise
867 ) const
868 {
869  return
870  interpolate_
871  ? calcInterpolatingWeights
872  (
873  pointXs,
874  zoneCellMinXs,
875  zoneCellMaxXs,
876  zoneCellMinOrder,
877  plotXs,
878  normalise
879  )
880  : calcNonInterpolatingWeights
881  (
882  pointXs,
883  zoneCellMinXs,
884  zoneCellMaxXs,
885  zoneCellMinOrder,
886  plotXs,
887  normalise
888  );
889 }
890 
891 
892 void Foam::functionObjects::cutLayerAverage::calcWeights()
893 {
894  const cellList& cells = mesh_.cells();
895  const faceList& faces = mesh_.faces();
896  const pointField& points = mesh_.points();
897 
898  // If interpolating, then the layers and the plot points are coincident. If
899  // not interpolating, then the layers lie in between the plot points, so
900  // there is one more point than there are layers.
901  const label nPlot = interpolate_ ? nLayers_ : nLayers_ + 1;
902 
903  // Calculate or get the point coordinates
904  tmp<pointScalarField> tdistance =
905  distanceName_ == word::null
906  ? tmp<pointScalarField>(nullptr)
907  : mesh_.foundObject<volScalarField>(distanceName_)
908  ? volPointInterpolation::New(mesh_).interpolate
909  (
910  mesh_.lookupObject<volScalarField>(distanceName_)
911  )
912  : tmp<pointScalarField>
913  (
914  mesh_.lookupObject<pointScalarField>(distanceName_)
915  );
916  tmp<scalarField> tpointXs =
917  distanceName_ == word::null
918  ? points & direction_
919  : tmp<scalarField>(tdistance().primitiveField());
920  const scalarField& pointXs = tpointXs();
921 
922  // Determine face min and max coordinates
923  scalarField zoneCellMinXs(zone_.nCells(), vGreat);
924  scalarField zoneCellMaxXs(zone_.nCells(), -vGreat);
925  forAll(zoneCellMinXs, zoneCelli)
926  {
927  const label celli = zone_.celli(zoneCelli);
928  forAll(cells[celli], cellFacei)
929  {
930  const label facei = cells[celli][cellFacei];
931  forAll(faces[facei], facePointi)
932  {
933  const label pointi = faces[facei][facePointi];
934  zoneCellMinXs[zoneCelli] =
935  min(zoneCellMinXs[zoneCelli], pointXs[pointi]);
936  zoneCellMaxXs[zoneCelli] =
937  max(zoneCellMaxXs[zoneCelli], pointXs[pointi]);
938  }
939  }
940  }
941 
942  // Create orderings of the cells based on their min and max coordinates
943  labelList zoneCellMinOrder(zone_.nCells());
944  sortedOrder(zoneCellMinXs, zoneCellMinOrder);
945 
946  // Assume equal spacing to begin with
947  const scalar xMin = gMin(pointXs), xMax = gMax(pointXs);
948  scalarField plotXs
949  (
950  (xMin + scalarList(identityMap(nPlot))/(nPlot - 1)*(xMax - xMin))
951  );
952 
953  // Names and fields for debug output of the counts, to observe the effect
954  // of iterative improvement of the spacing
956  #define DeclareTypeFieldValues(Type, nullArg) \
957  PtrList<Field<Type>> Type##FieldValues;
959  #undef DeclareTypeFieldValues
960 
961  // Iteratively optimise the spacing between the plot points to achieve an
962  // approximately equal number of data points in each interval
963  for (label iteri = 0; iteri < nOptimiseIter_ + debug; ++ iteri)
964  {
965  // Determine the count of faces that contribute to each layer
966  const List<weight> weights =
967  calcWeights
968  (
969  pointXs,
970  zoneCellMinXs,
971  zoneCellMaxXs,
972  zoneCellMinOrder,
973  plotXs,
974  false
975  );
976  const scalarField layerCounts
977  (
978  applyWeights<scalar>(weights, (1/mesh_.V())())
979  );
980 
981  if (debug)
982  {
983  const label nFields0 = (2 + !interpolate_)*iteri;
984  const label nFields = (2 + !interpolate_)*(iteri + 1);
985 
986  fieldNames.resize(nFields);
987  #define ResizeTypeFieldValues(Type, nullArg) \
988  Type##FieldValues.resize(nFields);
990  #undef ResizeTypeFieldValues
991 
992  if (!interpolate_)
993  {
994  const SubField<scalar> distance0s(plotXs, nLayers_);
995  const SubField<scalar> distance1s(plotXs, nLayers_, 1);
996 
997  fieldNames[nFields0] = "distance-" + Foam::name(iteri);
998  scalarFieldValues.set(nFields0, (distance0s + distance1s)/2);
999 
1000  fieldNames[nFields0 + 1] = "thickness-" + Foam::name(iteri);
1001  scalarFieldValues.set(nFields0 + 1, distance1s - distance0s);
1002  }
1003  else
1004  {
1005  fieldNames[nFields0] = "distance-" + Foam::name(iteri);
1006  scalarFieldValues.set(nFields0, new scalarField(plotXs));
1007  }
1008 
1009  fieldNames[nFields - 1] = "count-" + Foam::name(iteri);
1010  scalarFieldValues.set(nFields - 1, new scalarField(layerCounts));
1011 
1012  if (iteri == nOptimiseIter_) break;
1013  }
1014 
1015  // Do a cumulative sum of the layer counts across all plot points
1016  scalarField plotSumCounts(nPlot, 0);
1017  for (label ploti = 0; ploti < nPlot - 1; ++ ploti)
1018  {
1019  plotSumCounts[ploti + 1] =
1020  plotSumCounts[ploti]
1021  + (
1022  interpolate_
1023  ? (layerCounts[ploti + 1] + layerCounts[ploti])/2
1024  : layerCounts[ploti]
1025  );
1026  }
1027 
1028  // Compute the desired count in each interval
1029  const scalar plotDeltaCount = plotSumCounts.last()/(nPlot - 1);
1030 
1031  // Compute the new spacing between the points
1032  scalarField plot0Xs(plotXs);
1033  plotXs = -vGreat;
1034  plotXs.first() = xMin;
1035  label ploti = 1;
1036  for (label ploti0 = 0; ploti0 < nPlot - 1; ++ ploti0)
1037  {
1038  while
1039  (
1040  ploti < nPlot
1041  && plotSumCounts[ploti0 + 1] > ploti*plotDeltaCount
1042  )
1043  {
1044  const scalar f =
1045  (ploti*plotDeltaCount - plotSumCounts[ploti0])
1046  /(plotSumCounts[ploti0 + 1] - plotSumCounts[ploti0]);
1047 
1048  plotXs[ploti] = (1 - f)*plot0Xs[ploti0] + f*plot0Xs[ploti0 + 1];
1049 
1050  ploti ++;
1051  }
1052  }
1053  plotXs.last() = xMax;
1054  }
1055 
1056  if (debug)
1057  {
1058  mkDir(outputPath());
1059 
1060  formatter_->write
1061  (
1062  outputPath(),
1063  typeName + "_count",
1064  coordSet(labelList(nLayers_, 1)),
1065  fieldNames
1066  #define TypeFieldValuesParameter(Type, nullArg) \
1067  , Type##FieldValues
1070  );
1071  }
1072 
1073  // Finally, calculate the actual normalised interpolation weights
1074  weights_.reset
1075  (
1076  new List<weight>
1077  (
1078  calcWeights
1079  (
1080  pointXs,
1081  zoneCellMinXs,
1082  zoneCellMaxXs,
1083  zoneCellMinOrder,
1084  plotXs,
1085  true
1086  )
1087  )
1088  );
1089 
1090  // Calculate plot coordinates and widths
1091  if (interpolate_)
1092  {
1093  layerDistances_.reset(new scalarField(plotXs));
1094  }
1095  else
1096  {
1097  const SubField<scalar> distance0s(plotXs, nLayers_);
1098  const SubField<scalar> distance1s(plotXs, nLayers_, 1);
1099  layerDistances_.reset(((distance0s + distance1s)/2).ptr());
1100  layerThicknesses_.reset((distance1s - distance0s).ptr());
1101  }
1102 
1103  // Calculate the plot positions
1104  layerPositions_.reset
1105  (
1106  applyWeights<vector>(weights_, mesh_.C()).ptr()
1107  );
1108 
1109  if (debug)
1110  {
1111  const List<weight> weights =
1112  calcWeights
1113  (
1114  pointXs,
1115  zoneCellMinXs,
1116  zoneCellMaxXs,
1117  zoneCellMinOrder,
1118  plotXs,
1119  false
1120  );
1121 
1123  (
1124  IOobject
1125  (
1126  name() + ":layers",
1127  mesh_.time().name(),
1128  mesh()
1129  ),
1130  mesh(),
1132  );
1133 
1134  forAll(weights, weighti)
1135  {
1136  const weight& w = weights[weighti];
1137 
1138  layers[w.celli][w.layeri % tensor::nComponents] =
1139  w.value/mesh_.V()[w.celli];
1140  }
1141 
1142  Info<< name() << ": Writing " << layers.name() << endl;
1143 
1144  layers.write();
1145  }
1146 }
1147 
1148 
1149 template<class Type>
1151 Foam::functionObjects::cutLayerAverage::applyWeights
1152 (
1153  const List<weight>& weights,
1154  const VolInternalField<Type>& cellValues
1155 ) const
1156 {
1157  tmp<Field<Type>> tLayerValues(new Field<Type>(nLayers_, Zero));
1158 
1159  forAll(weights, weighti)
1160  {
1161  tLayerValues.ref()[weights[weighti].layeri] +=
1162  weights[weighti].value*cellValues[weights[weighti].celli];
1163  }
1164 
1165  Pstream::listCombineGather(tLayerValues.ref(), plusEqOp<Type>());
1166  Pstream::listCombineScatter(tLayerValues.ref());
1167 
1168  return tLayerValues;
1169 }
1170 
1171 
1172 void Foam::functionObjects::cutLayerAverage::clear()
1173 {
1174  weights_.clear();
1175  layerDistances_.clear();
1176  layerThicknesses_.clear();
1177  layerPositions_.clear();
1178 }
1179 
1180 
1181 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
1182 
1184 (
1185  const word& name,
1186  const Time& runTime,
1187  const dictionary& dict
1188 )
1189 :
1190  fvMeshFunctionObject(name, runTime, dict),
1191  zone_(mesh())
1192 {
1193  read(dict);
1194 }
1195 
1196 
1197 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
1198 
1200 {}
1201 
1202 
1203 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
1204 
1206 {
1207  zone_.read(dict);
1208 
1209  const bool haveDirection = dict.found("direction");
1210  const bool haveDistance = dict.found("distance");
1211  if (haveDirection == haveDistance)
1212  {
1214  << "keywords direction and distance both "
1215  << (haveDirection ? "" : "un") << "defined in "
1216  << "dictionary " << dict.name()
1217  << exit(FatalIOError);
1218  }
1219  else if (haveDirection)
1220  {
1221  direction_ = normalised(dict.lookup<vector>("direction"));
1222  distanceName_ = word::null;
1223  }
1224  else if (haveDistance)
1225  {
1226  direction_ = vector::nan;
1227  distanceName_ = dict.lookup<word>("distance");
1228  }
1229 
1230  nLayers_ = dict.lookup<label>("nPoints");
1231 
1232  interpolate_ = dict.lookupOrDefault<bool>("interpolate", false);
1233 
1234  fields_ = dict.lookup<wordList>("fields");
1235 
1236  axis_ =
1238  [
1239  dict.lookupOrDefault<word>
1240  (
1241  "axis",
1243  )
1244  ];
1245 
1246  formatter_ = setWriter::New(dict.lookup("setFormat"), dict);
1247 
1248  nOptimiseIter_ = dict.lookupOrDefault("nOptimiseIter", 2);
1249 
1250  clear();
1251 
1252  return true;
1253 }
1254 
1255 
1257 {
1258  wordList result(fields_);
1259 
1260  if (distanceName_ != word::null)
1261  {
1262  result.append(distanceName_);
1263  }
1264 
1265  return result;
1266 }
1267 
1268 
1270 {
1271  return true;
1272 }
1273 
1274 
1276 {
1277  if (!weights_.valid())
1278  {
1279  calcWeights();
1280  }
1281 
1282  const bool writeThickness =
1283  !interpolate_
1284  && (
1286  || axis_ == coordSet::axisType::DISTANCE
1287  );
1288 
1289  // Create list of field names
1291  if (writeThickness)
1292  {
1293  fieldNames.append("thickness");
1294  }
1295  forAll(fields_, fieldi)
1296  {
1297  if
1298  (
1299  false
1300  #define FoundTypeField(Type, nullArg) \
1301  || foundObject<VolField<Type>>(fields_[fieldi])
1303  #undef FoundTypeField
1304  )
1305  {
1306  fieldNames.append(fields_[fieldi]);
1307  }
1308  else
1309  {
1310  cannotFindObject(fields_[fieldi]);
1311  }
1312  }
1313 
1314  // Calculate the field values
1315  #define DeclareTypeFieldValues(Type, nullArg) \
1316  PtrList<Field<Type>> Type##FieldValues(fieldNames.size());
1318  #undef DeclareTypeFieldValues
1319  if (writeThickness)
1320  {
1321  scalarFieldValues.set(0, new scalarField(layerThicknesses_));
1322  }
1323  for (label fieldi = writeThickness; fieldi < fieldNames.size(); ++ fieldi)
1324  {
1325  #define CollapseTypeFields(Type, GeoField) \
1326  if (mesh_.foundObject<GeoField<Type>>(fieldNames[fieldi])) \
1327  { \
1328  const GeoField<Type>& field = \
1329  mesh_.lookupObject<GeoField<Type>>(fieldNames[fieldi]); \
1330  \
1331  Type##FieldValues.set \
1332  ( \
1333  fieldi, \
1334  applyWeights<Type>(weights_, field) \
1335  ); \
1336  }
1339  #undef CollapseTypeFields
1340  }
1341 
1342  // Write
1343  if (Pstream::master() && layerPositions_->size())
1344  {
1345  mkDir(outputPath());
1346 
1347  formatter_->write
1348  (
1349  outputPath(),
1350  typeName,
1351  coordSet
1352  (
1353  identityMap(layerPositions_->size()),
1354  word::null,
1355  layerPositions_,
1357  layerDistances_,
1359  ),
1360  fieldNames
1361  #define TypeFieldValuesParameter(Type, nullArg) , Type##FieldValues
1364  );
1365  }
1366 
1367  return true;
1368 }
1369 
1370 
1372 (
1373  const polyMesh& mesh
1374 )
1375 {
1376  if (&mesh == &mesh_)
1377  {
1378  zone_.movePoints();
1379  clear();
1380  }
1381 }
1382 
1383 
1385 (
1386  const polyTopoChangeMap& map
1387 )
1388 {
1389  if (&map.mesh() == &mesh_)
1390  {
1391  zone_.topoChange(map);
1392  clear();
1393  }
1394 }
1395 
1396 
1398 (
1399  const polyMeshMap& map
1400 )
1401 {
1402  if (&map.mesh() == &mesh_)
1403  {
1404  zone_.mapMesh(map);
1405  clear();
1406  }
1407 }
1408 
1409 
1411 (
1412  const polyDistributionMap& map
1413 )
1414 {
1415  if (&map.mesh() == &mesh_)
1416  {
1417  zone_.distribute(map);
1418  clear();
1419  }
1420 }
1421 
1422 
1423 // ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
Macros for easy insertion into run-time selection tables.
static cellEdgeAddressingList & New(const word &name, const polyMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
Pre-declare SubField and related Field type.
Definition: Field.H:83
Generic GeometricField class.
DimensionedField< Type, GeoMesh, PrimitiveField > Internal
Type of the internal field from which this GeometricField is derived.
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
void resize(const label)
Alias for setSize(const label)
Definition: ListI.H:138
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
virtual Ostream & write(const char)=0
Write character.
An ordered pair of two objects of type <Type> with first() and second() elements.
Definition: Pair.H:66
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: PtrList.H:75
bool set(const label) const
Is element set.
Definition: PtrListI.H:62
fileName globalPath() const
Return the global path.
Definition: TimePaths.H:132
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
A 2-tuple for storing two objects of different types.
Definition: Tuple2.H:66
const Type2 & second() const
Return second.
Definition: Tuple2.H:131
const Type1 & first() const
Return first.
Definition: Tuple2.H:119
A List with indirect addressing.
Definition: UIndirectList.H:60
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
static const direction nComponents
Number of components in this vector space.
Definition: VectorSpace.H:105
static const Form nan
Definition: VectorSpace.H:124
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
Holds list of sampling positions.
Definition: coordSet.H:51
static const NamedEnum< axisType, 6 > axisTypeNames_
String representation of axis enums.
Definition: coordSet.H:69
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
const word & name() const
Return const reference to name.
Class to manage face cut data.
const Pair< vectorField > & faceCutAreas(const label layeri) const
const List< List< labelPair > > & faceCuts(const label layeri) const
void cache(const label celli, const label layeri)
faceCutData(const fvMesh &mesh, const label nActiveLayers, const scalarField &pointXs, const scalarField &plotXs)
Base class for classes which manage incomplete sets of face data.
const scalarField & pointXs_
const pointField & points_
PtrList< DynamicList< label > > faceis_
const faceList & faces_
void clear(const label layeri)
label activeLayeri(const label layeri) const
const scalarField & plotXs_
const pointField & faceCentres_
const cellEdgeAddressingList & cAddrs_
PtrList< boolList > haveFaces_
const scalarField & cellVolumes_
faceData(const fvMesh &mesh, const label nActiveLayers, const scalarField &pointXs, const scalarField &plotXs)
const cellList & cells_
const vectorField & faceAreas_
Class to manage face basis function data.
void cache(const label celli, const label layeri)
const Pair< scalarField > & faceFs(const label layeri) const
faceFsData(const faceCutData &fcd, const fvMesh &mesh, const label nActiveLayers, const scalarField &pointXs, const scalarField &plotXs)
const Pair< scalarField > & pointFs(const label layeri) const
const Pair< Pair< scalarField > > & faceCutFs(const label layeri) const
A class for handling file names.
Definition: fileName.H:82
Abstract base-class for Time/database functionObjects.
const Time & time_
Reference to time.
const word & name() const
Return the name of this functionObject.
This function object writes graphs of cell values, volume-averaged in planes perpendicular to a given...
virtual wordList fields() const
Return the list of fields required.
virtual void topoChange(const polyTopoChangeMap &)
Update topology using the given map.
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
virtual void movePoints(const polyMesh &)
Update for mesh point-motion.
cutLayerAverage(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
virtual bool execute()
Execute, currently does nothing.
virtual bool write()
Write the cutLayerAverage.
virtual bool read(const dictionary &)
Read the cutLayerAverage data.
Specialisation of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
const fvMesh & mesh_
Reference to the fvMesh.
static const word outputPrefix
Directory prefix.
Definition: writeFile.H:72
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:96
const word & name() const
Return reference to name.
Definition: fvMesh.H:434
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
const polyMesh & mesh() const
Return polyMesh.
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
const polyMesh & mesh() const
Return polyMesh.
Definition: polyMeshMap.H:75
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:270
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const polyMesh & mesh() const
Return polyMesh.
label nPoints() const
label nFaces() const
static autoPtr< setWriter > New(const word &writeType, const IOstream::streamFormat writeFormat=IOstream::ASCII, const IOstream::compressionType writeCompression=IOstream::UNCOMPRESSED)
Select given write options.
Definition: setWriter.C:286
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define TypeFieldValuesParameter(Type, nullArg)
#define CollapseTypeFields(Type, GeoField)
#define FoundTypeField(Type, nullArg)
#define DeclareTypeFieldValues(Type, nullArg)
#define ResizeTypeFieldValues(Type, nullArg)
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
static List< word > fieldNames
Definition: globalFoam.H:46
const pointField & points
const cellShapeList & cells
tUEqn clear()
Tuple2< vector, std::tuple< AreaIntegralType< Types > ... > > faceCutAreaIntegral(const face &f, const vector &fArea, const std::tuple< Types ... > &fPsis, const List< labelPair > &fCuts, const pointField &ps, const std::tuple< const Field< Types > &... > &pPsis, const scalarField &pAlphas, const scalar isoAlpha, const bool below)
Compute the face-cut-area and face-cut-area-integral of the given properties.
vector faceCutArea(const face &f, const vector &fArea, const List< labelPair > &fCuts, const pointField &ps, const scalarField &pAlphas, const scalar isoAlpha, const bool below)
Compute the face-cut-area.
Tuple2< scalar, std::tuple< Types ... > > cellCutVolumeIntegral(const cell &c, const cellEdgeAddressing &cAddr, const scalar cVolume, const std::tuple< Types ... > &cPsis, const labelListList &cCuts, const faceUList &fs, const vectorField &fAreas, const pointField &fCentres, const std::tuple< const Field< Types > &... > &fPsis, const vectorField &fCutAreas, const std::tuple< const Field< Types > &... > &fCutPsis, const pointField &ps, const std::tuple< const Field< Types > &... > &pPsis, const scalarField &pAlphas, const scalar isoAlpha, const bool below)
Compute the cell-cut-volume and cell-cut-volume-integral.
Tuple2< scalar, std::tuple< Types ... > > cellVolumeIntegral(const cell &c, const cellEdgeAddressing &cAddr, const point &cPAvg, const std::tuple< Types ... > &cPsiAvgs, const vectorField &fAreas, const pointField &fCentres, const std::tuple< const Field< Types > &... > &fPsis)
Compute the cell-volume and cell-volume-integrals of the given properties.
Tuple2< vector, std::tuple< Types ... > > faceAreaAverage(const FaceValues< point > &fPs, const point &fPAvg, const std::tuple< FaceValues< Types > ... > &fPsis, const std::tuple< Types ... > &fPsiAvgs)
Compute the face-area and face-area-averages of the given properties.
List< labelPair > faceCuts(const face &f, const scalarField &pAlphas, const scalar isoAlpha)
Return the cuts for a given face. This returns a list of pairs of.
Definition: cutPoly.C:61
labelListList cellCuts(const cell &c, const cellEdgeAddressing &cAddr, const faceUList &fs, const List< List< labelPair >> &fCuts, const scalarField &pAlphas, const scalar isoAlpha)
Return the cuts for a given cell. This returns a list of lists of cell-edge.
Definition: cutPoly.C:121
scalar cellCutVolume(const cell &c, const cellEdgeAddressing &cAddr, const scalar cVolume, const labelListList &cCuts, const faceUList &fs, const vectorField &fAreas, const pointField &fCentres, const vectorField &fCutAreas, const pointField &ps, const scalarField &pAlphas, const scalar isoAlpha, const bool below)
Compute the cell-cut-volume.
defineTypeNameAndDebug(adjustTimeStepToCombustion, 0)
addToRunTimeSelectionTable(functionObject, adjustTimeStepToCombustion, dictionary)
static tmp< SurfaceField< Type > > interpolate(const VolField< Type > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static const zero Zero
Definition: zero.H:97
List< word > wordList
A List of words.
Definition: fileName.H:54
dimensioned< tensor > dimensionedTensor
Dimensioned tensor obtained from generic dimensioned type.
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:290
List< cell > cellList
list of cells
Definition: cellList.H:42
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:258
autoPtr< Pair< Field< Type > > > fieldPairPtr(const label size)
Allocate and return a pair of fields.
const dimensionSet dimless
messageStream Info
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
autoPtr< Pair< Pair< Field< Type > > > > fieldPairPairPtr(const label size)
Allocate and return a pair of a pair of fields.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
PointField< scalar > pointScalarField
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:62
dimensionSet normalised(const dimensionSet &)
Definition: dimensionSet.C:507
typename VolField< Type >::Internal VolInternalField
Definition: volFieldsFwd.H:59
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
Field< vector > vectorField
Specialisation of Field<T> for vector.
IOerror FatalIOError
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
FOR_ALL_FIELD_TYPES(makeFieldSourceTypedef)
void magSqr(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
Type gMin(const FieldField< Field, Type > &f)
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
void sortedOrder(const UList< T > &, labelList &order)
Generate the (stable) sort order for the list.
quaternion normalise(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
Definition: quaternionI.H:603
List< face > faceList
Definition: faceListFwd.H:41
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
Type gMax(const FieldField< Field, Type > &f)
labelList f(nPoints)
dictionary dict
const scalar xMin
Definition: createFields.H:29
const scalar xMax
Definition: createFields.H:30