Loading...
Searching...
No Matches
rotorDiskSourceTemplates.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) 2018-2020 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
29#include "rotorDiskSource.H"
30#include "volFields.H"
32
33using namespace Foam::constant;
34
35// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
36
37template<class RhoFieldType>
39(
40 const RhoFieldType& rho,
41 const vectorField& U,
42 const scalarField& thetag,
43 vectorField& force,
44 const bool divideVolume,
45 const bool output
46) const
47{
48 const scalarField& V = mesh_.V();
49
50 // Logging info
51 scalar dragEff = 0.0;
52 scalar liftEff = 0.0;
53 scalar AOAmin = GREAT;
54 scalar AOAmax = -GREAT;
55
56 // Cached position-dependent rotations available?
57 const bool hasCache = bool(Rcyl_);
58
59 forAll(cells_, i)
60 {
61 if (area_[i] > ROOTVSMALL)
62 {
63 const label celli = cells_[i];
64
65 const scalar radius = x_[i].x();
66
67 const tensor Rcyl =
68 (
69 hasCache
70 ? (*Rcyl_)[i]
71 : coordSys_.R(mesh_.C()[celli])
72 );
73
74 // Transform velocity into local cylindrical reference frame
75 vector Uc = invTransform(Rcyl, U[celli]);
76
77 // Transform velocity into local coning system
78 Uc = transform(Rcone_[i], Uc);
79
80 // Set radial component of velocity to zero
81 Uc.x() = 0.0;
82
83 // Set blade normal component of velocity
84 Uc.y() = radius*omega_ - Uc.y();
85
86 // Determine blade data for this radius
87 // i2 = index of upper radius bound data point in blade list
88 scalar twist = 0.0;
89 scalar chord = 0.0;
90 label i1 = -1;
91 label i2 = -1;
92 scalar invDr = 0.0;
93 blade_.interpolate(radius, twist, chord, i1, i2, invDr);
94
95 // Flip geometric angle if blade is spinning in reverse (clockwise)
96 scalar alphaGeom = thetag[i] + twist;
97 if (omega_ < 0)
98 {
99 alphaGeom = mathematical::pi - alphaGeom;
100 }
101
102 // Effective angle of attack
103 scalar alphaEff = alphaGeom - atan2(-Uc.z(), Uc.y());
105 {
107 }
109 {
111 }
112
113 AOAmin = min(AOAmin, alphaEff);
114 AOAmax = max(AOAmax, alphaEff);
115
116 // Determine profile data for this radius and angle of attack
117 const label profile1 = blade_.profileID()[i1];
118 const label profile2 = blade_.profileID()[i2];
119
120 scalar Cd1 = 0.0;
121 scalar Cl1 = 0.0;
122 profiles_[profile1].Cdl(alphaEff, Cd1, Cl1);
123
124 scalar Cd2 = 0.0;
125 scalar Cl2 = 0.0;
126 profiles_[profile2].Cdl(alphaEff, Cd2, Cl2);
127
128 scalar Cd = invDr*(Cd2 - Cd1) + Cd1;
129 scalar Cl = invDr*(Cl2 - Cl1) + Cl1;
130
131 // Apply tip effect for blade lift
132 scalar tipFactor = neg(radius/rMax_ - tipEffect_);
133
134 // Calculate forces perpendicular to blade
135 scalar pDyn = 0.5*rho[celli]*magSqr(Uc);
136
137 scalar f = pDyn*chord*nBlades_*area_[i]/radius/mathematical::twoPi;
138 vector localForce = vector(0.0, -f*Cd, tipFactor*f*Cl);
139
140 // Accumulate forces
141 dragEff += rhoRef_*localForce.y();
142 liftEff += rhoRef_*localForce.z();
143
144 // Transform force from local coning system into rotor cylindrical
145 localForce = invTransform(Rcone_[i], localForce);
146
147 // Transform force into global Cartesian coordinate system
148 force[celli] = transform(Rcyl, localForce);
149
150 if (divideVolume)
151 {
152 force[celli] /= V[celli];
153 }
154 }
155 }
156
157 if (output)
158 {
159 reduce(AOAmin, minOp<scalar>());
160 reduce(AOAmax, maxOp<scalar>());
161 reduce(dragEff, sumOp<scalar>());
162 reduce(liftEff, sumOp<scalar>());
163
164 Info<< type() << " output:" << nl
165 << " min/max(AOA) = " << radToDeg(AOAmin) << ", "
166 << radToDeg(AOAmax) << nl
167 << " Effective drag = " << dragEff << nl
168 << " Effective lift = " << liftEff << endl;
169 }
170}
171
172
173template<class Type>
175(
176 const word& name,
177 const List<Type>& values,
178 const bool writeNow
179) const
180{
181 if (mesh_.time().writeTime() || writeNow)
182 {
183 if (cells_.size() != values.size())
184 {
186 << "Size mismatch. Number of cells "
187 << cells_.size() << " != number of values "
188 << values.size() << nl
189 << abort(FatalError);
190 }
191
193 (
194 name,
196 mesh_,
198 );
199
200 auto& field = tfield.ref().primitiveFieldRef();
201
202 UIndirectList<Type>(field, cells_) = values;
203
204 tfield().write();
205 }
206}
207
208
209// ************************************************************************* //
static tmp< GeometricField< Type, PatchField, GeoMesh > > New(const word &name, IOobjectOption::registerOption regOpt, const Mesh &mesh, const dimensionSet &dims, const word &patchFieldType=PatchField< Type >::calculatedType())
Return tmp field (NO_READ, NO_WRITE) from name, mesh, dimensions and patch type. [Takes current timeN...
@ NO_REGISTER
Do not request registration (bool: false).
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
A List with indirect addressing. Like IndirectList but does not store addressing.
const Cmpt & x() const noexcept
Access to the vector x component.
Definition Vector.H:135
const Cmpt & z() const noexcept
Access to the vector z component.
Definition Vector.H:145
const Cmpt & y() const noexcept
Access to the vector y component.
Definition Vector.H:140
Generic dimensioned Type class.
scalar V() const noexcept
Return const access to the total cell volume.
labelList cells_
Set of cells to apply source to.
const word & name() const noexcept
Return const access to the source name.
Definition fvOptionI.H:24
const fvMesh & mesh_
Reference to the mesh database.
Definition fvOption.H:142
scalar omega_
Rotational speed [rad/s].
void calculate(const RhoFieldType &rho, const vectorField &U, const scalarField &thetag, vectorField &force, const bool divideVolume=true, const bool output=true) const
Calculate forces.
scalar rhoRef_
Reference density for incompressible case.
List< scalar > area_
Area [m2].
scalar tipEffect_
Tip effect [0-1].
void writeField(const word &name, const List< Type > &values, const bool writeNow=false) const
Helper function to write rotor values.
coordSystem::cylindrical coordSys_
Rotor local cylindrical coordinate system (r-theta-z).
scalar rMax_
Maximum radius.
List< point > x_
Cell centre positions in local rotor frame.
bladeModel blade_
Blade data.
List< tensor > Rcone_
Rotation tensor for flap angle.
label nBlades_
Number of blades.
autoPtr< tensorField > Rcyl_
Cached rotation tensors for cylindrical coordinates.
profileModelList profiles_
Profile data.
A class for handling words, derived from Foam::string.
Definition word.H:66
U
Definition pEqn.H:72
rDeltaTY field()
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
auto & name
volScalarField alphaEff("alphaEff", turbulence->nu()/Pr+alphat)
constexpr scalar pi(M_PI)
constexpr scalar twoPi(2 *M_PI)
Different types of constants.
dimensionSet invTransform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
const dimensionSet dimless
Dimensionless.
refinementData transform(const tensor &, const refinementData val)
No-op rotational transform for base types.
messageStream Info
Information stream (stdout output on master, null elsewhere).
Tensor< scalar > tensor
Definition symmTensor.H:57
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition POSIX.C:801
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
dimensionedScalar atan2(const dimensionedScalar &x, const dimensionedScalar &y)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
constexpr scalar radToDeg() noexcept
Multiplication factor for radians to degrees conversion.
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
errorManip< error > abort(error &err)
Definition errorManip.H:139
Field< vector > vectorField
Specialisation of Field<T> for vector.
dimensionedScalar neg(const dimensionedScalar &ds)
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
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
labelList f(nPoints)
volScalarField pDyn(IOobject("pDyn", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), mesh, dimensionedScalar(dimPressure, Zero))
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Unit conversion functions.