Loading...
Searching...
No Matches
activePressureForceBaffleVelocityFvPatchVectorField.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) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2016-2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
31#include "volFields.H"
32#include "surfaceFields.H"
33#include "cyclicFvPatch.H"
34
35// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
36
39(
40 const fvPatch& p,
42)
43:
44 fixedValueFvPatchVectorField(p, iF),
45 pName_("p"),
46 cyclicPatchName_(),
47 cyclicPatchLabel_(-1),
48 initWallSf_(0),
49 initCyclicSf_(0),
50 nbrCyclicSf_(0),
51 openFraction_(0),
52 openingTime_(0),
53 maxOpenFractionDelta_(0),
54 curTimeIndex_(-1),
55 minThresholdValue_(0),
56 fBased_(1),
57 baffleActivated_(0),
58 opening_(1)
59{}
60
61
64(
66 const fvPatch& p,
68 const fvPatchFieldMapper& mapper
69)
70:
71 fixedValueFvPatchVectorField(ptf, p, iF, mapper),
72 pName_(ptf.pName_),
73 cyclicPatchName_(ptf.cyclicPatchName_),
74 cyclicPatchLabel_(ptf.cyclicPatchLabel_),
75 initWallSf_(ptf.initWallSf_),
76 initCyclicSf_(ptf.initCyclicSf_),
77 nbrCyclicSf_(ptf.nbrCyclicSf_),
78 openFraction_(ptf.openFraction_),
79 openingTime_(ptf.openingTime_),
80 maxOpenFractionDelta_(ptf.maxOpenFractionDelta_),
81 curTimeIndex_(-1),
82 minThresholdValue_(ptf.minThresholdValue_),
83 fBased_(ptf.fBased_),
84 baffleActivated_(ptf.baffleActivated_),
85 opening_(ptf.opening_)
86{}
87
88
91(
92 const fvPatch& p,
94 const dictionary& dict
95)
96:
97 fixedValueFvPatchVectorField(p, iF, dict, IOobjectOption::NO_READ),
98 pName_(dict.getOrDefault<word>("p", "p")),
99 cyclicPatchName_(dict.lookup("cyclicPatch")),
100 cyclicPatchLabel_(p.patch().boundaryMesh().findPatchID(cyclicPatchName_)),
101 initWallSf_(0),
102 initCyclicSf_(0),
103 nbrCyclicSf_(0),
104 openFraction_(dict.get<scalar>("openFraction")),
105 openingTime_(dict.get<scalar>("openingTime")),
106 maxOpenFractionDelta_(dict.get<scalar>("maxOpenFractionDelta")),
107 curTimeIndex_(-1),
108 minThresholdValue_(dict.get<scalar>("minThresholdValue")),
109 fBased_(dict.get<bool>("forceBased")),
110 baffleActivated_(0),
111 opening_(dict.get<bool>("opening"))
112{
114
115 if (p.size() > 0)
116 {
117 initWallSf_ = p.Sf();
118 initCyclicSf_ = p.boundaryMesh()[cyclicPatchLabel_].Sf();
119 nbrCyclicSf_ = refCast<const cyclicFvPatch>
120 (
121 p.boundaryMesh()[cyclicPatchLabel_],
122 dict
123 ).neighbFvPatch().Sf();
124 }
125
126 dict.readIfPresent("p", pName_);
127}
128
129
132(
133 const activePressureForceBaffleVelocityFvPatchVectorField& ptf
134)
135:
136 fixedValueFvPatchVectorField(ptf),
137 pName_(ptf.pName_),
138 cyclicPatchName_(ptf.cyclicPatchName_),
139 cyclicPatchLabel_(ptf.cyclicPatchLabel_),
140 initWallSf_(ptf.initWallSf_),
141 initCyclicSf_(ptf.initCyclicSf_),
142 nbrCyclicSf_(ptf.nbrCyclicSf_),
143 openFraction_(ptf.openFraction_),
144 openingTime_(ptf.openingTime_),
145 maxOpenFractionDelta_(ptf.maxOpenFractionDelta_),
146 curTimeIndex_(-1),
147 minThresholdValue_(ptf.minThresholdValue_),
148 fBased_(ptf.fBased_),
149 baffleActivated_(ptf.baffleActivated_),
150 opening_(ptf.opening_)
151{}
152
153
156(
159)
160:
161 fixedValueFvPatchVectorField(ptf, iF),
162 pName_(ptf.pName_),
163 cyclicPatchName_(ptf.cyclicPatchName_),
164 cyclicPatchLabel_(ptf.cyclicPatchLabel_),
165 initWallSf_(ptf.initWallSf_),
166 initCyclicSf_(ptf.initCyclicSf_),
167 nbrCyclicSf_(ptf.nbrCyclicSf_),
168 openFraction_(ptf.openFraction_),
169 openingTime_(ptf.openingTime_),
170 maxOpenFractionDelta_(ptf.maxOpenFractionDelta_),
171 curTimeIndex_(-1),
172 minThresholdValue_(ptf.minThresholdValue_),
173 fBased_(ptf.fBased_),
174 baffleActivated_(ptf.baffleActivated_),
175 opening_(ptf.opening_)
176{}
177
178
179// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
180
182(
183 const fvPatchFieldMapper& m
184)
185{
186 fixedValueFvPatchVectorField::autoMap(m);
187
188 //- Note: cannot map field from cyclic patch anyway so just recalculate
189 // Areas should be consistent when doing autoMap except in case of
190 // topo changes.
191 //- Note: we don't want to use Sf here since triggers rebuilding of
192 // fvMesh::S() which will give problems when mapped (since already
193 // on new mesh)
194 forAll(patch().boundaryMesh().mesh().faceAreas(), i)
195 {
196 if (mag(patch().boundaryMesh().mesh().faceAreas()[i]) == 0)
197 {
198 Info << "faceArea[active] "<< i << endl;
199 }
200 }
201
202 if (patch().size() > 0)
203 {
204 const vectorField& areas = patch().boundaryMesh().mesh().faceAreas();
205 initWallSf_ = patch().patchSlice(areas);
206 initCyclicSf_ =
207 patch().boundaryMesh()[cyclicPatchLabel_].patchSlice(areas);
208 nbrCyclicSf_ = refCast<const cyclicFvPatch>
209 (
211 [
212 cyclicPatchLabel_
213 ]
214 ).neighbFvPatch().patch().patchSlice(areas);
216}
217
218
220(
221 const fvPatchVectorField& ptf,
222 const labelList& addr
223)
224{
225 fixedValueFvPatchVectorField::rmap(ptf, addr);
226
227 // See autoMap.
228 const vectorField& areas = patch().boundaryMesh().mesh().faceAreas();
229 initWallSf_ = patch().patchSlice(areas);
230 initCyclicSf_ =
231 patch().boundaryMesh()[cyclicPatchLabel_].patchSlice(areas);
232 nbrCyclicSf_ = refCast<const cyclicFvPatch>
233 (
234 patch().boundaryMesh()
235 [
236 cyclicPatchLabel_
237 ]
238 ).neighbFvPatch().patch().patchSlice(areas);
239}
240
241
243{
244 if (updated())
245 {
246 return;
247 }
248
249 // Execute the change to the openFraction only once per time-step
250 if (curTimeIndex_ != this->db().time().timeIndex())
251 {
252 const volScalarField& p =
253 db().lookupObject<volScalarField>(pName_);
254
255 const fvPatch& cyclicPatch = patch().boundaryMesh()[cyclicPatchLabel_];
256 const labelUList& cyclicFaceCells = cyclicPatch.patch().faceCells();
257 const fvPatch& nbrPatch =
258 refCast<const cyclicFvPatch>(cyclicPatch).neighbFvPatch();
259
260 const labelUList& nbrFaceCells = nbrPatch.patch().faceCells();
261
262 scalar valueDiff = 0;
263 scalar area = 0;
264
265 // Add this side (p*area)
266 forAll(cyclicFaceCells, facei)
267 {
268 valueDiff +=p[cyclicFaceCells[facei]]*mag(initCyclicSf_[facei]);
269 area += mag(initCyclicSf_[facei]);
270 }
271
272 // Remove other side
273 forAll(nbrFaceCells, facei)
274 {
275 valueDiff -=p[nbrFaceCells[facei]]*mag(initCyclicSf_[facei]);
276 }
277
278 if (!fBased_) //pressure based then weighted by area
279 {
280 valueDiff = valueDiff/(area + VSMALL);
281 }
282
283 reduce(valueDiff, sumOp<scalar>());
284
285 if (Pstream::master())
286 {
287 if (fBased_)
288 {
289 Info<< "Force difference (threshold) = " << valueDiff
290 << "(" << minThresholdValue_ << ")" << endl;
291 }
292 else
293 {
294 Info<< "Area-averaged pressure difference (threshold) = "
295 << valueDiff << "(" << minThresholdValue_ << ")" << endl;
296 }
297 }
298
299 if (mag(valueDiff) > mag(minThresholdValue_) || baffleActivated_)
300 {
301 openFraction_ =
302 (
303 openFraction_
304 + min
305 (
306 this->db().time().deltaTValue()/openingTime_,
307 maxOpenFractionDelta_
308 )
309 );
310
311 baffleActivated_ = true;
312 }
313 openFraction_ = clamp(openFraction_, scalar(1e-6), scalar(1 - 1e-6));
314
315 if (Pstream::master())
316 {
317 Info<< "Open fraction = " << openFraction_ << endl;
318 }
319
320 const scalar areaFraction =
321 (
322 opening_ ? openFraction_ : (1 - openFraction_)
323 );
324
325 if (patch().boundaryMesh().mesh().moving())
326 {
327 // All areas have been recalculated already so are consistent
328 // with the new points. Note we already only do this routine
329 // once per timestep. The alternative is to use the upToDate
330 // mechanism for regIOobject + polyMesh::upToDatePoints
331 initWallSf_ = patch().Sf();
332 initCyclicSf_ = patch().boundaryMesh()[cyclicPatchLabel_].Sf();
333 nbrCyclicSf_ = refCast<const cyclicFvPatch>
334 (
335 patch().boundaryMesh()[cyclicPatchLabel_]
336 ).neighbFvPatch().Sf();
337 }
338
339
340 // Update this wall patch
341 vectorField::subField Sfw = patch().patch().faceAreas();
342 vectorField newSfw((1 - areaFraction)*initWallSf_);
343 forAll(Sfw, facei)
344 {
345 Sfw[facei] = newSfw[facei];
346 }
347 const_cast<scalarField&>(patch().magSf()) = mag(patch().Sf());
348 // Cache fraction
349 const_cast<polyPatch&>(patch().patch()).areaFraction(1-areaFraction);
350
351
352 // Update owner side of cyclic
353 const_cast<vectorField&>(cyclicPatch.Sf()) = areaFraction*initCyclicSf_;
354 const_cast<scalarField&>(cyclicPatch.magSf()) = mag(cyclicPatch.Sf());
355 const_cast<polyPatch&>(cyclicPatch.patch()).areaFraction(areaFraction);
356
357
358 // Update neighbour side of cyclic
359 const_cast<vectorField&>(nbrPatch.Sf()) = areaFraction*nbrCyclicSf_;
360 const_cast<scalarField&>(nbrPatch.magSf()) = mag(nbrPatch.Sf());
361 const_cast<polyPatch&>(nbrPatch.patch()).areaFraction(areaFraction);
362
363 curTimeIndex_ = this->db().time().timeIndex();
364 }
365
366 fixedValueFvPatchVectorField::updateCoeffs();
367}
368
369
371write(Ostream& os) const
372{
374 os.writeEntryIfDifferent<word>("p", "p", pName_);
375 os.writeEntry("cyclicPatch", cyclicPatchName_);
376 os.writeEntry("openingTime", openingTime_);
377 os.writeEntry("maxOpenFractionDelta", maxOpenFractionDelta_);
378 os.writeEntry("openFraction", openFraction_);
379 os.writeEntry("minThresholdValue", minThresholdValue_);
380 os.writeEntry("forceBased", fBased_);
381 os.writeEntry("opening", opening_);
383}
384
385
386// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
387
388namespace Foam
389{
391 (
394 );
395}
396
397
398// ************************************************************************* //
Macros for easy insertion into run-time selection tables.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
SubField< vector > subField
Definition Field.H:183
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
This boundary condition is applied to the flow velocity, to simulate the opening or closure of a baff...
virtual void autoMap(const fvPatchFieldMapper &)
Map (and resize as needed) from self given a mapping object.
virtual void rmap(const fvPatchVectorField &, const labelList &)
Reverse map the given fvPatchField onto this fvPatchField.
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
activePressureForceBaffleVelocityFvPatchVectorField(const fvPatch &, const DimensionedField< vector, volMesh > &)
Construct from patch and internal field.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
A FieldMapper for finite-volume patch fields.
virtual void write(Ostream &) const
Write.
void writeValueEntry(Ostream &os) const
Write *this field as a "value" entry.
virtual void operator=(const UList< vector > &)
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition fvPatch.H:71
const polyPatch & patch() const noexcept
Return the polyPatch.
Definition fvPatch.H:202
const scalarField & magSf() const
Return face area magnitudes, like the fvMesh::magSf() method.
Definition fvPatch.C:131
const vectorField & Sf() const
Return face area vectors, like the fvMesh::Sf() method.
Definition fvPatch.C:125
A patch is a list of labels that address the faces in the global face list.
Definition polyPatch.H:73
tmp< scalarField > areaFraction(const pointField &points) const
Calculate the area fraction as the ratio of the stored face area and the area given by the face point...
Definition polyPatch.C:352
const labelUList & faceCells() const
Return face-cell addressing.
Definition polyPatch.C:401
Lookup type of boundary radiation properties.
Definition lookup.H:60
A class for handling words, derived from Foam::string.
Definition word.H:66
volScalarField & p
dynamicFvMesh & mesh
OBJstream os(runTime.globalPath()/outputName)
#define makePatchTypeField(PatchTypeField, typePatchTypeField)
Define a concrete fvPatchField type and add to run-time tables Example, (fvPatchScalarField,...
const wordList area
Standard area field types (scalar, vector, tensor, etc).
const std::string patch
OpenFOAM patch number as a std::string.
Namespace for OpenFOAM.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
Definition typeInfo.H:172
List< label > labelList
A List of labels.
Definition List.H:62
GeometricField< scalar, fvPatchField, volMesh > volScalarField
messageStream Info
Information stream (stdout output on master, null elsewhere).
dimensionSet clamp(const dimensionSet &a, const dimensionSet &range)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:26
Field< vector > vectorField
Specialisation of Field<T> for vector.
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
UList< label > labelUList
A UList of labels.
Definition UList.H:75
fvPatchField< vector > fvPatchVectorField
label timeIndex
dictionary dict
volScalarField & e
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Foam::surfaceFields.