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"
31#include "unitConversion.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{
182
183 if (mesh_.time().writeTime() || writeNow)
184 {
185 auto tfield = tmp<FieldType>::New
186 (
188 (
189 name,
190 mesh_.time().timeName(),
191 mesh_,
194 ),
195 mesh_,
197 );
198
199 auto& field = tfield.ref().primitiveFieldRef();
200
201 if (cells_.size() != values.size())
202 {
204 << abort(FatalError);
205 }
206
207 forAll(cells_, i)
208 {
209 const label celli = cells_[i];
210 field[celli] = values[i];
211 }
212
213 tfield().write();
214 }
215}
216
217
218// ************************************************************************* //
Generic GeometricField class.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
const Cmpt & z() const
Access to the vector z component.
Definition: VectorI.H:85
const Cmpt & y() const
Access to the vector y component.
Definition: VectorI.H:79
const Cmpt & x() const
Access to the vector x component.
Definition: VectorI.H:73
const List< label > & profileID() const
Return const access to the profile ID list.
Definition: bladeModel.C:146
virtual void interpolate(const scalar radius, scalar &twist, scalar &chord, label &i1, label &i2, scalar &invDr) const
Return the twist and chord for a given radius.
Definition: bladeModel.C:177
virtual tensor R(const point &global) const
Generic dimensioned Type class.
const volVectorField & C() const
Return cell centres as volVectorField.
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
scalar V() const noexcept
Return const access to the total cell volume.
labelList cells_
Set of cells to apply source to.
const fvMesh & mesh_
Reference to the mesh database.
Definition: fvOption.H:139
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:68
U
Definition: pEqn.H:72
rDeltaTY field()
bool
Definition: EEqn.H:20
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
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.
Definition: dimensionSet.C:542
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
const dimensionSet dimless
Dimensionless.
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:536
messageStream Info
Information stream (stdout output on master, null elsewhere)
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:598
dimensionedScalar atan2(const dimensionedScalar &x, const dimensionedScalar &y)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
constexpr scalar radToDeg() noexcept
Multiplication factor for radians to degrees conversion.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
errorManip< error > abort(error &err)
Definition: errorManip.H:144
static Ostream & output(Ostream &os, const IntRange< T > &range)
Definition: IntRanges.C:66
dimensionedScalar neg(const dimensionedScalar &ds)
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Vector< scalar > vector
Definition: vector.H:61
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
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:333
Unit conversion functions.