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-2016 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 
125 
126  for (label i = 1; i < triMagSf.size(); i++)
127  {
128  triMagSf[i] += triMagSf[i-1];
129  }
130 
131  // Transfer to persistent storage
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;
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 = rnd.globalPosition(scalar(0), patchArea_);
160 
161  if (cellOwners_.size() > 0)
162  {
163  // Determine which processor to inject from
164  label proci = 0;
166  {
167  if (areaFraction >= sumTriMagSf_[i])
168  {
169  proci = i;
170  break;
171  }
172  }
173 
174  if (Pstream::myProcNo() == proci)
175  {
176  // Find corresponding decomposed face triangle
177  label triI = 0;
178  scalar offset = sumTriMagSf_[proci];
180  {
181  if (areaFraction > triCumulativeMagSf_[i] + offset)
182  {
183  triI = i;
184  break;
185  }
186  }
187 
188  // Set cellOwner
189  label facei = triToFace_[triI];
190  cellOwner = cellOwners_[facei];
191 
192  // Find random point in triangle
193  const polyPatch& patch = mesh.boundaryMesh()[patchId_];
194  const pointField& points = patch.points();
195  const face& tf = triFace_[triI];
196  const triPointRef tri(points[tf[0]], points[tf[1]], points[tf[2]]);
197  const point pf(tri.randomPoint(rnd));
198 
199  // Position perturbed away from face (into domain)
200  const scalar a = rnd.position(scalar(0.1), scalar(0.5));
201  const vector& pc = mesh.cellCentres()[cellOwner];
202  const vector d = mag(pf - pc)*patchNormal_[facei];
203 
204  position = pf - a*d;
205 
206  // The position is between the face and cell centre, which could
207  // be in any tet of the decomposed cell, so arbitrarily choose the
208  // first face of the cell as the tetFace and the first point after
209  // the base point on the face as the tetPt. The tracking will pick
210  // the cell consistent with the motion in the first tracking step
211  tetFacei = mesh.cells()[cellOwner][0];
212  tetPtI = 1;
213  }
214  else
215  {
216  cellOwner = -1;
217  tetFacei = -1;
218  tetPtI = -1;
219 
220  // Dummy position
221  position = pTraits<vector>::max;
222  }
223  }
224  else
225  {
226  cellOwner = -1;
227  tetFacei = -1;
228  tetPtI = -1;
229 
230  // Dummy position
231  position = pTraits<vector>::max;
232  }
233 }
234 
235 
236 // ************************************************************************* //
const vectorField::subField faceAreas() const
Return face normals.
Definition: polyPatch.C:290
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:57
labelList triToFace_
Addressing from per triangle to patch face.
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
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.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
wordList names() const
Return a list of patch names.
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:417
Traits class for primitives.
Definition: pTraits.H:50
const Field< PointType > & points() const
Return reference to global points.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:440
Type globalPosition(const Type &start, const Type &end)
Return a sample between start and end.
Random number generator.
Definition: cachedRandom.H:63
patchInjectionBase(const polyMesh &mesh, const word &patchName)
Construct from mesh and patch name.
virtual void updateMesh(const polyMesh &mesh)
Update patch geometry and derived info for injection locations.
const cellList & cells() const
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
const tensorField & tf
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
vectorList patchNormal_
Patch face normal directions.
Point randomPoint(Random &rndGen) const
Return a random point on the triangle from a uniform.
Definition: triangleI.H:232
const pointField & points
A class for handling words, derived from string.
Definition: word.H:59
A triangular face using a FixedList of labels corresponding to mesh vertices.
Definition: triFace.H:68
scalarList sumTriMagSf_
Cumulative area fractions per processor.
face triFace(3)
const vectorField & cellCentres() const
const label patchId_
Patch ID.
scalarList triCumulativeMagSf_
Cumulative triangle area per triangle face.
static const char nl
Definition: Ostream.H:262
labelList f(nPoints)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
scalar patchArea_
Patch area - total across all processors.
const labelUList & faceCells() const
Return face-cell addressing.
Definition: polyPatch.C:315
labelList cellOwners_
List of cell labels corresponding to injector positions.
label triangles(const pointField &points, label &triI, faceList &triFaces) const
Split into triangles using existing points.
Definition: face.C:829
dimensioned< scalar > mag(const dimensioned< Type > &)
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
Type position(const Type &start, const Type &end)
Return a sample between start and end.
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:224
label findPatchID(const word &patchName) const
Find patch index given a name.
virtual ~patchInjectionBase()
Destructor.
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:365
faceList triFace_
Decomposed patch faces as a list of triangles.