meshToMesh0.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) 2011-2026 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 "meshToMesh0.H"
27 #include "processorFvPatch.H"
28 #include "demandDrivenData.H"
29 #include "meshSearch.H"
30 #include "treeDataFace.H"
31 #include "tetOverlapVolume.H"
32 #include "pointInCell.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38  defineTypeNameAndDebug(meshToMesh0, 0);
39 }
40 
41 
42 const Foam::scalar Foam::meshToMesh0::directHitTol = 1e-5;
43 
44 
45 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
46 
47 void Foam::meshToMesh0::calcAddressing()
48 {
49  if (debug)
50  {
52  << "Calculating mesh-to-mesh cell addressing" << endl;
53  }
54 
55  // Set reference to cells
56  const cellList& fromCells = fromMesh_.cells();
57  const pointField& fromPoints = fromMesh_.points();
58 
59  // In an attempt to preserve the efficiency of linear search and prevent
60  // failure, a RESCUE mechanism will be set up. Here, we shall mark all
61  // cells next to the solid boundaries. If such a cell is found as the
62  // closest, the relationship between the origin and cell will be examined.
63  // If the origin is outside the cell, a global n-squared search is
64  // triggered.
65 
66  // SETTING UP RESCUE
67 
68  // Visit all boundaries and mark the cell next to the boundary.
69 
70  if (debug)
71  {
72  InfoInFunction << "Setting up rescue" << endl;
73  }
74 
75  List<bool> boundaryCell(fromCells.size(), false);
76 
77  // Set reference to boundary
78  const polyPatchList& patchesFrom = fromMesh_.poly().boundary();
79 
80  forAll(patchesFrom, patchi)
81  {
82  // Get reference to cells next to the boundary
83  const labelUList& bCells = patchesFrom[patchi].faceCells();
84 
85  forAll(bCells, facei)
86  {
87  boundaryCell[bCells[facei]] = true;
88  }
89  }
90 
91  treeBoundBox meshBb(fromPoints);
92 
93  scalar typDim = meshBb.avgDim()/(2.0*cbrt(scalar(fromCells.size())));
94 
95  treeBoundBox shiftedBb
96  (
97  meshBb.min(),
98  meshBb.max() + vector(typDim, typDim, typDim)
99  );
100 
101  if (debug)
102  {
103  Info<< "\nMesh\n"
104  << " bounding box : " << meshBb << nl
105  << " bounding box (shifted) : " << shiftedBb << nl
106  << " typical dimension :" << shiftedBb.typDim() << endl;
107  }
108 
109  indexedOctree<treeDataCell> oc
110  (
111  treeDataCell(false, fromMesh_),
112  shiftedBb, // overall bounding box
113  8, // maxLevel
114  10, // leafsize
115  6.0 // duplicity
116  );
117 
118  if (debug)
119  {
120  oc.print(Pout, false, 0);
121  }
122 
123  cellAddresses
124  (
125  cellAddressing_,
126  toMesh_.cellCentres(),
127  fromMesh_,
128  boundaryCell,
129  oc
130  );
131 
132  forAll(toMesh_.poly().boundary(), patchi)
133  {
134  const polyPatch& toPatch = toMesh_.poly().boundary()[patchi];
135 
136  if (cuttingPatches_.found(toPatch.name()))
137  {
138  boundaryAddressing_[patchi].setSize(toPatch.size());
139 
140  cellAddresses
141  (
142  boundaryAddressing_[patchi],
143  toPatch.faceCentres(),
144  fromMesh_,
145  boundaryCell,
146  oc
147  );
148  }
149  else if
150  (
151  patchMap_.found(toPatch.name())
152  && fromMeshPatches_.found(patchMap_.find(toPatch.name())())
153  )
154  {
155  const polyPatch& fromPatch = fromMesh_.poly().boundary()
156  [
157  fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
158  ];
159 
160  if (fromPatch.empty())
161  {
163  << "Source patch " << fromPatch.name()
164  << " has no faces. Not performing mapping for it."
165  << endl;
166  boundaryAddressing_[patchi].setSize(toPatch.size());
167  boundaryAddressing_[patchi] = -1;
168  }
169  else
170  {
171  treeBoundBox wallBb(fromPatch.localPoints());
172  scalar typDim =
173  wallBb.avgDim()/(2.0*sqrt(scalar(fromPatch.size())));
174 
175  treeBoundBox shiftedBb
176  (
177  wallBb.min(),
178  wallBb.max() + vector(typDim, typDim, typDim)
179  );
180 
181  // Note: Allow more levels than in meshBoundarySearch. Assume
182  // patch is not as big as all boundary faces.
183  indexedOctree<treeDataFace> oc
184  (
185  treeDataFace(false, fromPatch),
186  shiftedBb, // overall search domain
187  12, // maxLevel
188  10, // leafsize
189  6.0 // duplicity
190  );
191 
192  const vectorField::subField centresToBoundary =
193  toPatch.faceCentres();
194 
195  boundaryAddressing_[patchi].setSize(toPatch.size());
196 
197  const scalar distSqr = sqr(wallBb.mag());
198 
199  forAll(toPatch, toi)
200  {
201  boundaryAddressing_[patchi][toi] = oc.findNearest
202  (
203  centresToBoundary[toi],
204  distSqr
205  ).index();
206  }
207  }
208  }
209  }
210 
211  if (debug)
212  {
214  << "Finished calculating mesh-to-mesh cell addressing" << endl;
215  }
216 }
217 
218 
219 void Foam::meshToMesh0::cellAddresses
220 (
221  labelList& cellAddressing_,
222  const pointField& points,
223  const fvMesh& fromMesh,
224  const List<bool>& boundaryCell,
225  const indexedOctree<treeDataCell>& oc
226 ) const
227 {
228  // The implemented search method is a simple neighbour array search.
229  // It starts from a cell zero, searches its neighbours and finds one
230  // which is nearer to the target point than the current position.
231  // The location of the "current position" is reset to that cell and
232  // search through the neighbours continues. The search is finished
233  // when all the neighbours of the cell are farther from the target
234  // point than the current cell
235 
236  // Set curCell label to zero (start)
237  label curCell = 0;
238 
239  // Set reference to cell to cell addressing
240  const vectorField& centresFrom = fromMesh.cellCentres();
241  const labelListList& cc = fromMesh.cellCells();
242 
243  forAll(points, toi)
244  {
245  // Pick up target position
246  const vector& p = points[toi];
247 
248  // Set the sqr-distance
249  scalar distSqr = magSqr(p - centresFrom[curCell]);
250 
251  bool closer;
252 
253  do
254  {
255  closer = false;
256 
257  // Set the current list of neighbouring cells
258  const labelList& neighbours = cc[curCell];
259 
260  forAll(neighbours, ni)
261  {
262  const scalar curDistSqr =
263  magSqr(p - centresFrom[neighbours[ni]]);
264 
265  // Search through all the neighbours.
266  // If the cell is closer, reset current cell and distance
267  if (curDistSqr < (1 - small)*distSqr)
268  {
269  curCell = neighbours[ni];
270  distSqr = curDistSqr;
271  closer = true; // A closer neighbour has been found
272  }
273  }
274  } while (closer);
275 
276  cellAddressing_[toi] = -1;
277 
278  // Check point is actually in the nearest cell
279  if (pointInCell(p, fromMesh, curCell))
280  {
281  cellAddressing_[toi] = curCell;
282  }
283  else
284  {
285  // If curCell is a boundary cell then the point maybe either outside
286  // the domain or in an other region of the domain, either way use
287  // the octree search to find it.
288  if (boundaryCell[curCell])
289  {
290  cellAddressing_[toi] =
291  oc.findInside(p, pointInCellShapes::tets);
292 
293  if (cellAddressing_[toi] != -1)
294  {
295  curCell = cellAddressing_[toi];
296  }
297  }
298  else
299  {
300  // If not on the boundary search the neighbours
301  bool found = false;
302 
303  // Set the current list of neighbouring cells
304  const labelList& neighbours = cc[curCell];
305 
306  forAll(neighbours, ni)
307  {
308  // Search through all the neighbours.
309  // If point is in neighbour reset current cell
310  if (pointInCell(p, fromMesh, neighbours[ni]))
311  {
312  cellAddressing_[toi] = neighbours[ni];
313  found = true;
314  break;
315  }
316  }
317 
318  if (!found)
319  {
320  // If still not found search the neighbour-neighbours
321 
322  // Set the current list of neighbouring cells
323  const labelList& neighbours = cc[curCell];
324 
325  forAll(neighbours, ni)
326  {
327  // Set the current list of neighbour-neighbouring cells
328  const labelList& nn = cc[neighbours[ni]];
329 
330  forAll(nn, ni)
331  {
332  // Search through all the neighbours.
333  // If point is in neighbour reset current cell
334  if (pointInCell(p, fromMesh, nn[ni]))
335  {
336  cellAddressing_[toi] = nn[ni];
337  found = true;
338  break;
339  }
340  }
341  if (found) break;
342  }
343  }
344 
345  if (!found)
346  {
347  // Still not found so use the octree
348  cellAddressing_[toi] =
349  oc.findInside(p, pointInCellShapes::tets);
350 
351  if (cellAddressing_[toi] != -1)
352  {
353  curCell = cellAddressing_[toi];
354  }
355  }
356  }
357  }
358  }
359 }
360 
361 
362 void Foam::meshToMesh0::calculateInverseDistanceWeights() const
363 {
364  if (debug)
365  {
367  << "Calculating inverse distance weighting factors" << endl;
368  }
369 
370  if (inverseDistanceWeightsPtr_)
371  {
373  << "weighting factors already calculated"
374  << exit(FatalError);
375  }
376 
377  //- Initialise overlap volume to zero
378  V_ = 0.0;
379 
380  inverseDistanceWeightsPtr_ = new scalarListList(toMesh_.nCells());
381  scalarListList& invDistCoeffs = *inverseDistanceWeightsPtr_;
382 
383  // get reference to source mesh data
384  const labelListList& cc = fromMesh_.cellCells();
385  const vectorField& centreFrom = fromMesh_.C();
386  const vectorField& centreTo = toMesh_.C();
387 
388  forAll(cellAddressing_, celli)
389  {
390  if (cellAddressing_[celli] != -1)
391  {
392  const vector& target = centreTo[celli];
393  scalar m = mag(target - centreFrom[cellAddressing_[celli]]);
394 
395  const labelList& neighbours = cc[cellAddressing_[celli]];
396 
397  // if the nearest cell is a boundary cell or there is a direct hit,
398  // pick up the value
399  label directCelli = -1;
400  if (m < directHitTol || neighbours.empty())
401  {
402  directCelli = celli;
403  }
404  else
405  {
406  forAll(neighbours, ni)
407  {
408  scalar nm = mag(target - centreFrom[neighbours[ni]]);
409  if (nm < directHitTol)
410  {
411  directCelli = neighbours[ni];
412  break;
413  }
414  }
415  }
416 
417 
418  if (directCelli != -1)
419  {
420  // Direct hit
421  invDistCoeffs[directCelli].setSize(1);
422  invDistCoeffs[directCelli][0] = 1.0;
423  V_ += fromMesh_.V()[cellAddressing_[directCelli]];
424  }
425  else
426  {
427  invDistCoeffs[celli].setSize(neighbours.size() + 1);
428 
429  // The first coefficient corresponds to the centre cell.
430  // The rest is ordered in the same way as the cellCells list.
431  scalar invDist = 1.0/m;
432  invDistCoeffs[celli][0] = invDist;
433  scalar sumInvDist = invDist;
434 
435  // now add the neighbours
436  forAll(neighbours, ni)
437  {
438  invDist = 1.0/mag(target - centreFrom[neighbours[ni]]);
439  invDistCoeffs[celli][ni + 1] = invDist;
440  sumInvDist += invDist;
441  }
442 
443  // divide by the total inverse-distance
444  forAll(invDistCoeffs[celli], i)
445  {
446  invDistCoeffs[celli][i] /= sumInvDist;
447  }
448 
449 
450  V_ +=
451  invDistCoeffs[celli][0]
452  *fromMesh_.V()[cellAddressing_[celli]];
453  for (label i = 1; i < invDistCoeffs[celli].size(); i++)
454  {
455  V_ +=
456  invDistCoeffs[celli][i]*fromMesh_.V()[neighbours[i-1]];
457  }
458  }
459  }
460  }
461 }
462 
463 
464 void Foam::meshToMesh0::calculateInverseVolumeWeights() const
465 {
466  if (debug)
467  {
469  << "Calculating inverse volume weighting factors" << endl;
470  }
471 
472  if (inverseVolumeWeightsPtr_)
473  {
475  << "weighting factors already calculated"
476  << exit(FatalError);
477  }
478 
479  //- Initialise overlap volume to zero
480  V_ = 0.0;
481 
482  inverseVolumeWeightsPtr_ = new scalarListList(toMesh_.nCells());
483  scalarListList& invVolCoeffs = *inverseVolumeWeightsPtr_;
484 
485  const labelListList& cellToCell = cellToCellAddressing();
486 
487  tetOverlapVolume overlapEngine;
488 
489  forAll(cellToCell, celli)
490  {
491  const labelList& overlapCells = cellToCell[celli];
492 
493  if (overlapCells.size() > 0)
494  {
495  invVolCoeffs[celli].setSize(overlapCells.size());
496 
497  forAll(overlapCells, j)
498  {
499  label cellFrom = overlapCells[j];
500  treeBoundBox bbFromMesh
501  (
502  pointField
503  (
504  fromMesh_.points(),
505  fromMesh_.cellPoints()[cellFrom]
506  )
507  );
508 
509  scalar v = overlapEngine.cellCellOverlapVolumeMinDecomp
510  (
511  toMesh_,
512  celli,
513 
514  fromMesh_,
515  cellFrom,
516  bbFromMesh
517  );
518  invVolCoeffs[celli][j] = v/toMesh_.V()[celli];
519 
520  V_ += v;
521  }
522  }
523  }
524 }
525 
526 
527 void Foam::meshToMesh0::calculateCellToCellAddressing() const
528 {
529  if (debug)
530  {
532  << "Calculating cell to cell addressing" << endl;
533  }
534 
535  if (cellToCellAddressingPtr_)
536  {
538  << "addressing already calculated"
539  << exit(FatalError);
540  }
541 
542  const meshSearch& fromSearchEngine = meshSearch::New(fromMesh_);
543 
544  //- Initialise overlap volume to zero
545  V_ = 0.0;
546 
547  cellToCellAddressingPtr_ = new labelListList(toMesh_.nCells());
548  labelListList& cellToCell = *cellToCellAddressingPtr_;
549 
550  forAll(cellToCell, iTo)
551  {
552  const labelList overLapCells =
553  fromSearchEngine.cellTree().findBox
554  (
555  treeBoundBox(toMesh_.points(), toMesh_.cellPoints()[iTo])
556  );
557 
558  if (overLapCells.size() > 0)
559  {
560  cellToCell[iTo].setSize(overLapCells.size());
561  forAll(overLapCells, j)
562  {
563  cellToCell[iTo][j] = overLapCells[j];
564  V_ += fromMesh_.V()[overLapCells[j]];
565  }
566  }
567  }
568 }
569 
570 
571 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
572 
574 (
575  const fvMesh& meshFrom,
576  const fvMesh& meshTo,
577  const HashTable<word>& patchMap,
578  const wordList& cuttingPatchNames
579 )
580 :
581  fromMesh_(meshFrom),
582  toMesh_(meshTo),
583  patchMap_(patchMap),
584  cellAddressing_(toMesh_.nCells()),
585  boundaryAddressing_(toMesh_.poly().boundary().size()),
586  inverseDistanceWeightsPtr_(nullptr),
587  inverseVolumeWeightsPtr_(nullptr),
588  cellToCellAddressingPtr_(nullptr),
589  V_(0.0)
590 {
591  forAll(fromMesh_.poly().boundary(), patchi)
592  {
593  fromMeshPatches_.insert
594  (
595  fromMesh_.poly().boundary()[patchi].name(),
596  patchi
597  );
598  }
599 
600  forAll(toMesh_.poly().boundary(), patchi)
601  {
602  toMeshPatches_.insert
603  (
604  toMesh_.poly().boundary()[patchi].name(),
605  patchi
606  );
607  }
608 
609  forAll(cuttingPatchNames, i)
610  {
611  if (toMeshPatches_.found(cuttingPatchNames[i]))
612  {
613  cuttingPatches_.insert
614  (
615  cuttingPatchNames[i],
616  toMeshPatches_.find(cuttingPatchNames[i])()
617  );
618  }
619  else
620  {
622  << "Cannot find cutting-patch " << cuttingPatchNames[i]
623  << " in destination mesh" << endl;
624  }
625  }
626 
627  forAll(toMesh_.poly().boundary(), patchi)
628  {
629  // Add the processor patches in the toMesh to the cuttingPatches list
630  if (isA<processorPolyPatch>(toMesh_.poly().boundary()[patchi]))
631  {
632  cuttingPatches_.insert
633  (
634  toMesh_.poly().boundary()[patchi].name(),
635  patchi
636  );
637  }
638  }
639 
640  calcAddressing();
641 }
642 
643 
645 (
646  const fvMesh& meshFrom,
647  const fvMesh& meshTo
648 )
649 :
650  fromMesh_(meshFrom),
651  toMesh_(meshTo),
652  cellAddressing_(toMesh_.nCells()),
653  boundaryAddressing_(toMesh_.poly().boundary().size()),
654  inverseDistanceWeightsPtr_(nullptr),
655  inverseVolumeWeightsPtr_(nullptr),
656  cellToCellAddressingPtr_(nullptr),
657  V_(0.0)
658 {
659  // check whether both meshes have got the same number
660  // of boundary patches
661  if (fromMesh_.boundary().size() != toMesh_.boundary().size())
662  {
664  << "Incompatible meshes: different number of patches, "
665  << "fromMesh = " << fromMesh_.boundary().size()
666  << ", toMesh = " << toMesh_.boundary().size()
667  << exit(FatalError);
668  }
669 
670  forAll(fromMesh_.poly().boundary(), patchi)
671  {
672  if
673  (
674  fromMesh_.poly().boundary()[patchi].name()
675  != toMesh_.poly().boundary()[patchi].name()
676  )
677  {
679  << "Incompatible meshes: different patch names for patch "
680  << patchi
681  << ", fromMesh = " << fromMesh_.boundary()[patchi].name()
682  << ", toMesh = " << toMesh_.boundary()[patchi].name()
683  << exit(FatalError);
684  }
685 
686  if
687  (
688  fromMesh_.poly().boundary()[patchi].type()
689  != toMesh_.poly().boundary()[patchi].type()
690  )
691  {
693  << "Incompatible meshes: different patch types for patch "
694  << patchi
695  << ", fromMesh = " << fromMesh_.boundary()[patchi].type()
696  << ", toMesh = " << toMesh_.boundary()[patchi].type()
697  << exit(FatalError);
698  }
699 
700  fromMeshPatches_.insert
701  (
702  fromMesh_.poly().boundary()[patchi].name(),
703  patchi
704  );
705 
706  toMeshPatches_.insert
707  (
708  toMesh_.poly().boundary()[patchi].name(),
709  patchi
710  );
711 
712  patchMap_.insert
713  (
714  toMesh_.poly().boundary()[patchi].name(),
715  fromMesh_.poly().boundary()[patchi].name()
716  );
717  }
718 
719  calcAddressing();
720 }
721 
722 
723 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
724 
726 {
727  deleteDemandDrivenData(inverseDistanceWeightsPtr_);
728  deleteDemandDrivenData(inverseVolumeWeightsPtr_);
729  deleteDemandDrivenData(cellToCellAddressingPtr_);
730 }
731 
732 
733 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
734 
735 const Foam::scalarListList& Foam::meshToMesh0::inverseDistanceWeights() const
736 {
737  if (!inverseDistanceWeightsPtr_)
738  {
739  calculateInverseDistanceWeights();
740  }
741 
742  return *inverseDistanceWeightsPtr_;
743 }
744 
745 
746 const Foam::scalarListList& Foam::meshToMesh0::inverseVolumeWeights() const
747 {
748  if (!inverseVolumeWeightsPtr_)
749  {
750  calculateInverseVolumeWeights();
751  }
752 
753  return *inverseVolumeWeightsPtr_;
754 }
755 
756 
757 const Foam::labelListList& Foam::meshToMesh0::cellToCellAddressing() const
758 {
759  if (!cellToCellAddressingPtr_)
760  {
761  calculateCellToCellAddressing();
762  }
763 
764  return *cellToCellAddressingPtr_;
765 }
766 
767 
768 // ************************************************************************* //
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
SubField< vector > subField
Declare type of subField.
Definition: Field.H:101
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:167
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:138
void setSize(const label)
Reset size of List.
Definition: List.C:281
const polyMesh & poly() const
Return reference to polyMesh.
Definition: fvMesh.H:456
static const meshSearch & New(const polyMesh &mesh, const pointInCellShapes=pointInCellShapes::tets)
Lookup or construct from mesh and cell decomposition option.
Definition: meshSearch.C:61
meshToMesh0(const fvMesh &fromMesh, const fvMesh &toMesh, const HashTable< word > &patchMap, const wordList &cuttingPatchNames)
Construct from the two meshes, the patch name map for the patches.
~meshToMesh0()
Destructor.
Motion of the mesh specified as a list of pointMeshMovers.
const polyBoundaryMesh & boundary() const
Return boundary mesh.
Definition: polyMesh.H:393
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1295
const vectorField & cellCentres() const
const cellList & cells() const
Template functions to aid in the implementation of demand driven data.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
label patchi
const pointField & points
#define WarningInFunction
Report a warning using Foam::Warning.
#define InfoInFunction
Report an information message using Foam::Info.
const dimensionedScalar e
Elementary charge.
Namespace for OpenFOAM.
List< scalarList > scalarListList
Definition: scalarList.H:51
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
List< word > wordList
A List of words.
Definition: fileName.H:54
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
List< cell > cellList
list of cells
Definition: cellList.H:42
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
void deleteDemandDrivenData(DataType *&dataPtr)
messageStream Info
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
PtrList< polyPatch > polyPatchList
container classes for polyPatch
Definition: polyPatchList.H:45
Field< vector > vectorField
Specialisation of Field<T> for vector.
void cbrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
error FatalError
void sqrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
bool pointInCell(const point &p, const polyMesh &mesh, const label celli, const pointInCellShapes=pointInCellShapes::tets)
Test if a point is in a given cell.
Definition: pointInCell.C:155
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
UList< label > labelUList
Definition: UList.H:65
static const char nl
Definition: Ostream.H:297
Function for determining if a point is within a cell of a polyMesh.
faceListList boundary(nPatches)
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(1e-3))
volScalarField & p