patchInjectionBase.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 | Copyright (C) 2013-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "patchInjectionBase.H"
27 #include "polyMesh.H"
28 #include "SubField.H"
29 #include "cachedRandom.H"
30 #include "triPointRef.H"
31 
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 
35 (
36  const polyMesh& mesh,
37  const word& patchName
38 )
39 :
40  patchName_(patchName),
41  patchId_(mesh.boundaryMesh().findPatchID(patchName_)),
42  patchArea_(0.0),
43  patchNormal_(),
44  cellOwners_(),
45  triFace_(),
46  triToFace_(),
47  triCumulativeMagSf_(),
48  sumTriMagSf_(Pstream::nProcs() + 1, 0.0)
49 {
50  if (patchId_ < 0)
51  {
53  << "Requested patch " << patchName_ << " not found" << nl
54  << "Available patches are: " << mesh.boundaryMesh().names() << nl
55  << exit(FatalError);
56  }
57 
58  updateMesh(mesh);
59 }
60 
61 
63 :
64  patchName_(pib.patchName_),
65  patchId_(pib.patchId_),
66  patchArea_(pib.patchArea_),
67  patchNormal_(pib.patchNormal_),
68  cellOwners_(pib.cellOwners_),
69  triFace_(pib.triFace_),
70  triToFace_(pib.triToFace_),
71  triCumulativeMagSf_(pib.triCumulativeMagSf_),
72  sumTriMagSf_(pib.sumTriMagSf_)
73 {}
74 
75 
76 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
77 
79 {}
80 
81 
82 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
83 
85 {
86  // Set/cache the injector cells
87  const polyPatch& patch = mesh.boundaryMesh()[patchId_];
88  const pointField& points = patch.points();
89 
90  cellOwners_ = patch.faceCells();
91 
92  // Triangulate the patch faces and create addressing
93  DynamicList<label> triToFace(2*patch.size());
94  DynamicList<scalar> triMagSf(2*patch.size());
95  DynamicList<face> triFace(2*patch.size());
96  DynamicList<face> tris(5);
97 
98  // Set zero value at the start of the tri area list
99  triMagSf.append(0.0);
100 
101  forAll(patch, faceI)
102  {
103  const face& f = patch[faceI];
104 
105  tris.clear();
106  f.triangles(points, tris);
107 
108  forAll(tris, i)
109  {
110  triToFace.append(faceI);
111  triFace.append(tris[i]);
112  triMagSf.append(tris[i].mag(points));
113  }
114  }
115 
116  forAll(sumTriMagSf_, i)
117  {
118  sumTriMagSf_[i] = 0.0;
119  }
120 
121  sumTriMagSf_[Pstream::myProcNo() + 1] = sum(triMagSf);
122 
124  Pstream::listCombineScatter(sumTriMagSf_);
125 
126  for (label i = 1; i < triMagSf.size(); i++)
127  {
128  triMagSf[i] += triMagSf[i-1];
129  }
130 
131  // Transfer to persistent storage
132  triFace_.transfer(triFace);
133  triToFace_.transfer(triToFace);
134  triCumulativeMagSf_.transfer(triMagSf);
135 
136  // Convert sumTriMagSf_ into cumulative sum of areas per proc
137  for (label i = 1; i < sumTriMagSf_.size(); i++)
138  {
139  sumTriMagSf_[i] += sumTriMagSf_[i-1];
140  }
141 
142  const scalarField magSf(mag(patch.faceAreas()));
143  patchArea_ = sum(magSf);
144  patchNormal_ = patch.faceAreas()/magSf;
145  reduce(patchArea_, sumOp<scalar>());
146 }
147 
148 
150 (
151  const polyMesh& mesh,
152  cachedRandom& rnd,
153  vector& position,
154  label& cellOwner,
155  label& tetFaceI,
156  label& tetPtI
157 )
158 {
159  scalar areaFraction = 0;
160 
161  if (Pstream::master())
162  {
163  areaFraction = rnd.position<scalar>(0, patchArea_);
164  }
165 
166  Pstream::scatter(areaFraction);
167 
168  if (cellOwners_.size() > 0)
169  {
170  // Determine which processor to inject from
171  label procI = 0;
172  forAllReverse(sumTriMagSf_, i)
173  {
174  if (areaFraction >= sumTriMagSf_[i])
175  {
176  procI = i;
177  break;
178  }
179  }
180 
181  if (Pstream::myProcNo() == procI)
182  {
183  // Find corresponding decomposed face triangle
184  label triI = 0;
185  scalar offset = sumTriMagSf_[procI];
186  forAllReverse(triCumulativeMagSf_, i)
187  {
188  if (areaFraction > triCumulativeMagSf_[i] + offset)
189  {
190  triI = i;
191  break;
192  }
193  }
194 
195  // Set cellOwner
196  label faceI = triToFace_[triI];
197  cellOwner = cellOwners_[faceI];
198 
199  // Find random point in triangle
200  const polyPatch& patch = mesh.boundaryMesh()[patchId_];
201  const pointField& points = patch.points();
202  const face& tf = triFace_[triI];
203  const triPointRef tri(points[tf[0]], points[tf[1]], points[tf[2]]);
204  const point pf(tri.randomPoint(rnd));
205 
206  // Position perturbed away from face (into domain)
207  const scalar a = rnd.position(scalar(0.1), scalar(0.5));
208  const vector& pc = mesh.cellCentres()[cellOwner];
209  const vector d = mag(pf - pc)*patchNormal_[faceI];
210 
211  position = pf - a*d;
212 
213  // The position is between the face and cell centre, which could
214  // be in any tet of the decomposed cell, so arbitrarily choose the
215  // first face of the cell as the tetFace and the first point after
216  // the base point on the face as the tetPt. The tracking will pick
217  // the cell consistent with the motion in the first tracking step
218  //tetFaceI = mesh.cells()[cellOwner][0];
219  //tetPtI = 1;
220 
221  //SAF: temporary fix for patchInjection.
222  // This function finds both cellOwner and tetFaceI. The particle
223  // was injected in a non-boundary cell and the tracking function
224  // could not find the cellOwner
226  (
227  position,
228  cellOwner,
229  tetFaceI,
230  tetPtI
231  );
232  }
233  else
234  {
235  cellOwner = -1;
236  tetFaceI = -1;
237  tetPtI = -1;
238 
239  // Dummy position
240  position = pTraits<vector>::max;
241  }
242  }
243  else
244  {
245  cellOwner = -1;
246  tetFaceI = -1;
247  tetPtI = -1;
248 
249  // Dummy position
250  position = pTraits<vector>::max;
251  }
252 }
253 
254 
255 // ************************************************************************* //
Foam::PrimitivePatch::points
const Field< PointType > & points() const
Return reference to global points.
Definition: PrimitivePatchTemplate.H:282
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
SubField.H
Foam::triangle::randomPoint
Point randomPoint(Random &rndGen) const
Return a random point on the triangle from a uniform.
Definition: triangleI.H:245
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::DynamicList< label >
Foam::patchInjectionBase::~patchInjectionBase
virtual ~patchInjectionBase()
Destructor.
Definition: patchInjectionBase.C:78
Foam::maxEqOp
Definition: ops.H:77
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
Definition: gatherScatter.C:147
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
triPointRef.H
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
polyMesh.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
tf
const tensorField & tf
Definition: getPatchFieldTensor.H:36
Foam::triangle
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:59
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
Foam::patchInjectionBase::patchInjectionBase
patchInjectionBase(const polyMesh &mesh, const word &patchName)
Construct from mesh and patch name.
Definition: patchInjectionBase.C:35
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:59
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::cachedRandom
Random number generator.
Definition: cachedRandom.H:63
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::cachedRandom::position
Type position(const Type &start, const Type &end)
Return a sample between start and end.
Definition: cachedRandomTemplates.C:58
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
Foam::DynamicList::clear
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:242
Foam::patchInjectionBase::updateMesh
virtual void updateMesh(const polyMesh &mesh)
Update patch geometry and derived info for injection locations.
Definition: patchInjectionBase.C:84
cachedRandom.H
Foam::FatalError
error FatalError
Foam::polyMesh::findCellFacePt
void findCellFacePt(const point &p, label &celli, label &tetFacei, label &tetPti) const
Find the cell, tetFacei and tetPti for point p.
Definition: polyMesh.C:1204
forAllReverse
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:418
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
patchInjectionBase.H
Foam::polyPatch::faceCells
const labelUList & faceCells() const
Return face-cell addressing.
Definition: polyPatch.C:340
Foam::patchInjectionBase::setPositionAndCell
virtual void setPositionAndCell(const polyMesh &mesh, cachedRandom &rnd, vector &position, label &cellOwner, label &tetFaceI, label &tetPtI)
Set the injection position and owner cell, tetFace and tetPt.
Definition: patchInjectionBase.C:150
Foam::DynamicList::append
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:405
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:399
Foam::Pstream::listCombineGather
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
Definition: combineGatherScatter.C:282
Foam::primitiveMesh::cellCentres
const vectorField & cellCentres() const
Definition: primitiveMeshCellCentresAndVols.C:211
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::sumOp
Definition: ops.H:162
Foam::triFace
A triangular face using a FixedList of labels corresponding to mesh vertices.
Definition: triFace.H:68
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::patchInjectionBase
Definition: patchInjectionBase.H:61
Foam::pTraits
Traits class for primitives.
Definition: pTraits.H:50
Foam::polyPatch::faceAreas
const vectorField::subField faceAreas() const
Return face normals.
Definition: polyPatch.C:314
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::DynamicList::transfer
void transfer(List< T > &)
Transfer contents of the argument List into this.
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:333
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::Pstream::listCombineScatter
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
Definition: combineGatherScatter.C:417
triFace
face triFace(3)