patchInjectionBase.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2013-2024 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 "injectionModel.H"
28 #include "polyMesh.H"
29 #include "SubField.H"
30 #include "randomGenerator.H"
31 #include "triPointRef.H"
32 #include "volFields.H"
34 #include "polygonTriangulate.H"
35 
36 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
37 
39 (
40  const polyMesh& mesh,
41  const word& patchName
42 )
43 :
44  patchName_(patchName),
45  patchId_(mesh.boundaryMesh().findIndex(patchName_)),
46  sumProcArea_(),
47  sumFaceArea_(),
48  sumFaceTriArea_()
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  topoChange(mesh);
59 }
60 
61 
63 :
64  patchName_(pib.patchName_),
65  patchId_(pib.patchId_),
66  sumProcArea_(pib.sumProcArea_),
67  sumFaceArea_(pib.sumFaceArea_),
68  sumFaceTriArea_(pib.sumFaceTriArea_)
69 {}
70 
71 
72 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
73 
75 {}
76 
77 
78 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
79 
81 {
82  // Set/cache the injector cells
83  const polyPatch& patch = mesh.boundaryMesh()[patchId_];
84 
85  // Initialise
86  sumProcArea_.resize(Pstream::nProcs());
87  sumProcArea_ = 0;
88  sumFaceArea_.resize(patch.size());
89  sumFaceArea_ = 0;
90  sumFaceTriArea_.resize(patch.size());
91  forAll(patch, patchFacei)
92  {
93  sumFaceTriArea_[patchFacei].resize(patch[patchFacei].nTriangles());
94  sumFaceTriArea_[patchFacei] = 0;
95  }
96 
97  // Cumulatively sum up the areas through the local patch
98  scalar patchArea = 0;
99  forAll(patch, patchFacei)
100  {
101  const label facei = patchFacei + patch.start();
102  const label celli = patch.faceCells()[patchFacei];
103 
104  scalar patchFaceArea = 0;
105  for
106  (
107  label patchFaceTrii = 0;
108  patchFaceTrii < patch[patchFacei].nTriangles();
109  ++ patchFaceTrii
110  )
111  {
112  const tetIndices tet(celli, facei, patchFaceTrii + 1);
113 
114  patchFaceArea += tet.faceTri(mesh).mag();
115  sumFaceTriArea_[patchFacei][patchFaceTrii] = patchFaceArea;
116  }
117 
118  patchArea += patchFaceArea;
119  sumFaceArea_[patchFacei] = patchArea;
120  }
121 
122  // Cumulatively sum the total areas across the processors
123  sumProcArea_[Pstream::myProcNo()] = patchArea;
124  Pstream::listCombineGather(sumProcArea_, maxEqOp<scalar>());
125  Pstream::listCombineScatter(sumProcArea_);
126  for (label proci = 1; proci < Pstream::nProcs(); proci ++)
127  {
128  sumProcArea_[proci] += sumProcArea_[proci - 1];
129  }
130 }
131 
132 
134 (
135  const fvMesh& mesh,
137  barycentric& coordinates,
138  label& celli,
139  label& tetFacei,
140  label& tetPti,
141  label& facei
142 )
143 {
144  // Linear searching for area fractions
145  auto findArea = []
146  (
147  const scalarList& areas,
148  scalar& area
149  )
150  {
151  for (label i = areas.size(); i > 0; i --)
152  {
153  if (area >= areas[i - 1])
154  {
155  area -= areas[i - 1];
156  return i;
157  }
158  }
159 
160  return label(0);
161  };
162 
163  const polyPatch& patch = mesh.boundaryMesh()[patchId_];
164 
165  scalar area = injectionModel::globalScalar01(rndGen)*sumProcArea_.last();
166 
167  if (patch.size() > 0)
168  {
169  // Determine which processor to inject from
170  const label proci = findArea(sumProcArea_, area);
171 
172  // If this processor...
173  if (Pstream::myProcNo() == proci)
174  {
175  // Determine the face to inject from
176  const label patchFacei = findArea(sumFaceArea_, area);
177 
178  // Determine the face-tri to inject from
179  const label patchFaceTrii =
180  findArea(sumFaceTriArea_[patchFacei], area);
181 
182  // Set the topology
184  coordinates = barycentric(0, r.a(), r.b(), r.c());
185  celli = mesh.faceOwner()[patch.start() + patchFacei];
186  tetFacei = patch.start() + patchFacei;
187  tetPti = patchFaceTrii + 1;
188  facei = patch.start() + patchFacei;
189  }
190  else
191  {
192  coordinates = barycentric::uniform(NaN);
193  celli = -1;
194  tetFacei = -1;
195  tetPti = -1;
196  facei = -1;
197  }
198  }
199  else
200  {
201  coordinates = barycentric::uniform(NaN);
202  celli = -1;
203  tetFacei = -1;
204  tetPti = -1;
205  facei = -1;
206  }
207 }
208 
209 
210 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Templated 2D Barycentric derived from VectorSpace. Has 3 components, one of which is redundant.
Definition: Barycentric2D.H:53
const Cmpt & a() const
const Cmpt & b() const
const Cmpt & c() const
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
void resize(const label)
Alias for setSize(const label)
Definition: PtrListI.H:32
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:411
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
static Form uniform(const Cmpt &s)
Return a VectorSpace with all elements = s.
Definition: VectorSpaceI.H:168
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:99
static scalar globalScalar01(randomGenerator &rndGen)
Return a scalar uniformly distributed between zero and one. Samples.
Base class for patch-based injection models.
virtual ~patchInjectionBase()
Destructor.
const word patchName_
Patch name.
const label patchId_
Patch ID.
patchInjectionBase(const polyMesh &mesh, const word &patchName)
Construct from mesh and patch name.
virtual void topoChange(const polyMesh &mesh)
Update patch geometry and derived info for injection locations.
virtual void setPositionAndCell(const fvMesh &mesh, randomGenerator &rndGen, barycentric &coordinates, label &celli, label &tetFacei, label &tetPti, label &facei)
Set the injection position and owner cell, tetFace and tetPt.
wordList names() const
Return the list of patch names.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1339
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:404
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:70
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:280
const labelUList & faceCells() const
Return face-cell addressing.
Definition: polyPatch.C:313
Random number generator.
Storage and named access for the indices of a tet which is part of the decomposition of a cell.
Definition: tetIndices.H:82
triPointRef faceTri(const polyMesh &mesh) const
Return the geometry corresponding to the tri on the face for.
Definition: tetIndicesI.H:123
scalar mag() const
Return scalar magnitude.
Definition: triangleI.H:103
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Barycentric< scalar > barycentric
A scalar version of the templated Barycentric.
Definition: barycentric.H:45
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
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
error FatalError
static const char nl
Definition: Ostream.H:266
barycentric2D barycentric2D01(randomGenerator &rndGen)
Generate a random barycentric coordinate within the unit triangle.
Definition: barycentric2D.C:31
randomGenerator rndGen(653213)