wallBoundedStreamLine.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2019 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 "wallBoundedStreamLine.H"
31 #include "sampledSet.H"
32 #include "faceSet.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 namespace functionObjects
40 {
41  defineTypeNameAndDebug(wallBoundedStreamLine, 0);
42 
44  (
45  functionObject,
46  wallBoundedStreamLine,
47  dictionary
48  );
49 }
50 }
51 
52 
53 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
54 
57 (
58  const bitSet& isWallPatch,
59  const point& seedPt,
60  const label celli
61 ) const
62 {
63  const cell& cFaces = mesh_.cells()[celli];
64 
65  label minFacei = -1;
66  label minTetPti = -1;
67  scalar minDistSqr = sqr(GREAT);
68  point nearestPt(GREAT, GREAT, GREAT);
69 
70  for (label facei : cFaces)
71  {
72  if (isWallPatch[facei])
73  {
74  const face& f = mesh_.faces()[facei];
75  const label fp0 = mesh_.tetBasePtIs()[facei];
76  const point& basePoint = mesh_.points()[f[fp0]];
77 
78  label fp = f.fcIndex(fp0);
79  for (label i = 2; i < f.size(); i++)
80  {
81  const point& thisPoint = mesh_.points()[f[fp]];
82  const label nextFp = f.fcIndex(fp);
83  const point& nextPoint = mesh_.points()[f[nextFp]];
84 
85  const triPointRef tri(basePoint, thisPoint, nextPoint);
86 
87  //const scalar d2 = magSqr(tri.centre() - seedPt);
88  const pointHit nearInfo(tri.nearestPoint(seedPt));
89  const scalar d2 = nearInfo.distance();
90  if (d2 < minDistSqr)
91  {
92  nearestPt = nearInfo.rawPoint();
93  minDistSqr = d2;
94  minFacei = facei;
95  minTetPti = i-1;
96  }
97  fp = nextFp;
98  }
99  }
100  }
101 
102  // Return tet and nearest point on wall triangle
104  (
105  tetIndices
106  (
107  celli,
108  minFacei,
109  minTetPti
110  ),
111  nearestPt
112  );
113 }
114 
115 
117 (
118  const triPointRef& tri,
119  const point& pt
120 ) const
121 {
122  //pointHit nearPt(tri.nearestPoint(pt));
123  //if (nearPt.distance() > ROOTSMALL)
124  //{
125  // FatalErrorInFunction << "tri:" << tri
126  // << " seed:" << pt << exit(FatalError);
127  //}
128 
129  return (1.0-ROOTSMALL)*pt+ROOTSMALL*tri.centre();
130 }
131 
132 
134 {
135  // Determine the 'wall' patches
136  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
137  // These are the faces that need to be followed
138 
140  bitSet isWallPatch(mesh_.nFaces(), boundaryPatch().addressing());
141 
142 
143  // Find nearest wall particle for the seedPoints
144  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
145 
148  (
149  mesh_,
150  cloudName_,
151  initialParticles
152  );
153 
154  {
155  // Get the seed points
156  // ~~~~~~~~~~~~~~~~~~~
157 
158  const sampledSet& seedPoints = sampledSetPoints();
159 
160  forAll(seedPoints, seedi)
161  {
162  const label celli = seedPoints.cells()[seedi];
163 
164  if (celli != -1)
165  {
166  const point& seedPt = seedPoints[seedi];
167  Tuple2<tetIndices, point> nearestId
168  (
169  findNearestTet(isWallPatch, seedPt, celli)
170  );
171  const tetIndices& ids = nearestId.first();
172 
173  if (ids.face() != -1 && isWallPatch[ids.face()])
174  {
175  //Pout<< "Seeding particle :" << nl
176  // << " seedPt:" << seedPt << nl
177  // << " face :" << ids.face() << nl
178  // << " at :" << mesh_.faceCentres()[ids.face()]
179  // << nl
180  // << " cell :" << mesh_.cellCentres()[ids.cell()]
181  // << nl << endl;
182 
183  particles.addParticle
184  (
186  (
187  mesh_,
188  // Perturb seed point to be inside triangle
189  pushIn(ids.faceTri(mesh_), nearestId.second()),
190  ids.cell(),
191  ids.face(), // tetFace
192  ids.tetPt(),
193  -1, // not on a mesh edge
194  -1, // not on a diagonal edge
195  (trackDir_ == trackDirType::FORWARD), // forward?
196  lifeTime_ // lifetime
197  )
198  );
199 
200  if (trackDir_ == trackDirType::BIDIRECTIONAL)
201  {
202  // Additional particle for other half of track
203  particles.addParticle
204  (
206  (
207  mesh_,
208  // Perturb seed point to be inside triangle
209  pushIn(ids.faceTri(mesh_), nearestId.second()),
210  ids.cell(),
211  ids.face(), // tetFace
212  ids.tetPt(),
213  -1, // not on a mesh edge
214  -1, // not on a diagonal edge
215  true, // forward
216  lifeTime_ // lifetime
217  )
218  );
219  }
220  }
221  else
222  {
223  Pout<< type() << " : ignoring seed " << seedPt
224  << " since not in wall cell." << endl;
225  }
226  }
227  }
228  }
229 
230  const label nSeeds = returnReduce(particles.size(), sumOp<label>());
231 
232  Log << type() << " : seeded " << nSeeds << " particles." << endl;
233 
234 
235 
236  // Read or lookup fields
241 
242  label UIndex = -1;
243 
245  (
246  nSeeds,
247  UIndex,
248  vsFlds,
249  vsInterp,
250  vvFlds,
251  vvInterp
252  );
253 
254  // Additional particle info
256  (
257  particles,
258  vsInterp,
259  vvInterp,
260  UIndex, // index of U in vvInterp
261  trackLength_, // fixed track length
262  isWallPatch, // which faces are to follow
263 
264  allTracks_,
265  allScalars_,
267  );
268 
269 
270  // Set very large dt. Note: cannot use GREAT since 1/GREAT is SMALL
271  // which is a trigger value for the tracking...
272  const scalar trackTime = Foam::sqrt(GREAT);
273 
274  // Track
275  particles.move(particles, td, trackTime);
276 }
277 
278 
279 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
280 
281 Foam::functionObjects::wallBoundedStreamLine::wallBoundedStreamLine
282 (
283  const word& name,
284  const Time& runTime,
285  const dictionary& dict
286 )
287 :
289 {
290  read(dict_);
291 }
292 
293 
294 Foam::functionObjects::wallBoundedStreamLine::wallBoundedStreamLine
295 (
296  const word& name,
297  const Time& runTime,
298  const dictionary& dict,
299  const wordList& fieldNames
300 )
301 :
302  streamLineBase(name, runTime, dict, fieldNames)
303 {
304  read(dict_);
305 }
306 
307 
308 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
309 
311 {}
312 
313 
314 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
315 
317 {
319  {
320  // Make sure that the mesh is trackable
321  if (debug)
322  {
323  // 1. Positive volume decomposition tets
324  faceSet faces(mesh_, "lowQualityTetFaces", mesh_.nFaces()/100+1);
325 
326  if
327  (
329  (
330  mesh_,
332  true,
333  &faces
334  )
335  )
336  {
337  label nFaces = returnReduce(faces.size(), sumOp<label>());
338 
340  << "Found " << nFaces
341  <<" faces with low quality or negative volume "
342  << "decomposition tets. Writing to faceSet " << faces.name()
343  << endl;
344  }
345 
346  // 2. All edges on a cell having two faces
347  EdgeMap<label> numFacesPerEdge;
348  for (const cell& cFaces : mesh_.cells())
349  {
350  numFacesPerEdge.clear();
351 
352  for (const label facei : cFaces)
353  {
354  const face& f = mesh_.faces()[facei];
355  forAll(f, fp)
356  {
357  const edge e(f[fp], f.nextLabel(fp));
358 
359  ++(numFacesPerEdge(e, 0));
360  }
361  }
362 
363  forAllConstIters(numFacesPerEdge, iter)
364  {
365  if (iter() != 2)
366  {
368  << "problem cell:" << cFaces
369  << abort(FatalError);
370  }
371  }
372  }
373  }
374  }
375 
376  return true;
377 }
378 
379 
380 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::sampledSet
Holds list of sampling points which is filled at construction time. Various implementations of this b...
Definition: sampledSet.H:83
Foam::polyMeshTetDecomposition::checkFaceTets
static bool checkFaceTets(const polyMesh &mesh, scalar tol=minTetQuality, const bool report=false, labelHashSet *setPtr=nullptr)
Check face-decomposition tet volume.
Definition: polyMeshTetDecomposition.C:345
Foam::Cloud::addParticle
void addParticle(ParticleType *pPtr)
Transfer particle to cloud.
Definition: Cloud.C:103
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::functionObjects::streamLineBase::trackLength_
scalar trackLength_
Track length.
Definition: streamLineBase.H:112
Foam::functionObjects::streamLineBase::allScalars_
List< DynamicList< scalarList > > allScalars_
Per scalarField, per track, the sampled values.
Definition: streamLineBase.H:145
Foam::polyMeshTetDecomposition::minTetQuality
static const scalar minTetQuality
Minimum tetrahedron quality.
Definition: polyMeshTetDecomposition.H:66
Foam::nearInfo
Tuple2< scalar, label > nearInfo
Private class for finding nearest.
Definition: sampledTriSurfaceMesh.C:67
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:64
Foam::tetIndices::cell
label cell() const
Return the cell.
Definition: tetIndicesI.H:30
Foam::PointHit< point >
Foam::primitiveMesh::nFaces
label nFaces() const
Number of mesh faces.
Definition: primitiveMeshI.H:90
wallBoundedStreamLineParticleCloud.H
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::functionObjects::streamLineBase::sampledSetPoints
const sampledSet & sampledSetPoints() const
Demand driven construction of the sampledSet.
Definition: streamLineBase.C:78
Foam::sampledSet::cells
const labelList & cells() const
Definition: sampledSet.H:296
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:63
Foam::tetIndices::face
label face() const
Return the face.
Definition: tetIndicesI.H:42
Foam::functionObjects::streamLineBase::wallPatch
autoPtr< indirectPrimitivePatch > wallPatch() const
Construct patch out of all wall patch faces.
Definition: streamLineBase.C:98
Foam::faceSet
A list of face labels.
Definition: faceSet.H:51
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
Foam::functionObjects::addToRunTimeSelectionTable
addToRunTimeSelectionTable(functionObject, add, dictionary)
Foam::functionObjects::streamLineBase::read
virtual bool read(const dictionary &)
Read the field average data.
Definition: streamLineBase.C:873
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::triangle::centre
Point centre() const
Return centre (centroid)
Definition: triangleI.H:105
Foam::functionObjects::wallBoundedStreamLine::track
virtual void track()
Do the actual tracking to fill the track data.
Definition: wallBoundedStreamLine.C:133
Foam::boundaryPatch
Like polyPatch but without reference to mesh. patchIdentifier::index is not used. Used in boundaryMes...
Definition: boundaryPatch.H:59
Foam::triangle
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:62
Foam::wallBoundedStreamLineParticleCloud
A Cloud of streamLine particles.
Definition: wallBoundedStreamLineParticleCloud.H:52
Foam::wallBoundedStreamLineParticle::trackingData
Class used to pass tracking data to the trackToEdge function.
Definition: wallBoundedStreamLineParticle.H:74
wallBoundedStreamLine.H
sampledSet.H
Foam::label
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:62
Foam::tetIndices::faceTri
triPointRef faceTri(const polyMesh &mesh) const
Return the geometry corresponding to the tri on the face for.
Definition: tetIndicesI.H:169
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::wallBoundedStreamLineParticle
Particle class that samples fields as it passes through. Used in streamline calculation.
Definition: wallBoundedStreamLineParticle.H:66
faceSet.H
Foam::functionObjects::wallBoundedStreamLine::pushIn
point pushIn(const triPointRef &tri, const point &pt) const
Push a point a tiny bit towards the centre of the triangle it is in.
Definition: wallBoundedStreamLine.C:117
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:65
Foam::functionObjects::streamLineBase::initInterpolations
void initInterpolations(const label nSeeds, label &UIndex, PtrList< volScalarField > &vsFlds, PtrList< interpolation< scalar >> &vsInterp, PtrList< volVectorField > &vvFlds, PtrList< interpolation< vector >> &vvInterp)
Initialise fields, interpolators and track storage.
Definition: streamLineBase.C:142
Foam::functionObjects::streamLineBase
Definition: streamLineBase.H:65
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::ILList
Template class for intrusive linked lists.
Definition: ILList.H:52
Foam::Cloud::move
void move(TrackCloudType &cloud, typename ParticleType::trackingData &td, const scalar trackTime)
Move the particles.
Definition: Cloud.C:146
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
Foam::functionObjects::streamLineBase::allVectors_
List< DynamicList< vectorList > > allVectors_
Per vectorField, per track, the sampled values.
Definition: streamLineBase.H:148
Foam::tetIndices::tetPt
label tetPt() const
Return the characterising tetPtI.
Definition: tetIndicesI.H:54
Foam::functionObjects::streamLineBase::trackDir_
trackDirType trackDir_
Whether to use +u or -u or both.
Definition: streamLineBase.H:106
Foam::functionObjects::defineTypeNameAndDebug
defineTypeNameAndDebug(fvMeshFunctionObject, 0)
Foam::tetIndices
Storage and named access for the indices of a tet which is part of the decomposition of a cell.
Definition: tetIndices.H:83
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::EdgeMap< label >
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::HashTable::clear
void clear()
Clear all entries from table.
Definition: HashTable.C:630
f
labelList f(nPoints)
Foam::functionObjects::streamLineBase::cloudName_
word cloudName_
Optional specified name of particles.
Definition: streamLineBase.H:118
Foam::functionObject::type
virtual const word & type() const =0
Runtime type information.
Foam::Vector< scalar >
Foam::List< word >
Foam::sqrt
dimensionedScalar sqrt(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:144
Foam::functionObjects::streamLineBase::lifeTime_
label lifeTime_
Maximum lifetime (= number of cells) of particle.
Definition: streamLineBase.H:109
Foam::functionObjects::fvMeshFunctionObject::mesh_
const fvMesh & mesh_
Reference to the fvMesh.
Definition: fvMeshFunctionObject.H:73
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::Tuple2::second
const T2 & second() const noexcept
Return second.
Definition: Tuple2.H:130
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:74
Foam::triangle::nearestPoint
pointHit nearestPoint(const point &p) const
Return nearest point to p on triangle.
Definition: triangleI.H:671
Foam::functionObjects::wallBoundedStreamLine::findNearestTet
Tuple2< tetIndices, point > findNearestTet(const bitSet &isWallPatch, const point &seedPt, const label celli) const
Find wall tet on cell.
Definition: wallBoundedStreamLine.C:57
Foam::Tuple2
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: Tuple2.H:57
Foam::functionObjects::wallBoundedStreamLine::read
virtual bool read(const dictionary &)
Read settings.
Definition: wallBoundedStreamLine.C:316
Foam::functionObjects::streamLineBase::allTracks_
DynamicList< List< point > > allTracks_
All tracks. Per track the points it passed through.
Definition: streamLineBase.H:142
Foam::Tuple2::first
const T1 & first() const noexcept
Return first.
Definition: Tuple2.H:118
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:294
Foam::cell
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:54
Foam::functionObjects::wallBoundedStreamLine::~wallBoundedStreamLine
virtual ~wallBoundedStreamLine()
Destructor.
Definition: wallBoundedStreamLine.C:310
Log
#define Log
Report write to Foam::Info if the local log switch is true.
Definition: messageStream.H:332