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 -------------------------------------------------------------------------------
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 "rotorDiskSource.H"
30 #include "volFields.H"
31 #include "unitConversion.H"
32 
33 using namespace Foam::constant;
34 
35 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
36 
37 template<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  }
108  if (alphaEff < -mathematical::pi)
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 
173 template<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  (
187  IOobject
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 // ************************************************************************* //
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
volFields.H
Foam::maxOp
Definition: ops.H:223
Foam::Tensor< scalar >
Foam::fv::rotorDiskSource::calculate
void calculate(const RhoFieldType &rho, const vectorField &U, const scalarField &thetag, vectorField &force, const bool divideVolume=true, const bool output=true) const
Calculate forces.
Definition: rotorDiskSourceTemplates.C:39
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::Vector::x
const Cmpt & x() const
Access to the vector x component.
Definition: VectorI.H:73
Foam::output
static Ostream & output(Ostream &os, const IntRange< T > &range)
Definition: IntRanges.C:66
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
pDyn
volScalarField pDyn(IOobject("pDyn", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), mesh, dimensionedScalar(dimPressure, Zero))
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::HashTableOps::values
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:149
Foam::minOp
Definition: ops.H:224
Foam::constant
Different types of constants.
Definition: atomicConstants.C:38
Foam::atan2
dimensionedScalar atan2(const dimensionedScalar &x, const dimensionedScalar &y)
Definition: dimensionedScalar.C:312
unitConversion.H
Unit conversion functions.
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::transform
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:521
rho
rho
Definition: readInitialConditions.H:88
Foam::Vector::z
const Cmpt & z() const
Access to the vector z component.
Definition: VectorI.H:85
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::magSqr
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::Field< vector >
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
rotorDiskSource.H
Foam::radToDeg
constexpr scalar radToDeg(const scalar rad) noexcept
Conversion from radians to degrees.
Definition: unitConversion.H:54
field
rDeltaTY field()
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::constant::mathematical::twoPi
constexpr scalar twoPi(2 *M_PI)
Foam::FatalError
error FatalError
Foam::dimensioned
Generic dimensioned Type class.
Definition: dimensionedScalarFwd.H:42
Foam::fv::rotorDiskSource::writeField
void writeField(const word &name, const List< Type > &values, const bool writeNow=false) const
Helper function to write rotor values.
Definition: rotorDiskSourceTemplates.C:175
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
U
U
Definition: pEqn.H:72
Foam::Vector::y
const Cmpt & y() const
Access to the vector y component.
Definition: VectorI.H:79
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::constant::mathematical::pi
constexpr scalar pi(M_PI)
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::List< Type >
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::invTransform
dimensionSet invTransform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:527
alphaEff
volScalarField alphaEff("alphaEff", turbulence->nu()/Pr+alphat)
Foam::tmp::New
static tmp< T > New(Args &&... args)
Construct tmp of T with forwarding arguments.
bool
bool
Definition: EEqn.H:20
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::GeometricField< Type, fvPatchField, volMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:188
Foam::neg
dimensionedScalar neg(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:199
Foam::dimless
const dimensionSet dimless
Dimensionless.
Definition: dimensionSets.C:189