controlMeshRefinement.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) 2013-2015 OpenFOAM Foundation
9  Copyright (C) 2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "controlMeshRefinement.H"
31 #include "OFstream.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  defineTypeNameAndDebug(controlMeshRefinement, 0);
38 }
39 
40 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
41 
42 
43 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
44 
45 Foam::scalar Foam::controlMeshRefinement::calcFirstDerivative
46 (
47  const Foam::point& a,
48  const scalar& cellSizeA,
49  const Foam::point& b,
50  const scalar& cellSizeB
51 ) const
52 {
53  return (cellSizeA - cellSizeB)/mag(a - b);
54 }
55 
56 
57 //Foam::scalar Foam::controlMeshRefinement::calcSecondDerivative
58 //(
59 // const Foam::point& a,
60 // const scalar& cellSizeA,
61 // const Foam::point& midPoint,
62 // const scalar& cellSizeMid,
63 // const Foam::point& b,
64 // const scalar& cellSizeB
65 //) const
66 //{
67 // return (cellSizeA - 2*cellSizeMid + cellSizeB)/magSqr((a - b)/2);
68 //}
69 
70 
71 bool Foam::controlMeshRefinement::detectEdge
72 (
73  const Foam::point& startPt,
74  const Foam::point& endPt,
75  pointHit& pointFound,
76  const scalar tolSqr,
77  const scalar secondDerivTolSqr
78 ) const
79 {
80  Foam::point a(startPt);
81  Foam::point b(endPt);
82 
83  Foam::point midPoint = (a + b)/2.0;
84 
85  //label nIterations = 0;
86 
87  while (true)
88  {
89  //++nIterations;
90 
91  if
92  (
93  magSqr(a - b) < tolSqr
94  )
95  {
96  pointFound.hitPoint(midPoint);
97  return true;
98  }
99 
100  // Split into two regions
101 
102  scalar cellSizeA = sizeControls_.cellSize(a);
103  scalar cellSizeB = sizeControls_.cellSize(b);
104 
105 // if (magSqr(cellSizeA - cellSizeB) < 1e-6)
106 // {
107 // return false;
108 // }
109 
110  scalar cellSizeMid = sizeControls_.cellSize(midPoint);
111 
112  // Region 1
113  Foam::point midPoint1 = (a + midPoint)/2.0;
114  const scalar cellSizeMid1 = sizeControls_.cellSize(midPoint1);
115 
116 // scalar firstDerivative1 =
117 // calcFirstDerivative(cellSizeA, cellSizeMid);
118 
119  scalar secondDerivative1 =
120  calcSecondDerivative
121  (
122  a,
123  cellSizeA,
124  midPoint1,
125  cellSizeMid1,
126  midPoint,
127  cellSizeMid
128  );
129 
130  // Region 2
131  Foam::point midPoint2 = (midPoint + b)/2.0;
132  const scalar cellSizeMid2 = sizeControls_.cellSize(midPoint2);
133 
134 // scalar firstDerivative2 =
135 // calcFirstDerivative(f, cellSizeMid, cellSizeB);
136 
137  scalar secondDerivative2 =
138  calcSecondDerivative
139  (
140  midPoint,
141  cellSizeMid,
142  midPoint2,
143  cellSizeMid2,
144  b,
145  cellSizeB
146  );
147 
148  // Neither region appears to have an inflection
149  // To be sure should use higher order derivatives
150  if
151  (
152  magSqr(secondDerivative1) < secondDerivTolSqr
153  && magSqr(secondDerivative2) < secondDerivTolSqr
154  )
155  {
156  return false;
157  }
158 
159  // Pick region with greatest second derivative
160  if (magSqr(secondDerivative1) > magSqr(secondDerivative2))
161  {
162  b = midPoint;
163  midPoint = midPoint1;
164  }
165  else
166  {
167  a = midPoint;
168  midPoint = midPoint2;
169  }
170  }
171 }
172 
173 
174 Foam::pointHit Foam::controlMeshRefinement::findDiscontinuities
175 (
176  const linePointRef& l
177 ) const
178 {
180 
181  const scalar tolSqr = sqr(1e-3);
182  const scalar secondDerivTolSqr = sqr(1e-3);
183 
184  detectEdge
185  (
186  l.start(),
187  l.end(),
188  p,
189  tolSqr,
190  secondDerivTolSqr
191  );
192 
193  return p;
194 }
195 
196 
197 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
198 
199 
200 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
201 
202 Foam::controlMeshRefinement::controlMeshRefinement
203 (
204  cellShapeControl& shapeController
205 )
206 :
207  shapeController_(shapeController),
208  mesh_(shapeController.shapeControlMesh()),
209  sizeControls_(shapeController.sizeAndAlignment()),
210  geometryToConformTo_(sizeControls_.geometryToConformTo())
211 {}
212 
213 
214 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
215 
217 {}
218 
219 
220 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
221 
223 (
224  const autoPtr<backgroundMeshDecomposition>& decomposition
225 )
226 {
227  if (shapeController_.shapeControlMesh().vertexCount() > 0)
228  {
229  // Mesh already populated.
230  Info<< "Cell size and alignment mesh already populated." << endl;
231  return;
232  }
233 
234  autoPtr<boundBox> overallBoundBox;
235 
236  // Need to pass in the background mesh decomposition so that can test if
237  // a point to insert is on the processor.
238  if (Pstream::parRun())
239  {
240 // overallBoundBox.set(new boundBox(decomposition().procBounds()));
241  }
242  else
243  {
244 // overallBoundBox.set
245 // (
246 // new boundBox(geometryToConformTo_.geometry().bounds())
247 // );
248 //
249 // mesh_.insertBoundingPoints
250 // (
251 // overallBoundBox(),
252 // sizeControls_
253 // );
254  }
255 
256  Map<label> priorityMap;
257 
258  const PtrList<cellSizeAndAlignmentControl>& controlFunctions =
259  sizeControls_.controlFunctions();
260 
261  forAll(controlFunctions, fI)
262  {
263  const cellSizeAndAlignmentControl& controlFunction =
264  controlFunctions[fI];
265 
266  const Switch forceInsertion =
267  controlFunction.forceInitialPointInsertion();
268 
269  Info<< "Inserting points from " << controlFunction.name()
270  << " (" << controlFunction.type() << ")" << endl;
271  Info<< " Force insertion is " << forceInsertion.c_str() << endl;
272 
273  pointField pts;
274  scalarField sizes;
275  triadField alignments;
276 
277  controlFunction.initialVertices(pts, sizes, alignments);
278 
279  Info<< " Got initial vertices list of size " << pts.size() << endl;
280 
281  List<Vb> vertices(pts.size());
282 
283  // Clip the minimum size
284  for (label vI = 0; vI < pts.size(); ++vI)
285  {
287 
288  label maxPriority = -1;
289  scalar size = sizeControls_.cellSize(pts[vI], maxPriority);
290 
291  if (maxPriority > controlFunction.maxPriority())
292  {
293  vertices[vI].targetCellSize() = max
294  (
295  size,
296  shapeController_.minimumCellSize()
297  );
298  }
299 // else if (maxPriority == controlFunction.maxPriority())
300 // {
301 // vertices[vI].targetCellSize() = max
302 // (
303 // min(sizes[vI], size),
304 // shapeController_.minimumCellSize()
305 // );
306 // }
307  else
308  {
309  vertices[vI].targetCellSize() = max
310  (
311  sizes[vI],
312  shapeController_.minimumCellSize()
313  );
314  }
315 
316  vertices[vI].alignment() = alignments[vI];
317  }
318 
319  Info<< " Clipped minimum size" << endl;
320 
321  pts.clear();
322  sizes.clear();
323  alignments.clear();
324 
325  bitSet keepVertex(vertices.size(), true);
326 
327  forAll(vertices, vI)
328  {
329  bool keep = true;
330 
331  pointFromPoint pt = topoint(vertices[vI].point());
332 
333  if (Pstream::parRun())
334  {
335  keep = decomposition().positionOnThisProcessor(pt);
336  }
337 
338  if (keep && geometryToConformTo_.wellOutside(pt, SMALL))
339  {
340  keep = false;
341  }
342 
343  if (!keep)
344  {
345  keepVertex.unset(vI);
346  }
347  }
348 
349  inplaceSubset(keepVertex, vertices);
350 
351  const label preInsertedSize = mesh_.number_of_vertices();
352 
353  Info<< " Check sizes" << endl;
354 
355  forAll(vertices, vI)
356  {
357  bool insertPoint = false;
358 
360 
361  if
362  (
363  mesh_.dimension() < 3
364  || mesh_.is_infinite
365  (
366  mesh_.locate(vertices[vI].point())
367  )
368  )
369  {
370  insertPoint = true;
371  }
372 
373  const scalar interpolatedCellSize = shapeController_.cellSize(pt);
374  const triad interpolatedAlignment =
375  shapeController_.cellAlignment(pt);
376  const scalar calculatedCellSize = vertices[vI].targetCellSize();
377  const triad calculatedAlignment = vertices[vI].alignment();
378 
379  if (debug)
380  {
381  Info<< "Point = " << pt << nl
382  << " Size(interp) = " << interpolatedCellSize << nl
383  << " Size(calc) = " << calculatedCellSize << nl
384  << " Align(interp) = " << interpolatedAlignment << nl
385  << " Align(calc) = " << calculatedAlignment << nl
386  << endl;
387  }
388 
389  const scalar sizeDiff =
390  mag(interpolatedCellSize - calculatedCellSize);
391  const scalar alignmentDiff =
392  diff(interpolatedAlignment, calculatedAlignment);
393 
394  if (debug)
395  {
396  Info<< " size difference = " << sizeDiff << nl
397  << ", alignment difference = " << alignmentDiff << endl;
398  }
399 
400  // TODO: Also need to base it on the alignments
401  if
402  (
403  sizeDiff/interpolatedCellSize > 0.1
404  || alignmentDiff > 0.15
405  )
406  {
407  insertPoint = true;
408  }
409 
410  if (forceInsertion || insertPoint)
411  {
412  const label oldSize = mesh_.vertexCount();
413 
414  cellShapeControlMesh::Vertex_handle insertedVert = mesh_.insert
415  (
416  pt,
417  calculatedCellSize,
418  vertices[vI].alignment(),
420  );
421 
422  if (oldSize == mesh_.vertexCount() - 1)
423  {
424  priorityMap.insert
425  (
426  insertedVert->index(),
427  controlFunction.maxPriority()
428  );
429  }
430  }
431  }
432 
433  //mesh_.rangeInsertWithInfo(vertices.begin(), vertices.end());
434 
435  Info<< " Inserted "
436  << returnReduce
437  (
438  label(mesh_.number_of_vertices()) - preInsertedSize,
439  sumOp<label>()
440  )
441  << "/" << returnReduce(vertices.size(), sumOp<label>())
442  << endl;
443  }
444 
445 
446 
447  forAll(controlFunctions, fI)
448  {
449  const cellSizeAndAlignmentControl& controlFunction =
450  controlFunctions[fI];
451 
452  const Switch forceInsertion =
453  controlFunction.forceInitialPointInsertion();
454 
455  Info<< "Inserting points from " << controlFunction.name()
456  << " (" << controlFunction.type() << ")" << endl;
457  Info<< " Force insertion is " << forceInsertion.c_str() << endl;
458 
459  DynamicList<Foam::point> extraPts;
460  DynamicList<scalar> extraSizes;
461 
462  controlFunction.cellSizeFunctionVertices(extraPts, extraSizes);
463 
464  List<Vb> vertices(extraPts.size());
465 
466  // Clip the minimum size
467  for (label vI = 0; vI < extraPts.size(); ++vI)
468  {
469  vertices[vI] = Vb(extraPts[vI], Vb::vtUnassigned);
470 
471  label maxPriority = -1;
472  scalar size = sizeControls_.cellSize(extraPts[vI], maxPriority);
473 
474  if (maxPriority > controlFunction.maxPriority())
475  {
476  vertices[vI].targetCellSize() = max
477  (
478  size,
479  shapeController_.minimumCellSize()
480  );
481  }
482  else if (maxPriority == controlFunction.maxPriority())
483  {
484  vertices[vI].targetCellSize() = max
485  (
486  min(extraSizes[vI], size),
487  shapeController_.minimumCellSize()
488  );
489  }
490  else
491  {
492  vertices[vI].targetCellSize() = max
493  (
494  extraSizes[vI],
495  shapeController_.minimumCellSize()
496  );
497  }
498  }
499 
500  bitSet keepVertex(vertices.size(), true);
501 
502  forAll(vertices, vI)
503  {
504  bool keep = true;
505 
506  pointFromPoint pt = topoint(vertices[vI].point());
507 
508  if (Pstream::parRun())
509  {
510  keep = decomposition().positionOnThisProcessor(pt);
511  }
512 
513  if (keep && geometryToConformTo_.wellOutside(pt, SMALL))
514  {
515  keep = false;
516  }
517 
518  if (!keep)
519  {
520  keepVertex.unset(vI);
521  }
522  }
523 
524  inplaceSubset(keepVertex, vertices);
525 
526  const label preInsertedSize = mesh_.number_of_vertices();
527 
528  forAll(vertices, vI)
529  {
530  bool insertPoint = false;
531 
533 
534  if
535  (
536  mesh_.dimension() < 3
537  || mesh_.is_infinite
538  (
539  mesh_.locate(vertices[vI].point())
540  )
541  )
542  {
543  insertPoint = true;
544  }
545 
546  const scalar interpolatedCellSize = shapeController_.cellSize(pt);
547  const scalar calculatedCellSize = vertices[vI].targetCellSize();
548 
549  if (debug)
550  {
551  Info<< "Point = " << pt << nl
552  << " Size(interp) = " << interpolatedCellSize << nl
553  << " Size(calc) = " << calculatedCellSize << nl
554  << endl;
555  }
556 
557  const scalar sizeDiff =
558  mag(interpolatedCellSize - calculatedCellSize);
559 
560  if (debug)
561  {
562  Info<< " size difference = " << sizeDiff << endl;
563  }
564 
565  // TODO: Also need to base it on the alignments
566  if (sizeDiff/interpolatedCellSize > 0.1)
567  {
568  insertPoint = true;
569  }
570 
571  if (forceInsertion || insertPoint)
572  {
573  // Check the priority
574 
575 // cellShapeControlMesh::Cell_handle ch =
576 // mesh_.locate(toPoint<cellShapeControlMesh::Point>(pt));
577 
578 // if (mesh_.is_infinite(ch))
579 // {
580 // continue;
581 // }
582 
583 // const label newPtPriority = controlFunction.maxPriority();
584 
585 // label highestPriority = -1;
586 // for (label cI = 0; cI < 4; ++cI)
587 // {
588 // if (mesh_.is_infinite(ch->vertex(cI)))
589 // {
590 // continue;
591 // }
592 
593 // const label vertPriority =
594 // priorityMap[ch->vertex(cI)->index()];
595 
596 // if (vertPriority > highestPriority)
597 // {
598 // highestPriority = vertPriority;
599 // }
600 // }
601 
602 // if (newPtPriority >= highestPriority)
603 // {
604 // const label oldSize = mesh_.vertexCount();
605 //
606 // cellShapeControlMesh::Vertex_handle insertedVert =
607  mesh_.insert
608  (
609  pt,
610  calculatedCellSize,
611  vertices[vI].alignment(),
613  );
614 
615 // if (oldSize == mesh_.vertexCount() - 1)
616 // {
617 // priorityMap.insert
618 // (
619 // insertedVert->index(),
620 // newPtPriority
621 // );
622 // }
623 // }
624  }
625  }
626 
627  //mesh_.rangeInsertWithInfo(vertices.begin(), vertices.end());
628 
629  Info<< " Inserted extra points "
630  << returnReduce
631  (
632  label(mesh_.number_of_vertices()) - preInsertedSize,
633  sumOp<label>()
634  )
635  << "/" << returnReduce(vertices.size(), sumOp<label>())
636  << endl;
637  }
638 
639  // Change cell size function of bounding points to be consistent
640  // with their nearest neighbours
641 // for
642 // (
643 // CellSizeDelaunay::Finite_vertices_iterator vit =
644 // mesh_.finite_vertices_begin();
645 // vit != mesh_.finite_vertices_end();
646 // ++vit
647 // )
648 // {
649 // if (vit->uninitialised())
650 // {
651 // // Get its adjacent vertices
652 // std::list<CellSizeDelaunay::Vertex_handle> adjacentVertices;
653 //
654 // mesh_.adjacent_vertices
655 // (
656 // vit,
657 // std::back_inserter(adjacentVertices)
658 // );
659 //
660 // scalar totalCellSize = 0;
661 // label nVerts = 0;
662 //
663 // for
664 // (
665 // std::list<CellSizeDelaunay::Vertex_handle>::iterator avit =
666 // adjacentVertices.begin();
667 // avit != adjacentVertices.end();
668 // ++avit
669 // )
670 // {
671 // if (!(*avit)->uninitialised())
672 // {
673 // totalCellSize += (*avit)->targetCellSize();
674 // nVerts++;
675 // }
676 // }
677 //
678 // Pout<< "Changing " << vit->info();
679 //
680 // vit->targetCellSize() = totalCellSize/nVerts;
681 // vit->type() = Vb::vtInternalNearBoundary;
682 //
683 // Pout<< "to " << vit->info() << endl;
684 // }
685 // }
686 }
687 
688 
690 (
691  const autoPtr<backgroundMeshDecomposition>& decomposition
692 )
693 {
694  Info<< "Iterate over "
695  << returnReduce(label(mesh_.number_of_finite_edges()), sumOp<label>())
696  << " cell size mesh edges" << endl;
697 
698  DynamicList<Vb> verts(mesh_.number_of_vertices());
699 
700  label count = 0;
701 
702  for
703  (
704  CellSizeDelaunay::Finite_edges_iterator eit =
705  mesh_.finite_edges_begin();
706  eit != mesh_.finite_edges_end();
707  ++eit
708  )
709  {
710  if (count % 10000 == 0)
711  {
712  Info<< count << " edges, inserted " << verts.size()
713  << " Time = " << mesh_.time().elapsedCpuTime()
714  << endl;
715  }
716  count++;
717 
718  CellSizeDelaunay::Cell_handle c = eit->first;
719  CellSizeDelaunay::Vertex_handle vA = c->vertex(eit->second);
720  CellSizeDelaunay::Vertex_handle vB = c->vertex(eit->third);
721 
722  if
723  (
724  mesh_.is_infinite(vA)
725  || mesh_.is_infinite(vB)
726  || (vA->referred() && vB->referred())
727  || (vA->referred() && (vA->procIndex() > vB->procIndex()))
728  || (vB->referred() && (vB->procIndex() > vA->procIndex()))
729  )
730  {
731  continue;
732  }
733 
734  pointFromPoint ptA(topoint(vA->point()));
735  pointFromPoint ptB(topoint(vB->point()));
736 
737  linePointRef l(ptA, ptB);
738 
739  const pointHit hitPt = findDiscontinuities(l);
740 
741  if (hitPt.hit())
742  {
743  const Foam::point& pt = hitPt.point();
744 
745  if (!geometryToConformTo_.inside(pt))
746  {
747  continue;
748  }
749 
750  if (Pstream::parRun())
751  {
752  if (!decomposition().positionOnThisProcessor(pt))
753  {
754  continue;
755  }
756  }
757 
758  verts.append
759  (
760  Vb
761  (
762  toPoint(pt),
764  )
765  );
766 
767  verts.last().targetCellSize() = sizeControls_.cellSize(pt);
768  verts.last().alignment() = triad::unset;
769  }
770  }
771 
772  mesh_.insertPoints(verts, false);
773 
774  return verts.size();
775 }
776 
777 
778 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
779 
780 
781 // * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * * //
782 
783 
784 // * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
785 
786 
787 // ************************************************************************* //
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
Definition: triad.C:373
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
pointFromPoint topoint(const Point &P)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
dimensionedSymmTensor sqr(const dimensionedVector &dv)
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1061
void inplaceSubset(const BoolListType &select, ListType &input, const bool invert=false)
Inplace extract elements of the input list when select is true.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
An indexed form of CGAL::Triangulation_vertex_base_3<K> used to keep track of the Delaunay vertices i...
Definition: indexedVertex.H:59
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
void initialMeshPopulation(const autoPtr< backgroundMeshDecomposition > &decomposition)
pointField vertices(const blockVertexList &bvl)
CGAL::indexedVertex< K > Vb
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
label refineMesh(const autoPtr< backgroundMeshDecomposition > &decomposition)
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
line< point, const point & > linePointRef
A line using referred points.
Definition: line.H:66
static const triad unset
Definition: triad.H:107
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:130
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
PointFrompoint toPoint(const Foam::point &p)
Describes the interaction of a object and a (templated) point. It carries the info of a successful hi...
Definition: pointHit.H:43
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
~controlMeshRefinement()
Destructor.
Field< triad > triadField
Specialisation of Field<T> for triad.
Definition: triadFieldFwd.H:37
CellSizeDelaunay::Vertex_handle Vertex_handle
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
int debug
Static debugging option.
defineTypeNameAndDebug(combustionModel, 0)
vector point
Point is a vector.
Definition: point.H:37
static constexpr direction size() noexcept
The number of elements in the VectorSpace = Ncmpts.
Definition: VectorSpace.H:206
const dimensionedScalar c
Speed of light in a vacuum.
messageStream Info
Information stream (stdout output on master, null elsewhere)
volScalarField & p
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
PointHit< point > pointHit
A PointHit with a 3D point.
Definition: pointHit.H:43
Namespace for OpenFOAM.
const pointField & pts