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 (label 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  for (const label gblIdx : stencil[celli])
284  {
285  vector n = -distribute.getValue(normal, mapNormal, gblIdx);
286  if (mag(n) != 0)
287  {
288  n /= mag(n);
289  vector c = distribute.getValue(centre,mapCentres,gblIdx);
290  vector distanceToIntSeg = (c - p);
291  scalar distToSurf = distanceToIntSeg & (n);
292  scalar weight = 0;
293 
294  if (mag(distanceToIntSeg) != 0)
295  {
296  distanceToIntSeg /= mag(distanceToIntSeg);
297  weight = sqr(mag(distanceToIntSeg & n));
298  }
299  else // exactly on the center
300  {
301  weight = 1;
302  }
303  averageDist += distToSurf * weight;
304  avgWeight += weight;
305  }
306  }
307 
308  if (avgWeight != 0)
309  {
310  reconDistFunc[celli] = averageDist / avgWeight;
311  }
312  }
313  }
314  else
315  {
316  reconDistFunc[celli] = 0;
317  }
318  }
319 
320  forAll(reconDistFunc.boundaryField(), patchI)
321  {
322  fvPatchScalarField& pRDF = reconDistFunc.boundaryFieldRef()[patchI];
323  if (isA<calculatedFvPatchScalarField>(pRDF))
324  {
325  const polyPatch& pp = pRDF.patch().patch();
326  forAll(pRDF, i)
327  {
328  const label pCellI = pp.faceCells()[i];
329 
330  if (nextToInterface_[pCellI])
331  {
332  scalar averageDist = 0;
333  scalar avgWeight = 0;
334  const point p = mesh_.C().boundaryField()[patchI][i];
335 
336  forAll(stencil[pCellI], j)
337  {
338  const label gblIdx = stencil[pCellI][j];
339  vector n = -distribute.getValue(normal, mapNormal, gblIdx);
340  if (mag(n) != 0)
341  {
342  n /= mag(n);
343  vector c =
344  distribute.getValue(centre, mapCentres, gblIdx);
345  vector distanceToIntSeg = (c - p);
346  scalar distToSurf = distanceToIntSeg & (n);
347  scalar weight = 0;
348 
349  if (mag(distanceToIntSeg) != 0)
350  {
351  distanceToIntSeg /= mag(distanceToIntSeg);
352  weight = sqr(mag(distanceToIntSeg & n));
353  }
354  else // exactly on the center
355  {
356  weight = 1;
357  }
358  averageDist += distToSurf * weight;
359  avgWeight += weight;
360  }
361  }
362 
363  if (avgWeight != 0)
364  {
365  pRDF[i] = averageDist / avgWeight;
366  }
367  else
368  {
369  pRDF[i] = 0;
370  }
371  }
372  else
373  {
374  pRDF[i] = 0;
375  }
376  }
377  }
378  }
379 
380  reconDistFunc.correctBoundaryConditions();
381 
382  return reconDistFunc;
383 }
384 
385 
387 (
388  const volScalarField& alpha,
389  const volVectorField& U,
390  surfaceVectorField::Boundary& nHatb
391 )
392 {
393  const fvMesh& mesh = alpha.mesh();
394  const volScalarField::Boundary& abf = alpha.boundaryField();
395  volScalarField::Boundary& RDFbf = this->boundaryFieldRef();
396 
398 
399  forAll(boundary, patchi)
400  {
401  if (isA<alphaContactAngleTwoPhaseFvPatchScalarField>(abf[patchi]))
402  {
405  (
406  refCast<const alphaContactAngleTwoPhaseFvPatchScalarField>
407  (
408  abf[patchi]
409  )
410  );
411 
412  fvsPatchVectorField& nHatp = nHatb[patchi];
413  const scalarField theta
414  (
415  degToRad()*acap.theta(U.boundaryField()[patchi], nHatp)
416  );
417 
418  RDFbf[patchi] =
419  1/acap.patch().deltaCoeffs()*cos(theta)
420  + RDFbf[patchi].patchInternalField();
421  }
422  }
423 }
424 
425 
426 // ************************************************************************* //
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:82
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
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:67
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:169
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:194
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:52
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:387
syncTools.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::fvBoundaryMesh
Foam::fvBoundaryMesh.
Definition: fvBoundaryMesh.H:57
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::primitiveMesh::nCells
label nCells() const noexcept
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::alphaContactAngleTwoPhaseFvPatchScalarField
Abstract base class for two-phase alphaContactAngle boundary conditions.
Definition: alphaContactAngleTwoPhaseFvPatchScalarField.H:78
reconstructedDistanceFunction.H
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::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:42
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:85
Foam::polyPatch::faceCells
const labelUList & faceCells() const
Return face-cell addressing.
Definition: polyPatch.C:371
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:127
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:685
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:453
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::zoneDistribute::getStencil
const labelListList & getStencil() noexcept
Stencil reference.
Definition: zoneDistribute.H:136
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:280
alphaContactAngleTwoPhaseFvPatchScalarField.H
Foam::fvPatchField::patch
const fvPatch & patch() const
Return patch.
Definition: fvPatchField.H:357
Foam::GeometricField< scalar, fvPatchField, volMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:188
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::dimless
const dimensionSet dimless
Dimensionless.
Definition: dimensionSets.C:189
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