betaMax.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) 2020-2023 PCOpt/NTUA
9  Copyright (C) 2020-2023 FOSS GP
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "betaMax.H"
30 #include "EdgeMap.H"
31 #include "syncTools.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
39 }
40 
41 
42 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
43 
44 Foam::scalar Foam::betaMax::computeLength(const dictionary& dict) const
45 {
46  scalar length = Zero;
47  // If length is not provided explicitly, loop over the provided patches
48  // and compute the hydraulic diamater
49  const dictionary& DarcyDict = dict.subDict(type() + "Coeffs");
50  if (!DarcyDict.readIfPresent("length", length))
51  {
52  const labelHashSet inletPatches =
54  (
55  DarcyDict.get<wordRes>("inletPatches")
56  );
57 
58  // If 2D, use the inlet area divided by the depth in the empty direction
59  if (mesh_.nGeometricD() != label(3))
60  {
61  // Accumulate area
62  for (const label pI : inletPatches)
63  {
64  const fvPatch& patch = mesh_.boundary()[pI];
65  length += gSum(patch.magSf());
66  }
67 
68  // Divide with the span in the empty direction
69  const Vector<label>& geometricD = mesh_.geometricD();
70  const boundBox& bounds = mesh_.bounds();
71  forAll(geometricD, iDir)
72  {
73  if (geometricD[iDir] == -1)
74  {
75  length /= bounds.span()[iDir];
76  }
77  }
78  }
79  // If 3D, use the inlet hydraulic diameter
80  else
81  {
82  scalar perimeter = Zero;
83  scalar area = Zero;
84  for (const label pI : inletPatches)
85  {
86  const polyPatch& patch = mesh_.boundaryMesh()[pI];
87  // Accumulate perimeter
88  const edgeList& edges = patch.edges();
89  const vectorField& points = patch.localPoints();
90  const label nInternalEdges = patch.nInternalEdges();
91  const label nEdges = patch.nEdges();
92  // Processor edges should not be accounted for
93  boolList isProcessorEdge = markProcessorEdges(patch);
94  label nActiveEdges(0);
95  forAll(isProcessorEdge, beI)
96  {
97  if (!isProcessorEdge[beI])
98  {
99  perimeter += edges[nInternalEdges + beI].mag(points);
100  nActiveEdges++;
101  }
102  }
103 
104  if (debug > 1)
105  {
106  Info<< "patch:: " << patch.name() << nl
107  << "Number of boundary edges "
108  << returnReduce(nEdges - nInternalEdges, sumOp<label>())
109  << ", Number of non-processor edges "
110  << returnReduce(nActiveEdges, sumOp<label>()) << endl;
111  }
112 
113  // Accumulate area
114  area += sum(patch.magFaceAreas());
115  }
116 
117  reduce(perimeter, sumOp<scalar>());
118  reduce(area, sumOp<scalar>());
119 
120  length = scalar(4)*area/perimeter;
121  }
122  }
123 
124  return length;
125 }
126 
127 
129 (
130  const polyPatch& patch
131 ) const
132 {
133  const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
134  const label nNonProcessor = pbm.nNonProcessor();
135 
136  // Processor edges will artificially increase the perimeter of the inlet.
137  // We need to purge them.
138 
139  // Mark all edges connected to a processor patch
140  label nProcEdges(0);
141  for (label procI = nNonProcessor; procI < pbm.size() ; ++procI)
142  {
143  const polyPatch& procPatch = pbm[procI];
144  nProcEdges += procPatch.nEdges() - procPatch.nInternalEdges();
145  }
146 
147  EdgeMap<bool> isInletEdge(nProcEdges);
148 
149  for (label procI = nNonProcessor; procI < pbm.size() ; ++procI)
150  {
151  const polyPatch& procPatch = pbm[procI];
152  const labelList& procMp = procPatch.meshPoints();
153  const label procInternalEdges = procPatch.nInternalEdges();
154  const label procEdges = procPatch.nEdges();
155 
156  for (label edgeI = procInternalEdges; edgeI < procEdges; ++edgeI)
157  {
158  const edge& e = procPatch.edges()[edgeI];
159  const edge meshE = edge(procMp[e[0]], procMp[e[1]]);
160  isInletEdge.insert(meshE, false);
161  }
162  }
163 
164  // Loop over inlet edges to mark common edges with processor patches
165  const label nInternalEdges = patch.nInternalEdges();
166  const label nEdges = patch.nEdges();
167 
168  const edgeList& edges = patch.edges();
169  const labelList& mp = patch.meshPoints();
170  for (label edgeI = nInternalEdges; edgeI < nEdges; ++edgeI)
171  {
172  const edge& e = edges[edgeI];
173  const edge meshE = edge(mp[e[0]], mp[e[1]]);
174  auto iter = isInletEdge.find(meshE);
175 
176  if (iter.found())
177  {
178  iter.val() = true;
179  }
180  }
181 
182  // A special case is a processor patch intersecting the inlet patches on a
183  // (true) boundary edge of the latter. Use syncEdgeMap to make sure these
184  // edges don't make it to the final list
186  (
187  pbm.mesh(),
188  isInletEdge,
189  andEqOp<bool>()
190  );
191 
192  // Now loop over the inlet faces once more and mark the common edges with
193  // processor boundaries
194  boolList isProcessorEdge(nEdges - nInternalEdges, false);
195  for (label edgeI = nInternalEdges; edgeI < nEdges; ++edgeI)
196  {
197  const edge& e = edges[edgeI];
198  const edge meshE = edge(mp[e[0]], mp[e[1]]);
199  const auto iter = isInletEdge.cfind(meshE);
200 
201  if (iter.found() && iter.val())
202  {
203  isProcessorEdge[edgeI - nInternalEdges] = true;
204  }
205  }
206 
207  return isProcessorEdge;
208 }
209 
210 
211 
212 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
213 
214 Foam::betaMax::betaMax
215 (
216  const fvMesh& mesh,
217  const dictionary& dict
218 )
219 :
220  mesh_(mesh),
221  value_(dict.getOrDefault<scalar>("betaMax", Zero))
222 {}
223 
224 
225 // * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
226 
228 (
229  const fvMesh& mesh,
230  const dictionary& dict
231 )
232 {
233  const word modelType(dict.getOrDefault<word>("betaMaxType", "value"));
234 
235  auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
236 
237  Info<< "betaMax type " << modelType << endl;
238 
239  if (!cstrIter.found())
240  {
242  (
243  dict,
244  "betaMaxType",
245  modelType,
246  *dictionaryConstructorTablePtr_
247  ) << exit(FatalIOError);
248  }
250  return autoPtr<betaMax>(cstrIter()(mesh, dict));
251 }
252 
253 
254 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
255 
256 Foam::scalar Foam::betaMax::value() const
257 {
258  return value_;
259 }
260 
261 
262 // ************************************************************************* //
const polyBoundaryMesh & pbm
dictionary dict
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1)
const fvMesh & mesh_
Reference to mesh.
Definition: betaMax.H:73
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
List< edge > edgeList
List of edge.
Definition: edgeList.H:32
labelHashSet patchSet(const UList< wordRe > &select, const bool warnNotFound=true, const bool useGroups=true) const
Return the set of patch IDs corresponding to the given names.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:70
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
label nGeometricD() const
Return the number of valid geometric dimensions in the mesh.
Definition: polyMesh.C:876
static autoPtr< betaMax > New(const fvMesh &mesh, const dictionary &dict)
Construct and return the selected betaMax model.
Definition: betaMax.C:221
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
const Vector< label > & geometricD() const
Return the vector of geometric directions in mesh.
Definition: polyMesh.C:865
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
dynamicFvMesh & mesh
Type gSum(const FieldField< Field, Type > &f)
const pointField & points
const polyMesh & mesh() const noexcept
Return the mesh reference.
const wordList area
Standard area field types (scalar, vector, tensor, etc)
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition: polyMesh.H:608
A class for handling words, derived from Foam::string.
Definition: word.H:63
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
boolList markProcessorEdges(const polyPatch &patch) const
Mark all common inlet - processor edges.
Definition: betaMax.C:122
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:53
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
int debug
Static debugging option.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
Base class for selecting the betaMax value, i.e. the value multiplying the Brinkman penalisation term...
Definition: betaMax.H:49
defineTypeNameAndDebug(combustionModel, 0)
scalar computeLength(const dictionary &dict) const
Compute the characteristic length.
Definition: betaMax.C:37
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
const std::string patch
OpenFOAM patch number as a std::string.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
const fvBoundaryMesh & boundary() const noexcept
Return reference to boundary mesh.
Definition: fvMesh.H:395
const boundBox & bounds() const noexcept
Return mesh bounding box.
Definition: polyMesh.H:616
Field< vector > vectorField
Specialisation of Field<T> for vector.
virtual scalar value() const
Get value.
Definition: betaMax.C:249
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
List< label > labelList
A List of labels.
Definition: List.H:62
label nNonProcessor() const
The number of patches before the first processor patch.
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
Definition: error.H:635
List< bool > boolList
A List of bools.
Definition: List.H:60
static void syncEdgeMap(const polyMesh &mesh, EdgeMap< T > &edgeValues, const CombineOp &cop, const TransformOp &top)
Synchronize values on selected edges.
const dimensionedScalar mp
Proton mass.
Namespace for OpenFOAM.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127