reconstructedDistanceFunction.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) 2019-2020 DLR
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 "emptyPolyPatch.H"
30 #include "processorPolyPatch.H"
31 #include "syncTools.H"
32 #include "unitConversion.H"
33 #include "wedgePolyPatch.H"
35 
36 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
37 
39 Foam::reconstructedDistanceFunction::coupledFacesPatch() const
40 {
41  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
42 
43  label nCoupled = 0;
44 
45  for (const polyPatch& pp : patches)
46  {
47  if (isA<coupledPolyPatch>(pp))
48  {
49  nCoupled += pp.size();
50  }
51  }
52  labelList nCoupledFaces(nCoupled);
53  nCoupled = 0;
54 
55  for (const polyPatch& pp : patches)
56  {
57  if (isA<coupledPolyPatch>(pp))
58  {
59  label facei = pp.start();
60 
61  forAll(pp, i)
62  {
63  nCoupledFaces[nCoupled++] = facei++;
64  }
65  }
66  }
67 
69  (
70  IndirectList<face>
71  (
72  mesh_.faces(),
73  nCoupledFaces
74  ),
75  mesh_.points()
76  );
77 }
78 
79 
81 (
82  const boolList& interfaceCells,
83  const label neiRingLevel
84 )
85 {
86  // performance might be improved by increasing the saving last iterations
87  // cells in a Map and loop over the map
88  if (mesh_.topoChanging())
89  {
90  // Introduced resizing to cope with changing meshes
91  if (nextToInterface_.size() != mesh_.nCells())
92  {
93  nextToInterface_.resize(mesh_.nCells());
94  }
95  coupledBoundaryPoints_ = coupledFacesPatch()().meshPoints();
96  }
97 
98  const labelListList& pCells = mesh_.cellPoints();
99  const labelListList& cPoints = mesh_.pointCells();
100 
101  boolList alreadyMarkedPoint(mesh_.nPoints(), false);
102  nextToInterface_ = false;
103 
104  // do coupled face first
105  Map<bool> syncMap;
106 
107  for (int level=0;level<=neiRingLevel;level++)
108  {
109  // parallel
110  if (level > 0)
111  {
112  forAll(coupledBoundaryPoints_, i)
113  {
114  const label pi = coupledBoundaryPoints_[i];
115  forAll(mesh_.pointCells()[pi], j)
116  {
117  const label celli = cPoints[pi][j];
118  if (cellDistLevel_[celli] == level-1)
119  {
120  syncMap.insert(pi, true);
121  break;
122  }
123  }
124  }
125 
126  syncTools::syncPointMap(mesh_, syncMap, orEqOp<bool>());
127 
128  // mark parallel points first
129  forAllConstIters(syncMap, iter)
130  {
131  const label pi = iter.key();
132 
133  if (!alreadyMarkedPoint[pi])
134  {
135  // loop over all cells attached to the point
136  forAll(cPoints[pi], j)
137  {
138  const label pCelli = cPoints[pi][j];
139  if (cellDistLevel_[pCelli] == -1)
140  {
141  cellDistLevel_[pCelli] = level;
142  nextToInterface_[pCelli] = true;
143  }
144  }
145  }
146  alreadyMarkedPoint[pi] = true;
147  }
148  }
149 
150 
151  forAll(cellDistLevel_, celli)
152  {
153  if (level == 0)
154  {
155  if (interfaceCells[celli])
156  {
157  cellDistLevel_[celli] = 0;
158  nextToInterface_[celli] = true;
159  }
160  else
161  {
162  cellDistLevel_[celli] = -1;
163  }
164  }
165  else
166  {
167  if (cellDistLevel_[celli] == level-1)
168  {
169  forAll(pCells[celli], i)
170  {
171  const label pI = pCells[celli][i];
172 
173  if (!alreadyMarkedPoint[pI])
174  {
175  forAll(cPoints[pI], j)
176  {
177  const label pCelli = cPoints[pI][j];
178  if (cellDistLevel_[pCelli] == -1)
179  {
180  cellDistLevel_[pCelli] = level;
181  nextToInterface_[pCelli] = true;
182  }
183  }
184  }
185  alreadyMarkedPoint[pI] = true;
186  }
187  }
188  }
189  }
190  }
191 }
192 
193 
194 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
195 
197 (
198  const fvMesh& mesh
199 )
200 :
202  (
203  IOobject
204  (
205  "RDF",
206  mesh.time().timeName(),
207  mesh,
210  ),
211  mesh,
213  ),
214  mesh_(mesh),
215  coupledBoundaryPoints_(coupledFacesPatch()().meshPoints()),
216  cellDistLevel_
217  (
218  IOobject
219  (
220  "cellDistLevel",
221  mesh.time().timeName(),
222  mesh,
225  ),
226  mesh,
227  dimensionedScalar("cellDistLevel", dimless, -1)
228  ),
229  nextToInterface_(mesh.nCells(), false)
230 {}
231 
232 
233 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
234 
236 (
237  const boolList& nextToInterface,
238  const volVectorField& centre,
239  const volVectorField& normal,
240  zoneDistribute& distribute,
241  bool updateStencil
242 )
243 {
244  volScalarField& reconDistFunc = *this;
245 
246  if (nextToInterface.size() != centre.size())
247  {
249  << "size of nextToInterface: " << nextToInterface.size()
250  << "size of centre:" << centre.size()
251  << "do not match. Did the mesh change?"
252  << exit(FatalError);
253  return reconDistFunc;
254  }
255 
256 
257  distribute.setUpCommforZone(nextToInterface, updateStencil);
258 
259  Map<vector> mapCentres =
260  distribute.getDatafromOtherProc(nextToInterface, centre);
261  Map<vector> mapNormal =
262  distribute.getDatafromOtherProc(nextToInterface, normal);
263 
264  const labelListList& stencil = distribute.getStencil();
265 
266 
267  forAll(nextToInterface,celli)
268  {
269  if (nextToInterface[celli])
270  {
271  if (mag(normal[celli]) != 0) // interface cell
272  {
273  vector n = -normal[celli]/mag(normal[celli]);
274  scalar dist = (centre[celli] - mesh_.C()[celli]) & n;
275  reconDistFunc[celli] = dist;
276  }
277  else // nextToInterfaceCell or level == 1 cell
278  {
279  scalar averageDist = 0;
280  scalar avgWeight = 0;
281  const point p = mesh_.C()[celli];
282 
283  forAll(stencil[celli], i)
284  {
285  const label gblIdx = stencil[celli][i];
286  vector n = -distribute.getValue(normal, mapNormal, gblIdx);
287  if (mag(n) != 0)
288  {
289  n /= mag(n);
290  vector c = distribute.getValue(centre,mapCentres,gblIdx);
291  vector distanceToIntSeg = (c - p);
292  scalar distToSurf = distanceToIntSeg & (n);
293  scalar weight = 0;
294 
295  if (mag(distanceToIntSeg) != 0)
296  {
297  distanceToIntSeg /= mag(distanceToIntSeg);
298  weight = sqr(mag(distanceToIntSeg & n));
299  }
300  else // exactly on the center
301  {
302  weight = 1;
303  }
304  averageDist += distToSurf * weight;
305  avgWeight += weight;
306  }
307  }
308 
309  if (avgWeight != 0)
310  {
311  reconDistFunc[celli] = averageDist / avgWeight;
312  }
313  }
314  }
315  else
316  {
317  reconDistFunc[celli] = 0;
318  }
319  }
320 
321  forAll(reconDistFunc.boundaryField(), patchI)
322  {
323  fvPatchScalarField& pRDF = reconDistFunc.boundaryFieldRef()[patchI];
324  if (isA<calculatedFvPatchScalarField>(pRDF))
325  {
326  const polyPatch& pp = pRDF.patch().patch();
327  forAll(pRDF, i)
328  {
329  const label pCellI = pp.faceCells()[i];
330 
331  if (nextToInterface_[pCellI])
332  {
333  scalar averageDist = 0;
334  scalar avgWeight = 0;
335  const point p = mesh_.C().boundaryField()[patchI][i];
336 
337  forAll(stencil[pCellI], j)
338  {
339  const label gblIdx = stencil[pCellI][j];
340  vector n = -distribute.getValue(normal, mapNormal, gblIdx);
341  if (mag(n) != 0)
342  {
343  n /= mag(n);
344  vector c =
345  distribute.getValue(centre, mapCentres, gblIdx);
346  vector distanceToIntSeg = (c - p);
347  scalar distToSurf = distanceToIntSeg & (n);
348  scalar weight = 0;
349 
350  if (mag(distanceToIntSeg) != 0)
351  {
352  distanceToIntSeg /= mag(distanceToIntSeg);
353  weight = sqr(mag(distanceToIntSeg & n));
354  }
355  else // exactly on the center
356  {
357  weight = 1;
358  }
359  averageDist += distToSurf * weight;
360  avgWeight += weight;
361  }
362  }
363 
364  if (avgWeight != 0)
365  {
366  pRDF[i] = averageDist / avgWeight;
367  }
368  else
369  {
370  pRDF[i] = 0;
371  }
372  }
373  else
374  {
375  pRDF[i] = 0;
376  }
377  }
378  }
379  }
380 
381  reconDistFunc.correctBoundaryConditions();
382 
383  return reconDistFunc;
384 }
385 
386 
388 (
389  const volScalarField& alpha,
390  const volVectorField& U,
391  surfaceVectorField::Boundary& nHatb
392 )
393 {
394  const fvMesh& mesh = alpha.mesh();
395  const volScalarField::Boundary& abf = alpha.boundaryField();
396  volScalarField::Boundary& RDFbf = this->boundaryFieldRef();
397 
399 
400  forAll(boundary, patchi)
401  {
402  if (isA<alphaContactAngleTwoPhaseFvPatchScalarField>(abf[patchi]))
403  {
406  (
407  refCast<const alphaContactAngleTwoPhaseFvPatchScalarField>
408  (
409  abf[patchi]
410  )
411  );
412 
413  fvsPatchVectorField& nHatp = nHatb[patchi];
414  const scalarField theta
415  (
416  degToRad()*acap.theta(U.boundaryField()[patchi], nHatp)
417  );
418 
419  RDFbf[patchi] =
420  1/acap.patch().deltaCoeffs()*cos(theta)
421  + RDFbf[patchi].patchInternalField();
422  }
423  }
424 }
425 
426 
427 // ************************************************************************* //
Foam::fvPatchField< scalar >
Foam::zoneDistribute::getValue
Type getValue(const GeometricField< Type, fvPatchField, volMesh > &phi, const Map< Type > &valuesFromOtherProc, const label gblIdx) const
Definition: zoneDistributeI.H:85
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1069
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
Foam::zoneDistribute::getDatafromOtherProc
Map< Type > getDatafromOtherProc(const boolList &zone, const GeometricField< Type, fvPatchField, volMesh > &phi)
Returns stencil and provides a Map with globalNumbering.
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:129
Foam::dimless
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Dimensionless.
Definition: dimensionSets.H:50
Foam::syncTools::syncPointMap
static void syncPointMap(const polyMesh &mesh, Map< T > &pointValues, const CombineOp &cop, const TransformOp &top)
Synchronize values on selected points.
Definition: syncToolsTemplates.C:84
Foam::dimLength
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:53
Foam::reconstructedDistanceFunction::constructRDF
const volScalarField & constructRDF(const boolList &nextToInterface, const volVectorField &centre, const volVectorField &normal, zoneDistribute &distribute, bool updateStencil=true)
Definition: reconstructedDistanceFunction.C:236
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
wedgePolyPatch.H
Foam::constant::atomic::alpha
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
Definition: readThermalProperties.H:212
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::fvsPatchField
An abstract base class with a fat-interface to all derived classes covering all possible ways in whic...
Definition: fvsPatchField.H:68
Foam::Map
A HashTable to objects of type <T> with a label key.
Definition: lumpedPointController.H:69
unitConversion.H
Unit conversion functions.
Foam::orEqOp
Definition: ops.H:86
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::reconstructedDistanceFunction::updateContactAngle
void updateContactAngle(const volScalarField &alpha, const volVectorField &U, surfaceVectorField::Boundary &nHatb)
Definition: reconstructedDistanceFunction.C:388
syncTools.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::fvBoundaryMesh
Foam::fvBoundaryMesh.
Definition: fvBoundaryMesh.H:56
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::alphaContactAngleTwoPhaseFvPatchScalarField
Abstract base class for two-phase alphaContactAngle boundary conditions.
Definition: alphaContactAngleTwoPhaseFvPatchScalarField.H:78
reconstructedDistanceFunction.H
Foam::primitiveMesh::nCells
label nCells() const
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::Field< scalar >
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::zoneDistribute::getStencil
const labelListList & getStencil()
Stencil reference.
Definition: zoneDistribute.H:129
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:43
Foam::volScalarField
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:57
Foam::reconstructedDistanceFunction::markCellsNearSurf
void markCellsNearSurf(const boolList &interfaceCells, const label neiRingLevel)
Definition: reconstructedDistanceFunction.C:81
Foam::FatalError
error FatalError
processorPolyPatch.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:83
Foam::polyPatch::faceCells
const labelUList & faceCells() const
Return face-cell addressing.
Definition: polyPatch.C:363
Foam::degToRad
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
Definition: unitConversion.H:48
emptyPolyPatch.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::zoneDistribute::setUpCommforZone
void setUpCommforZone(const boolList &zone, bool updateStencil=true)
Update stencil with boolList the size has to match mesh nCells.
Definition: zoneDistribute.C:131
Foam::GeometricField::correctBoundaryConditions
void correctBoundaryConditions()
Correct boundary field.
Definition: GeometricField.C:940
Foam::fvMesh::boundary
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:679
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
U
U
Definition: pEqn.H:72
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1094
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
Foam::constant::mathematical::pi
constexpr scalar pi(M_PI)
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::zoneDistribute
Class for parallel communication in a narrow band. It either provides a Map with the neighbouring val...
Definition: zoneDistribute.H:64
Foam::GeometricField::boundaryFieldRef
Boundary & boundaryFieldRef(const bool updateAccessTime=true)
Return a reference to the boundary field.
Definition: GeometricField.C:783
Foam::Vector< scalar >
Foam::List< bool >
Foam::alphaContactAngleTwoPhaseFvPatchScalarField::theta
virtual tmp< scalarField > theta(const fvPatchVectorField &Up, const fvsPatchVectorField &nHat) const =0
Return the contact angle.
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::fvPatch::patch
const polyPatch & patch() const
Return the polyPatch.
Definition: fvPatch.H:161
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:275
alphaContactAngleTwoPhaseFvPatchScalarField.H
Foam::fvPatchField::patch
const fvPatch & patch() const
Return patch.
Definition: fvPatchField.H:343
Foam::GeometricField< scalar, fvPatchField, volMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:123
boundary
faceListList boundary
Definition: createBlockMesh.H:4
Foam::GeometricField::boundaryField
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Definition: GeometricFieldI.H:62
Foam::reconstructedDistanceFunction::reconstructedDistanceFunction
reconstructedDistanceFunction(const fvMesh &mesh)
Construct from fvMesh.
Definition: reconstructedDistanceFunction.C:197
Foam::cos
dimensionedScalar cos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:265