46 template<
class RhoFieldType>
49 const RhoFieldType&
rho,
55 rotor_.calculate(
rho,
U, thetag, force,
false,
false);
61 const vector& origin = rotor_.coordSys().origin();
62 const vector& rollAxis = rotor_.coordSys().e1();
63 const vector& pitchAxis = rotor_.coordSys().e2();
64 const vector& yawAxis = rotor_.coordSys().e3();
71 label celli =
cells[i];
74 vector mc = fc^(
C[celli] - origin);
78 scalar radius =
x[i].x();
79 scalar coeff2 =
rho[celli]*coeff1*
pow4(radius);
82 cf[0] += (fc & yawAxis)/(coeff2 + ROOTVSMALL);
83 cf[1] += (mc & pitchAxis)/(coeff2*radius + ROOTVSMALL);
84 cf[2] += (mc & rollAxis)/(coeff2*radius + ROOTVSMALL);
88 cf[0] += fc & yawAxis;
89 cf[1] += mc & pitchAxis;
90 cf[2] += mc & rollAxis;
94 reduce(cf, sumOp<vector>());
100 template<
class RhoFieldType>
103 const RhoFieldType&
rho,
108 if (rotor_.mesh().time().timeIndex() % calcFrequency_ == 0)
110 word calcType =
"forces";
113 calcType =
"coefficients";
117 <<
" solving for target trim " << calcType <<
nl;
119 const scalar rhoRef = rotor_.rhoRef();
127 while ((err > tol_) && (iter < nIter_))
133 old = calcCoeffs(
rho,
U, thetag(), force);
137 for (label pitchI = 0; pitchI < 3; pitchI++)
139 theta_[pitchI] -= dTheta_/2.0;
140 vector cf0 = calcCoeffs(
rho,
U, thetag(), force);
142 theta_[pitchI] += dTheta_;
143 vector cf1 = calcCoeffs(
rho,
U, thetag(), force);
145 vector ddTheta = (cf1 - cf0)/dTheta_;
147 J[pitchI + 0] = ddTheta[0];
148 J[pitchI + 3] = ddTheta[1];
149 J[pitchI + 6] = ddTheta[2];
155 vector dt =
inv(J) & (target_/rhoRef - old);
158 vector thetaNew = theta_ + relax_*dt;
161 err =
mag(thetaNew - theta_);
170 Info<<
" solution not converged in " << iter
171 <<
" iterations, final residual = " << err
172 <<
"(" << tol_ <<
")" <<
endl;
176 Info<<
" final residual = " << err <<
"(" << tol_
177 <<
"), iterations = " << iter <<
endl;
180 Info<<
" current and target " << calcType <<
nl 181 <<
" thrust = " << old[0]*rhoRef <<
", " << target_[0] <<
nl 182 <<
" pitch = " << old[1]*rhoRef <<
", " << target_[1] <<
nl 183 <<
" roll = " << old[2]*rhoRef <<
", " << target_[2] <<
nl 184 <<
" new pitch angles [deg]:" <<
nl 197 const fv::rotorDiskSource& rotor,
198 const dictionary&
dict 201 trimModel(rotor,
dict, typeName),
222 const dictionary& targetDict(coeffs_.subDict(
"target"));
223 useCoeffs_ = targetDict.
getOrDefault(
"useCoeffs",
true);
230 targetDict.readEntry(
"thrust" + ext, target_[0]);
231 targetDict.readEntry(
"pitch" + ext, target_[1]);
232 targetDict.readEntry(
"roll" + ext, target_[2]);
234 const dictionary& pitchAngleDict(coeffs_.subDict(
"pitchAngles"));
235 theta_[0] =
degToRad(pitchAngleDict.get<scalar>(
"theta0Ini"));
236 theta_[1] =
degToRad(pitchAngleDict.get<scalar>(
"theta1cIni"));
237 theta_[2] =
degToRad(pitchAngleDict.get<scalar>(
"theta1sIni"));
239 coeffs_.readEntry(
"calcFrequency", calcFrequency_);
241 coeffs_.readIfPresent(
"nIter", nIter_);
242 coeffs_.readIfPresent(
"tol", tol_);
243 coeffs_.readIfPresent(
"relax", relax_);
245 if (coeffs_.readIfPresent(
"dTheta", dTheta_))
250 coeffs_.readIfPresent(
"alpha", alpha_);
256 const List<vector>&
x = rotor_.x();
259 auto& t = ttheta.ref();
263 scalar
psi =
x[i].y();
264 t[i] = theta_[0] + theta_[1]*
cos(
psi) + theta_[2]*
sin(
psi);
288 correctTrim(
rho,
U, force);
Different types of constants.
Graphite solid properties.
virtual void correct(const vectorField &U, vectorField &force)
Correct the model.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
A list of keyword definitions, which are a keyword followed by a number of values (eg...
void correctTrim(const RhoFieldType &rho, const vectorField &U, vectorField &force)
Correct the model.
virtual void read(const dictionary &dict)
Read.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Macros for easy insertion into run-time selection tables.
bool read(const char *buf, int32_t &val)
Same as readInt32.
#define forAll(list, i)
Loop across all elements in list.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
const dimensionedScalar e
Elementary charge.
A class representing the concept of a GeometricField of 1 used to avoid unnecessary manipulations for...
dimensionedScalar cos(const dimensionedScalar &ds)
A class for handling words, derived from Foam::string.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
constexpr scalar pi(M_PI)
vector calcCoeffs(const RhoFieldType &rho, const vectorField &U, const scalarField &alphag, vectorField &force) const
Calculate the rotor force and moment coefficients vector.
virtual tmp< scalarField > thetag() const
Return the geometric angle of attack [rad].
dimensionedScalar sin(const dimensionedScalar &ds)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
defineTypeNameAndDebug(combustionModel, 0)
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
targetCoeffTrim(const fv::rotorDiskSource &rotor, const dictionary &dict)
Constructor from rotor and dictionary.
constexpr scalar radToDeg(const scalar rad) noexcept
Conversion from radians to degrees.
dimensionedScalar pow4(const dimensionedScalar &ds)
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
void read(const dictionary &dict)
Read.
Field< vector > vectorField
Specialisation of Field<T> for vector.
const volScalarField & psi
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
A class for managing temporary objects.
Tensor of scalars, i.e. Tensor<scalar>.
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
static constexpr const zero Zero
Global zero (0)