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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2013-2017 OpenFOAM Foundation
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 "patchInjectionBase.H"
29 #include "polyMesh.H"
30 #include "SubField.H"
31 #include "Random.H"
32 #include "triPointRef.H"
33 #include "volFields.H"
35 
36 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
37 
39 (
40  const polyMesh& mesh,
41  const word& patchName
42 )
43 :
44  patchName_(patchName),
45  patchId_(mesh.boundaryMesh().findPatchID(patchName_)),
46  patchArea_(0.0),
47  patchNormal_(),
48  cellOwners_(),
49  triFace_(),
50  triToFace_(),
51  triCumulativeMagSf_(),
52  sumTriMagSf_(Pstream::nProcs() + 1, Zero)
53 {
54  if (patchId_ < 0)
55  {
57  << "Requested patch " << patchName_ << " not found" << nl
58  << "Available patches are: " << mesh.boundaryMesh().names() << nl
59  << exit(FatalError);
60  }
61 
62  updateMesh(mesh);
63 }
64 
65 
67 :
68  patchName_(pib.patchName_),
69  patchId_(pib.patchId_),
70  patchArea_(pib.patchArea_),
71  patchNormal_(pib.patchNormal_),
72  cellOwners_(pib.cellOwners_),
73  triFace_(pib.triFace_),
74  triToFace_(pib.triToFace_),
75  triCumulativeMagSf_(pib.triCumulativeMagSf_),
76  sumTriMagSf_(pib.sumTriMagSf_)
77 {}
78 
79 
80 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
81 
83 {
84  // Set/cache the injector cells
85  const polyPatch& patch = mesh.boundaryMesh()[patchId_];
86  const pointField& points = patch.points();
87 
88  cellOwners_ = patch.faceCells();
89 
90  // Triangulate the patch faces and create addressing
91  DynamicList<label> triToFace(2*patch.size());
92  DynamicList<scalar> triMagSf(2*patch.size());
94  DynamicList<face> tris(5);
95 
96  // Set zero value at the start of the tri area list
97  triMagSf.append(0.0);
98 
99  forAll(patch, facei)
100  {
101  const face& f = patch[facei];
102 
103  tris.clear();
104  f.triangles(points, tris);
105 
106  forAll(tris, i)
107  {
108  triToFace.append(facei);
109  triFace.append(tris[i]);
110  triMagSf.append(tris[i].mag(points));
111  }
112  }
113 
114  forAll(sumTriMagSf_, i)
115  {
116  sumTriMagSf_[i] = 0.0;
117  }
118 
119  sumTriMagSf_[Pstream::myProcNo() + 1] = sum(triMagSf);
120 
122  Pstream::listCombineScatter(sumTriMagSf_);
123 
124  for (label i = 1; i < triMagSf.size(); i++)
125  {
126  triMagSf[i] += triMagSf[i-1];
127  }
128 
129  // Transfer to persistent storage
130  triFace_.transfer(triFace);
131  triToFace_.transfer(triToFace);
132  triCumulativeMagSf_.transfer(triMagSf);
133 
134  // Convert sumTriMagSf_ into cumulative sum of areas per proc
135  for (label i = 1; i < sumTriMagSf_.size(); i++)
136  {
137  sumTriMagSf_[i] += sumTriMagSf_[i-1];
138  }
139 
140  const scalarField magSf(mag(patch.faceAreas()));
141  patchArea_ = sum(magSf);
142  patchNormal_ = patch.faceAreas()/magSf;
143  reduce(patchArea_, sumOp<scalar>());
144 }
145 
146 
148 (
149  const fvMesh& mesh,
150  Random& rnd,
151  vector& position,
152  label& cellOwner,
153  label& tetFacei,
154  label& tetPti
155 )
156 {
157  scalar areaFraction = rnd.globalPosition(scalar(0), patchArea_);
158 
159  if (cellOwners_.size() > 0)
160  {
161  // Determine which processor to inject from
162  label proci = 0;
163  forAllReverse(sumTriMagSf_, i)
164  {
165  if (areaFraction >= sumTriMagSf_[i])
166  {
167  proci = i;
168  break;
169  }
170  }
171 
172  if (Pstream::myProcNo() == proci)
173  {
174  // Find corresponding decomposed face triangle
175  label trii = 0;
176  scalar offset = sumTriMagSf_[proci];
177  forAllReverse(triCumulativeMagSf_, i)
178  {
179  if (areaFraction > triCumulativeMagSf_[i] + offset)
180  {
181  trii = i;
182  break;
183  }
184  }
185 
186  // Set cellOwner
187  label facei = triToFace_[trii];
188  cellOwner = cellOwners_[facei];
189 
190  // Find random point in triangle
191  const polyPatch& patch = mesh.boundaryMesh()[patchId_];
192  const pointField& points = patch.points();
193  const face& tf = triFace_[trii];
194  const triPointRef tri(points[tf[0]], points[tf[1]], points[tf[2]]);
195  const point pf(tri.randomPoint(rnd));
196 
197  // Position perturbed away from face (into domain)
198  const scalar a = rnd.position(scalar(0.1), scalar(0.5));
199  const vector& pc = mesh.cellCentres()[cellOwner];
200  const vector d =
201  mag((pf - pc) & patchNormal_[facei])*patchNormal_[facei];
202 
203  position = pf - a*d;
204 
205  // Try to find tetFacei and tetPti in the current position
206  mesh.findTetFacePt(cellOwner, position, tetFacei, tetPti);
207 
208  // tetFacei and tetPti not found, check if the cell has changed
209  if (tetFacei == -1 ||tetPti == -1)
210  {
211  mesh.findCellFacePt(position, cellOwner, tetFacei, tetPti);
212  }
213 
214  // Both searches failed, choose a random position within
215  // the original cell
216  if (tetFacei == -1 ||tetPti == -1)
217  {
218  // Reset cellOwner
219  cellOwner = cellOwners_[facei];
220  const scalarField& V = mesh.V();
221 
222  // Construct cell tet indices
223  const List<tetIndices> cellTetIs =
225 
226  // Construct cell tet volume fractions
227  scalarList cTetVFrac(cellTetIs.size(), Zero);
228  for (label teti=1; teti<cellTetIs.size()-1; teti++)
229  {
230  cTetVFrac[teti] =
231  cTetVFrac[teti-1]
232  + cellTetIs[teti].tet(mesh).mag()/V[cellOwner];
233  }
234  cTetVFrac.last() = 1;
235 
236  // Set new particle position
237  const scalar volFrac = rnd.sample01<scalar>();
238  label teti = 0;
239  forAll(cTetVFrac, vfI)
240  {
241  if (cTetVFrac[vfI] > volFrac)
242  {
243  teti = vfI;
244  break;
245  }
246  }
247  position = cellTetIs[teti].tet(mesh).randomPoint(rnd);
248  tetFacei = cellTetIs[teti].face();
249  tetPti = cellTetIs[teti].tetPt();
250  }
251  }
252  else
253  {
254  cellOwner = -1;
255  tetFacei = -1;
256  tetPti = -1;
257 
258  // Dummy position
259  position = pTraits<vector>::max;
260  }
261  }
262  else
263  {
264  cellOwner = -1;
265  tetFacei = -1;
266  tetPti = -1;
267 
268  // Dummy position
269  position = pTraits<vector>::max;
270  }
271 }
272 
273 
274 // ************************************************************************* //
volFields.H
Foam::Random
Random number generator.
Definition: Random.H:59
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
SubField.H
Foam::triangle::randomPoint
Point randomPoint(Random &rndGen) const
Return a random point on the triangle from a uniform.
Definition: triangleI.H:254
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
Foam::DynamicList< label >
Foam::Random::sample01
Type sample01()
Return a sample whose components lie in the range [0,1].
Definition: RandomTemplates.C:36
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:435
triPointRef.H
polyMesh.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
polyMeshTetDecomposition.H
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::triangle
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:62
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::patchInjectionBase::patchInjectionBase
patchInjectionBase(const polyMesh &mesh, const word &patchName)
Construct from mesh and patch name.
Definition: patchInjectionBase.C:39
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::Field< vector >
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:348
Foam::patchInjectionBase::updateMesh
virtual void updateMesh(const polyMesh &mesh)
Update patch geometry and derived info for injection locations.
Definition: patchInjectionBase.C:82
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:1302
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:84
patchInjectionBase.H
Foam::maxEqOp
Definition: ops.H:80
Random.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:444
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:290
Foam::primitiveMesh::cellCentres
const vectorField & cellCentres() const
Definition: primitiveMeshCellCentresAndVols.C:176
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::triFace
A triangular face using a FixedList of labels corresponding to mesh vertices.
Definition: triFace.H:70
f
labelList f(nPoints)
Foam::Random::position
Type position(const Type &start, const Type &end)
Return a sample on the interval [start,end].
Definition: RandomTemplates.C:62
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::Vector< scalar >
Foam::patchInjectionBase
Definition: patchInjectionBase.H:64
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:102
Foam::pTraits
Traits class for primitives.
Definition: pTraits.H:52
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:327
Foam::polyMeshTetDecomposition::cellTetIndices
static List< tetIndices > cellTetIndices(const polyMesh &mesh, label cI)
Return the tet decomposition of the given cell, see.
Definition: polyMeshTetDecomposition.C:527
forAllReverse
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:303
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:74
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:432
Foam::polyMesh::findTetFacePt
void findTetFacePt(const label celli, const point &p, label &tetFacei, label &tetPti) const
Find the tetFacei and tetPti for point p in celli.
Definition: polyMesh.C:1327
triFace
face triFace(3)
Foam::Random::globalPosition
Type globalPosition(const Type &start, const Type &end)
Return a sample on the interval [start,end].
Definition: RandomTemplates.C:126
Foam::fvMesh::V
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
Definition: fvMeshGeometry.C:190
Foam::patchInjectionBase::setPositionAndCell
virtual void setPositionAndCell(const fvMesh &mesh, Random &rnd, vector &position, label &cellOwner, label &tetFacei, label &tetPti)
Set the injection position and owner cell, tetFace and tetPt.
Definition: patchInjectionBase.C:148