-
Notifications
You must be signed in to change notification settings - Fork 1
/
particle.H
705 lines (521 loc) · 21.6 KB
/
particle.H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::particle
Description
Base particle class
\*---------------------------------------------------------------------------*/
#ifndef particle_H
#define particle_H
#include "vector.H"
#include "barycentric.H"
#include "barycentricTensor.H"
#include "Cloud.H"
#include "IDLList.H"
#include "pointField.H"
#include "faceList.H"
#include "OFstream.H"
#include "tetPointRef.H"
#include "FixedList.H"
#include "polyMeshTetDecomposition.H"
#include "particleMacros.H"
#include "vectorTensorTransform.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class particle;
class polyPatch;
class cyclicPolyPatch;
class processorPolyPatch;
class symmetryPlanePolyPatch;
class symmetryPolyPatch;
class wallPolyPatch;
class wedgePolyPatch;
// Forward declaration of friend functions and operators
Ostream& operator<<
(
Ostream&,
const particle&
);
bool operator==(const particle&, const particle&);
bool operator!=(const particle&, const particle&);
/*---------------------------------------------------------------------------*\
Class Particle Declaration
\*---------------------------------------------------------------------------*/
class particle
:
public IDLList<particle>::link
{
// Private member data
//- Size in bytes of the position data
static const std::size_t sizeofPosition_;
//- Size in bytes of the fields
static const std::size_t sizeofFields_;
//- The factor by which the displacement is increased when passing
// through negative space. This should be slightly bigger than one.
// This is needed as a straight trajectory can form a closed loop
// through regions of overlapping positive and negative space, leading
// to a track which never ends. By increasing the rate of displacement
// through negative regions, the change in track fraction over this
// part of the loop no longer exactly cancels the change over the
// positive part, and the track therefore terminates.
static const scalar negativeSpaceDisplacementFactor;
public:
template<class CloudType>
class TrackingData
{
// Private data
//- Reference to the cloud containing (this) particle
CloudType& cloud_;
public:
// Public data
typedef CloudType cloudType;
//- Flag to switch processor
bool switchProcessor;
//- Flag to indicate whether to keep particle (false = delete)
bool keepParticle;
// Constructor
TrackingData(CloudType& cloud)
:
cloud_(cloud)
{}
// Member functions
//- Return a reference to the cloud
CloudType& cloud()
{
return cloud_;
}
};
private:
// Private data
//- Reference to the polyMesh database
const polyMesh& mesh_;
//- Coordinates of particle
barycentric coordinates_;
//- Index of the cell it is in
label celli_;
//- Index of the face that owns the decomposed tet that the
// particle is in
label tetFacei_;
//- Index of the point on the face that defines the decomposed
// tet that the particle is in. Relative to the face base
// point.
label tetPti_;
//- Face index if the particle is on a face otherwise -1
label facei_;
//- Fraction of time-step completed
scalar stepFraction_;
//- Originating processor id
label origProc_;
//- Local particle id on originating processor
label origId_;
private:
// Private Member Functions
// Tetrahedra functions
//- Get the vertices of the current tet
void stationaryTetGeometry
(
vector& centre,
vector& base,
vector& vertex1,
vector& vertex2
) const;
//- Get the transformation associated with the current tet. This
// will convert a barycentric position within the tet to a
// cartesian position in the global coordinate system. The
// conversion is x = A & y, where x is the cartesian position, y is
// the barycentric position and A is the transformation tensor.
barycentricTensor stationaryTetTransform() const;
//- Get the reverse transform associated with the current tet. The
// conversion is detA*y = (x - centre) & T. The variables x, y and
// centre have the same meaning as for the forward transform. T is
// the transposed inverse of the forward transform tensor, A,
// multiplied by its determinant, detA. This separation allows
// the barycentric tracking algorithm to function on inverted or
// degenerate tetrahedra.
void stationaryTetReverseTransform
(
vector& centre,
scalar& detA,
barycentricTensor& T
) const;
//- Get the vertices of the current moving tet. Two values are
// returned for each vertex. The first is a constant, and the
// second is a linear coefficient of the track fraction.
void movingTetGeometry
(
const scalar endStepFraction,
Pair<vector>& centre,
Pair<vector>& base,
Pair<vector>& vertex1,
Pair<vector>& vertex2
) const;
//- Get the transformation associated with the current, moving, tet.
// This is of the same form as for the static case. As with the
// moving geometry, a linear function of the tracking fraction is
// returned for each component.
Pair<barycentricTensor> movingTetTransform
(
const scalar endStepFraction
) const;
//- Get the reverse transformation associated with the current,
// moving, tet. This is of the same form as for the static case. As
// with the moving geometry, a function of the tracking fraction is
// returned for each component. The functions are higher order than
// for the forward transform; the determinant is cubic, and the
// tensor is quadratic.
void movingTetReverseTransform
(
const scalar endStepFraction,
Pair<vector>& centre,
FixedList<scalar, 4>& detA,
FixedList<barycentricTensor, 3>& T
) const;
// Transformations
//- Reflection transform. Corrects the coordinates when the particle
// moves between two tets which share a base vertex, but for which
// the other two non cell-centre vertices are reversed. All hits
// which retain the same face behave this way, as do face hits.
void reflect();
//- Rotation transform. Corrects the coordinates when the particle
// moves between two tets with different base vertices, but are
// otherwise similarly oriented. Hits which change the face within
// the cell make use of both this and the reflect transform.
void rotate(const bool direction);
// Topology changes
//- Change tet within a cell. Called after a triangle is hit.
void changeTet(const label tetTriI);
//- Change tet face within a cell. Called by changeTet.
void changeFace(const label tetTriI);
//- Change cell. Called when the particle hits an internal face.
void changeCell();
// Geometry changes
//- Locate the particle at the given position
void locate
(
const vector& position,
const vector* direction,
const label celli,
const bool boundaryFail,
const string boundaryMsg
);
protected:
// Patch interactions
//- Overridable function to handle the particle hitting a face
template<class TrackData>
void hitFace(TrackData& td);
//- Overridable function to handle the particle hitting a
// patch. Executed before other patch-hitting functions.
// trackFraction is passed in to allow mesh motion to
// interpolate in time to the correct face state.
template<class TrackData>
bool hitPatch
(
const polyPatch&,
TrackData& td,
const label patchi,
const scalar trackFraction,
const tetIndices& tetIs
);
//- Overridable function to handle the particle hitting a wedgePatch
template<class TrackData>
void hitWedgePatch(const wedgePolyPatch&, TrackData& td);
//- Overridable function to handle the particle hitting a
// symmetryPlanePatch
template<class TrackData>
void hitSymmetryPlanePatch
(
const symmetryPlanePolyPatch&,
TrackData& td
);
//- Overridable function to handle the particle hitting a
// symmetryPatch
template<class TrackData>
void hitSymmetryPatch(const symmetryPolyPatch&, TrackData& td);
//- Overridable function to handle the particle hitting a cyclicPatch
template<class TrackData>
void hitCyclicPatch(const cyclicPolyPatch&, TrackData& td);
//- Overridable function to handle the particle hitting a cyclicAMIPatch
template<class TrackData>
void hitCyclicAMIPatch
(
const cyclicAMIPolyPatch&,
TrackData& td,
const vector& direction
);
//- Overridable function to handle the particle hitting a
// processorPatch
template<class TrackData>
void hitProcessorPatch(const processorPolyPatch&, TrackData& td);
//- Overridable function to handle the particle hitting a wallPatch
template<class TrackData>
void hitWallPatch
(
const wallPolyPatch&,
TrackData& td,
const tetIndices& tetIs
);
//- Overridable function to handle the particle hitting a
// general patch
template<class TrackData>
void hitPatch(const polyPatch&, TrackData& td);
public:
// Static data members
//- Runtime type information
TypeName("particle");
//- String representation of properties
DefinePropertyList
(
"(coordinatesa coordinatesb coordinatesc coordinatesd) "
"celli tetFacei tetPti facei stepFraction origProc origId"
);
//- Cumulative particle counter - used to provode unique ID
static label particleCount_;
// Constructors
//- Construct from components
particle
(
const polyMesh& mesh,
const barycentric& coordinates,
const label celli,
const label tetFacei,
const label tetPti
);
//- Construct from a position and a cell, searching for the rest of the
// required topology
particle
(
const polyMesh& mesh,
const vector& position,
const label celli
);
//- Construct from Istream
particle(const polyMesh& mesh, Istream&, bool readFields = true);
//- Construct as a copy
particle(const particle& p);
//- Construct as a copy with refernce to a new mesh
particle(const particle& p, const polyMesh& mesh);
//- Construct a clone
virtual autoPtr<particle> clone() const
{
return autoPtr<particle>(new particle(*this));
}
//- Factory class to read-construct particles used for
// parallel transfer
class iNew
{
const polyMesh& mesh_;
public:
iNew(const polyMesh& mesh)
:
mesh_(mesh)
{}
autoPtr<particle> operator()(Istream& is) const
{
return autoPtr<particle>(new particle(mesh_, is, true));
}
};
//- Destructor
virtual ~particle()
{}
// Member Functions
// Access
//- Get unique particle creation id
inline label getNewParticleID() const;
//- Return the mesh database
inline const polyMesh& mesh() const;
//- Return current particle coordinates
inline const barycentric& coordinates() const;
//- Return current cell particle is in
inline label cell() const;
//- Return current tet face particle is in
inline label tetFace() const;
//- Return current tet face particle is in
inline label tetPt() const;
//- Return current face particle is on otherwise -1
inline label face() const;
//- Return the fraction of time-step completed
inline scalar stepFraction() const;
//- Return the fraction of time-step completed
inline scalar& stepFraction();
//- Return the originating processor ID
inline label origProc() const;
//- Return the originating processor ID
inline label& origProc();
//- Return the particle ID on the originating processor
inline label origId() const;
//- Return the particle ID on the originating processor
inline label& origId();
// Check
//- Return the step fraction change within the overall time-step.
// Returns the start value and the change as a scalar pair. Always
// return Pair<scalar>(0, 1), unless sub-cycling is in effect, in
// which case the values will reflect the span of the sub-cycle
// within the time-step.
inline Pair<scalar> stepFractionSpan() const;
//- Return the current fraction within the timestep. This differs
// from the stored step fraction due to sub-cycling.
inline scalar currentTimeFraction() const;
//- Return the indices of the current tet that the
// particle occupies.
inline tetIndices currentTetIndices() const;
//- Return the current tet transformation tensor
inline barycentricTensor currentTetTransform() const;
//- Return the normal of the tri on tetFacei_ for the
// current tet.
inline vector normal() const;
//- Return the normal of the tri on tetFacei_ for the
// current tet at the start of the timestep, i.e. based
// on oldPoints
inline vector oldNormal() const;
//- Is the particle on a face?
inline bool onFace() const;
//- Is the particle on an internal face?
inline bool onInternalFace() const;
//- Is the particle on a boundary face?
inline bool onBoundaryFace() const;
//- Return the index of patch that the particle is on
inline label patch() const;
//- Return current particle position
inline vector position() const;
// Track
//- Track along the displacement for a given fraction of the overall
// step. End when the track is complete, or when a boundary is hit.
// On exit, stepFraction_ will have been incremented to the current
// position, and facei_ will be set to the index of the boundary
// face that was hit, or -1 if the track completed within a cell.
// The proportion of the displacement still to be completed is
// returned.
scalar track
(
const vector& displacement,
const scalar fraction
);
//- As particle::track, but also stops on internal faces.
scalar trackToFace
(
const vector& displacement,
const scalar fraction
);
//- As particle::trackToFace, but also stops on tet triangles. On
// exit, tetTriI is set to the index of the tet triangle that was
// hit, or -1 if the end position was reached.
scalar trackToTri
(
const vector& displacement,
const scalar fraction,
label& tetTriI
);
//- As particle::trackToTri, but for stationary meshes
scalar trackToStationaryTri
(
const vector& displacement,
const scalar fraction,
label& tetTriI
);
//- As particle::trackToTri, but for moving meshes
scalar trackToMovingTri
(
const vector& displacement,
const scalar fraction,
label& tetTriI
);
//- As non-templated particle::trackToFace, but with additional
// boundary handling.
template<class TrackData>
void trackToFace
(
const vector& displacement,
const scalar fraction,
TrackData& td
);
//- Set the constrained components of the particle position to the
// mesh centre.
void constrainToMeshCentre();
// Patch data
//- Get the normal and velocity of the current patch location
void patchData(vector& n, vector& U) const;
// Transformations
//- Transform the physical properties of the particle
// according to the given transformation tensor
virtual void transformProperties(const tensor& T);
//- Transform the physical properties of the particle
// according to the given separation vector
virtual void transformProperties(const vector& separation);
//- The nearest distance to a wall that
// the particle can be in the n direction
virtual scalar wallImpactDistance(const vector& n) const;
// Parallel transfer
//- Convert global addressing to the processor patch
// local equivalents
template<class TrackData>
void prepareForParallelTransfer(const label patchi, TrackData& td);
//- Convert processor patch addressing to the global equivalents
// and set the celli to the face-neighbour
template<class TrackData>
void correctAfterParallelTransfer(const label patchi, TrackData& td);
// Interaction list referral
//- Break the topology and store the particle position so that the
// particle can be referred.
void prepareForInteractionListReferral
(
const vectorTensorTransform& transform
);
//- Correct the topology after referral. The particle may still be
// outside the stored tet and therefore not track-able.
void correctAfterInteractionListReferral(const label celli);
// Decompose and reconstruct
//- Return the tet point approproate for decomposition or reconstruction
// to or from the given mesh.
label procTetPt
(
const polyMesh& procMesh,
const label procCell,
const label procTetFace
) const;
// Mapping
//- Map after a topology change
void autoMap(const vector& position, const mapPolyMesh& mapper);
// I-O
//- Read the fields associated with the owner cloud
template<class CloudType>
static void readFields(CloudType& c);
//- Write the fields associated with the owner cloud
template<class CloudType>
static void writeFields(const CloudType& c);
//- Write the particle position and cell
void writePosition(Ostream&) const;
// Friend Operators
friend Ostream& operator<<(Ostream&, const particle&);
friend bool operator==(const particle& pA, const particle& pB);
friend bool operator!=(const particle& pA, const particle& pB);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "particleI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "particleTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //