Loading...
Searching...
No Matches
setFlow.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) 2017-2023 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
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 "setFlow.H"
29#include "volFields.H"
30#include "surfaceFields.H"
31#include "fvcFlux.H"
33#include "fvcSurfaceIntegrate.H"
35// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36
37namespace Foam
38{
39namespace functionObjects
40{
43}
44}
45
46
47const Foam::Enum
48<
49 Foam::functionObjects::setFlow::modeType
50>
51Foam::functionObjects::setFlow::modeTypeNames
52({
53 { functionObjects::setFlow::modeType::FUNCTION, "function" },
54 { functionObjects::setFlow::modeType::ROTATION, "rotation" },
55 { functionObjects::setFlow::modeType::VORTEX2D, "vortex2D" },
56 { functionObjects::setFlow::modeType::VORTEX3D, "vortex3D" },
57});
58
59
60// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
61
62void Foam::functionObjects::setFlow::setPhi(const volVectorField& U)
63{
64 surfaceScalarField* phiptr =
65 mesh_.getObjectPtr<surfaceScalarField>(phiName_);
66
67 if (!phiptr)
68 {
69 return;
70 }
71
72 if (rhoName_ != "none")
73 {
74 const volScalarField* rhoptr =
75 mesh_.findObject<volScalarField>(rhoName_);
76
77 if (rhoptr)
78 {
79 const volScalarField& rho = *rhoptr;
80 *phiptr = fvc::flux(rho*U);
81 }
82 else
83 {
85 << "Unable to find rho field'" << rhoName_
86 << "' in the mesh database. Available fields are:"
87 << flatOutput(mesh_.sortedNames<volScalarField>())
88 << exit(FatalError);
89 }
90 }
91 else
92 {
93 *phiptr = fvc::flux(U);
94 }
95}
96
97
98// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
99
101(
102 const word& name,
103 const Time& runTime,
104 const dictionary& dict
105)
106:
107 fvMeshFunctionObject(name, runTime, dict),
108 mode_(modeType::FUNCTION),
109 UName_("U"),
110 rhoName_("none"),
111 phiName_("phi"),
112 reverseTime_(VGREAT),
113 scalePtr_(nullptr),
114 origin_(Zero),
115 R_(tensor::I),
116 omegaPtr_(nullptr),
117 velocityPtr_(nullptr)
119 read(dict);
120}
121
122
123// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
124
126{
128 {
129 Info<< name() << ":" << endl;
130
131 modeTypeNames.readEntry("mode", dict, mode_);
132
133 Info<< " operating mode: " << modeTypeNames[mode_] << endl;
134
135 if (dict.readIfPresent("U", UName_))
136 {
137 Info<< " U field name: " << UName_ << endl;
138 }
139
140 if (dict.readIfPresent("rho", rhoName_))
141 {
142 Info<< " rho field name: " << rhoName_ << endl;
143 }
144
145 if (dict.readIfPresent("phi", phiName_))
146 {
147 Info<< " phi field name: " << phiName_ << endl;
148 }
149
150 if (dict.readIfPresent("reverseTime", reverseTime_))
151 {
152 Info<< " reverse flow direction at time: " << reverseTime_
153 << endl;
154 reverseTime_ = mesh_.time().userTimeToTime(reverseTime_);
155 }
156
157 // Scaling is applied across all modes
158 scalePtr_ = Function1<scalar>::New("scale", dict, &mesh_);
159
160 switch (mode_)
161 {
162 case modeType::FUNCTION:
163 {
164 velocityPtr_ = Function1<vector>::New("velocity", dict, &mesh_);
165 break;
166 }
167 case modeType::ROTATION:
168 {
169 omegaPtr_ = Function1<scalar>::New("omega", dict, &mesh_);
170
171 dict.readEntry("origin", origin_);
172 const vector refDir(dict.get<vector>("refDir").normalise());
173 const vector axis(dict.get<vector>("axis").normalise());
174
175 R_ = tensor(refDir, axis, refDir^axis);
176 break;
177 }
178 case modeType::VORTEX2D:
179 case modeType::VORTEX3D:
180 {
181 dict.readEntry("origin", origin_);
182 const vector refDir(dict.get<vector>("refDir").normalise());
183 const vector axis(dict.get<vector>("axis").normalise());
184
185 R_ = tensor(refDir, axis, refDir^axis);
186 break;
187 }
188 }
189
190 Info<< endl;
191
192 return true;
193 }
194
195 return false;
196}
197
198
200{
201 volVectorField* Uptr =
202 mesh_.getObjectPtr<volVectorField>(UName_);
203
204 surfaceScalarField* phiptr =
205 mesh_.getObjectPtr<surfaceScalarField>(phiName_);
206
207 Log << nl << name() << ":" << nl;
208
209 if (!Uptr || !phiptr)
210 {
211 Info<< " Either field " << UName_ << " or " << phiName_
212 << " not found in the mesh database" << nl;
213
214 return true;
215 }
216
217 const scalar t = mesh_.time().timeOutputValue();
218
219 Log << " setting " << UName_ << " and " << phiName_ << nl;
220
221 volVectorField& U = *Uptr;
222 surfaceScalarField& phi = *phiptr;
223
224 switch (mode_)
225 {
226 case modeType::FUNCTION:
227 {
228 const vector Uc = velocityPtr_->value(t);
229 U == dimensionedVector("Uc", dimVelocity, Uc);
230 U.correctBoundaryConditions();
231 setPhi(U);
232
233 break;
234 }
235 case modeType::ROTATION:
236 {
237 const auto oldConsistency = FieldBase::localBoundaryConsistency(0);
238
239 const volVectorField& C = mesh_.C();
240 const volVectorField d
241 (
243 C - dimensionedVector("origin", dimLength, origin_)
244 );
245 const scalarField x(d.component(vector::X));
246 const scalarField z(d.component(vector::Z));
247
248 const scalar omega = omegaPtr_->value(t);
249 vectorField& Uc = U.primitiveFieldRef();
250 Uc.replace(vector::X, -omega*z);
251 Uc.replace(vector::Y, scalar(0));
252 Uc.replace(vector::Z, omega*x);
253
254 volVectorField::Boundary& Ubf = U.boundaryFieldRef();
255 forAll(Ubf, patchi)
256 {
257 vectorField& Uf = Ubf[patchi];
258 if (Uf.size())
259 {
260 const vectorField& Cp = C.boundaryField()[patchi];
261 const vectorField dp(Cp - origin_);
262 const scalarField xp(dp.component(vector::X));
263 const scalarField zp(dp.component(vector::Z));
264 Uf.replace(vector::X, -omega*zp);
265 Uf.replace(vector::Y, scalar(0));
266 Uf.replace(vector::Z, omega*xp);
267 }
268 }
269
270 U = U & R_;
271
273 U.correctBoundaryConditions();
274 setPhi(U);
275
276 break;
277 }
278 case modeType::VORTEX2D:
279 {
281
282 const auto oldConsistency = FieldBase::localBoundaryConsistency(0);
283
284 const volVectorField& C = mesh_.C();
285
286 const volVectorField d
287 (
289 C - dimensionedVector("origin", dimLength, origin_)
290 );
291 const scalarField x(d.component(vector::X));
292 const scalarField z(d.component(vector::Z));
293
294 vectorField& Uc = U.primitiveFieldRef();
295 Uc.replace(vector::X, -sin(2*pi*z)*sqr(sin(pi*x)));
296 Uc.replace(vector::Y, scalar(0));
297 Uc.replace(vector::Z, sin(2*pi*x)*sqr(sin(pi*z)));
298
299 U = U & R_;
300
302 U.correctBoundaryConditions();
303
304 // Calculating phi
305 // Note: R_ rotation not implemented in phi calculation
306 const vectorField Cf(mesh_.Cf().primitiveField() - origin_);
307 const scalarField Xf(Cf.component(vector::X));
308 const scalarField Yf(Cf.component(vector::Y));
309 const scalarField Zf(Cf.component(vector::Z));
310 vectorField Uf(Xf.size());
311 Uf.replace(vector::X, -sin(2*pi*Zf)*sqr(sin(pi*Xf)));
312 Uf.replace(vector::Y, scalar(0));
313 Uf.replace(vector::Z, sin(2*pi*Xf)*sqr(sin(pi*Zf)));
314
315 scalarField& phic = phi.primitiveFieldRef();
316 const vectorField& Sfc = mesh_.Sf().primitiveField();
317 phic = Uf & Sfc;
318
319 surfaceScalarField::Boundary& phibf = phi.boundaryFieldRef();
320 const surfaceVectorField::Boundary& Sfbf =
321 mesh_.Sf().boundaryField();
322 const surfaceVectorField::Boundary& Cfbf =
323 mesh_.Cf().boundaryField();
324
325 forAll(phibf, patchi)
326 {
327 scalarField& phif = phibf[patchi];
328 const vectorField& Sff = Sfbf[patchi];
329 const vectorField& Cff = Cfbf[patchi];
330 const scalarField xf(Cff.component(vector::X));
331 const scalarField yf(Cff.component(vector::Y));
332 const scalarField zf(Cff.component(vector::Z));
333 vectorField Ufb(xf.size());
334 Ufb.replace(vector::X, -sin(2*pi*zf)*sqr(sin(pi*xf)));
335 Ufb.replace(vector::Y, scalar(0));
336 Ufb.replace(vector::Z, sin(2*pi*xf)*sqr(sin(pi*zf)));
337 phif = Ufb & Sff;
338 }
339
340 break;
341 }
342 case modeType::VORTEX3D:
343 {
345
346 const auto oldConsistency = FieldBase::localBoundaryConsistency(0);
347
348 const volVectorField& C = mesh_.C();
349
350 const volVectorField d
351 (
353 C - dimensionedVector("origin", dimLength, origin_)
354 );
355 const scalarField x(d.component(vector::X));
356 const scalarField y(d.component(vector::Y));
357 const scalarField z(d.component(vector::Z));
358
359 vectorField& Uc = U.primitiveFieldRef();
360 Uc.replace(vector::X, 2*sqr(sin(pi*x))*sin(2*pi*y)*sin(2*pi*z));
361 Uc.replace(vector::Y, -sin(2*pi*x)*sqr(sin(pi*y))*sin(2*pi*z));
362 Uc.replace(vector::Z, -sin(2*pi*x)*sin(2*pi*y)*sqr(sin(pi*z)));
363
364 U = U & R_;
365
367 U.correctBoundaryConditions();
368
369 // Calculating phi
370 // Note: R_ rotation not implemented in phi calculation
371 const vectorField Cf(mesh_.Cf().primitiveField() - origin_);
372 const scalarField Xf(Cf.component(vector::X));
373 const scalarField Yf(Cf.component(vector::Y));
374 const scalarField Zf(Cf.component(vector::Z));
375 vectorField Uf(Xf.size());
376 Uf.replace(0, 2*sqr(sin(pi*Xf))*sin(2*pi*Yf)*sin(2*pi*Zf));
377 Uf.replace(1, -sin(2*pi*Xf)*sqr(sin(pi*Yf))*sin(2*pi*Zf));
378 Uf.replace(2, -sin(2*pi*Xf)*sin(2*pi*Yf)*sqr(sin(pi*Zf)));
379
380 scalarField& phic = phi.primitiveFieldRef();
381 const vectorField& Sfc = mesh_.Sf().primitiveField();
382 phic = Uf & Sfc;
383
384 surfaceScalarField::Boundary& phibf = phi.boundaryFieldRef();
385 const surfaceVectorField::Boundary& Sfbf =
386 mesh_.Sf().boundaryField();
387 const surfaceVectorField::Boundary& Cfbf =
388 mesh_.Cf().boundaryField();
389
390 forAll(phibf, patchi)
391 {
392 scalarField& phif = phibf[patchi];
393 const vectorField& Sff = Sfbf[patchi];
394 const vectorField& Cff = Cfbf[patchi];
395 const scalarField xf(Cff.component(vector::X));
396 const scalarField yf(Cff.component(vector::Y));
397 const scalarField zf(Cff.component(vector::Z));
398 vectorField Uf(xf.size());
399 Uf.replace(0, 2*sqr(sin(pi*xf))*sin(2*pi*yf)*sin(2*pi*zf));
400 Uf.replace(1, -sin(2*pi*xf)*sqr(sin(pi*yf))*sin(2*pi*zf));
401 Uf.replace(2, -sin(2*pi*xf)*sin(2*pi*yf)*sqr(sin(pi*zf)));
402 phif = Uf & Sff;
403 }
404
405 break;
406 }
407 }
408
409 if (t > reverseTime_)
410 {
411 Log << " flow direction: reverse" << nl;
412 U.negate();
413 phi.negate();
414 }
415
416 // Apply scaling
417 const scalar s = scalePtr_->value(t);
418 U *= s;
419 phi *= s;
420
421 U.correctBoundaryConditions();
422
424 Log << " Continuity error: max(mag(sum(phi))) = "
425 << gMax(mag(sumPhi)) << nl << endl;
426
427 return true;
428}
429
430
432{
433 const auto* Uptr = mesh_.findObject<volVectorField>(UName_);
434 if (Uptr)
435 {
436 Uptr->write();
437 }
438
439 const auto* phiptr = mesh_.findObject<surfaceScalarField>(phiName_);
440 if (phiptr)
441 {
442 phiptr->write();
443 }
444
445 return true;
446}
447
448
449// ************************************************************************* //
static const Foam::dimensionedScalar C("", Foam::dimTemperature, 234.5)
scalar y
constexpr scalar pi(M_PI)
surfaceScalarField phic(mixture.cAlpha() *mag(alphaPhic/mesh.magSf()))
#define Log
Definition PDRblock.C:28
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Graphite solid properties.
Definition C.H:49
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition Enum.H:57
static int localBoundaryConsistency() noexcept
Get flag for local boundary consistency checks.
Definition Field.H:133
void replace(const direction, const UList< cmptType > &)
Replace a component field of the field.
Definition Field.C:619
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
Definition Field.C:607
GeometricBoundaryField< vector, fvPatchField, volMesh > Boundary
tmp< GeometricField< cmptType, PatchField, GeoMesh > > component(const direction) const
Return a component of the field.
static word scopedName(const std::string &scope, const word &name)
Create scope:name or scope_name string.
Definition IOobjectI.H:50
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
Vector< Cmpt > & normalise(const scalar tol=ROOTVSMALL)
Inplace normalise the vector by its magnitude.
Definition VectorI.H:114
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
Abstract base-class for Time/database function objects.
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
const fvMesh & mesh_
Reference to the fvMesh.
fvMeshFunctionObject(const fvMeshFunctionObject &)=delete
No copy construct.
Provides options to set the velocity and flux fields as a function of time.
Definition setFlow.H:259
setFlow(const word &name, const Time &runTime, const dictionary &dict)
Construct from name, Time and dictionary.
Definition setFlow.C:94
virtual bool read(const dictionary &dict)
Read the function-object dictionary.
Definition setFlow.C:118
virtual bool execute()
Execute the function-object operations.
Definition setFlow.C:192
virtual bool write()
Write the function-object results.
Definition setFlow.C:424
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
U
Definition pEqn.H:72
const volScalarField & Cp
Definition EEqn.H:7
engineTime & runTime
autoPtr< surfaceVectorField > Uf
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
Calculate the face-flux of the given field.
Surface integrate surfaceField creating a volField. Surface sum a surfaceField creating a volField.
auto & name
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
constexpr scalar pi(M_PI)
Function objects are OpenFOAM utilities to ease workflow configurations and enhance workflows.
tmp< surfaceScalarField > flux(const volVectorField &vvf)
Return the face-flux field obtained from the given volVectorField.
Definition fvcFlux.C:27
void surfaceIntegrate(Field< Type > &ivf, const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Namespace for OpenFOAM.
GeometricField< vector, fvPatchField, volMesh > volVectorField
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition int32.H:127
dimensionedSymmTensor sqr(const dimensionedVector &dv)
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
GeometricField< scalar, fvPatchField, volMesh > volScalarField
dimensionedScalar sin(const dimensionedScalar &ds)
const dimensionSet dimVelocity
messageStream Info
Information stream (stdout output on master, null elsewhere).
static const Identity< scalar > I
Definition Identity.H:100
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
Tensor< scalar > tensor
Definition symmTensor.H:57
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition FlatOutput.H:217
Field< vector > vectorField
Specialisation of Field<T> for vector.
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
Vector< scalar > vector
Definition vector.H:57
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
Type gMax(const FieldField< Field, Type > &f)
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Foam::surfaceFields.