57 { geometryModeType::gmAuto,
"auto" },
58 { geometryModeType::gmSpecified,
"specified" },
68 { inletFlowType::ifFixed,
"fixed" },
69 { inletFlowType::ifSurfaceNormal,
"surfaceNormal" },
70 { inletFlowType::ifLocal,
"local" },
96 scalar UIn(
coeffs_.
get<scalar>(
"inletNormalVelocity"));
116 <<
"Source cannot be used with '"
118 <<
"' mode. Please use one of: " <<
nl
132 static const scalar tol = 0.8;
134 const label nInternalFaces = mesh_.nInternalFaces();
144 labelList nbrFaceCellAddr(mesh_.nBoundaryFaces(), -1);
153 label facei = pp.
start() + i;
154 label nbrFacei = facei - nInternalFaces;
155 label own = mesh_.faceOwner()[facei];
156 nbrFaceCellAddr[nbrFacei] = cellAddr[own];
165 for (label facei = 0; facei < nInternalFaces; facei++)
167 const label own = cellAddr[mesh_.faceOwner()[facei]];
168 const label nbr = cellAddr[mesh_.faceNeighbour()[facei]];
170 if ((own != -1) && (nbr == -1))
172 vector nf = Sf[facei]/magSf[facei];
174 if ((nf & axis) > tol)
176 area_[own] += magSf[facei];
180 else if ((own == -1) && (nbr != -1))
182 vector nf = Sf[facei]/magSf[facei];
184 if ((-nf & axis) > tol)
186 area_[nbr] += magSf[facei];
197 const vectorField& Sfp = mesh_.Sf().boundaryField()[patchi];
198 const scalarField& magSfp = mesh_.magSf().boundaryField()[patchi];
204 const label facei = pp.
start() + j;
205 const label own = cellAddr[mesh_.faceOwner()[facei]];
206 const label nbr = nbrFaceCellAddr[facei - nInternalFaces];
207 const vector nf = Sfp[j]/magSfp[j];
209 if ((own != -1) && (nbr == -1) && ((nf & axis) > tol))
211 area_[own] += magSfp[j];
220 const label facei = pp.
start() + j;
221 const label own = cellAddr[mesh_.faceOwner()[facei]];
222 const vector nf = Sfp[j]/magSfp[j];
224 if ((own != -1) && ((nf & axis) > tol))
226 area_[own] += magSfp[j];
246 mesh_.time().timeName(),
256 Info<<
type() <<
": " << name_ <<
" writing field " << area.name()
272 geometryModeTypeNames_.get(
"geometryMode", coeffs_);
284 const label celli = cells_[i];
286 origin += V[celli]*
C[celli];
294 scalar magR = -GREAT;
297 const label celli = cells_[i];
298 vector test =
C[celli] - origin;
299 if (
mag(test) > magR)
311 const label celli = cells_[i];
312 vector dx2 =
C[celli] - origin;
313 if (
mag(dx2) > 0.5*magR)
316 if (
mag(axis) > SMALL)
328 vector dir = pointAbove - origin;
330 if ((dir & axis) < 0)
336 coeffs_.readEntry(
"refDirection", refDir);
340 setFaceArea(axis,
true);
346 coeffs_.readEntry(
"origin", origin);
347 coeffs_.readEntry(
"axis", axis);
348 coeffs_.readEntry(
"refDirection", refDir);
350 setFaceArea(axis,
false);
357 <<
"Unknown geometryMode " << geometryModeTypeNames_[gm]
358 <<
". Available geometry modes include "
359 << geometryModeTypeNames_
366 const scalar sumArea =
gSum(area_);
368 Info<<
" Rotor gometry:" <<
nl
369 <<
" - disk diameter = " << diameter <<
nl
370 <<
" - disk area = " << sumArea <<
nl
371 <<
" - origin = " << coordSys_.origin() <<
nl
372 <<
" - r-axis = " << coordSys_.e1() <<
nl
373 <<
" - psi-axis = " << coordSys_.e2() <<
nl
374 <<
" - z-axis = " << coordSys_.e3() <<
endl;
387 if (area_[i] > ROOTVSMALL)
390 x_[i] = coordSys_.localPosition(cc[i]);
393 rMax_ =
max(rMax_, x_[i].
x());
396 scalar
psi = x_[i].y();
400 flap_.beta0 - flap_.beta1c*
cos(
psi) - flap_.beta2s*
sin(
psi);
406 Rcone_[i] =
tensor(c, 0, -
s, 0, 1, 0,
s, 0, c);
420 case ifSurfaceNormal:
428 return U.primitiveField();
448 const word& modelType,
459 inletVelocity_(
Zero),
462 x_(cells_.size(),
Zero),
463 Rcone_(cells_.size(),
I),
464 area_(cells_.size(),
Zero),
468 blade_(coeffs_.subDict(
"blade")),
469 profiles_(coeffs_.subDict(
"profiles"))
487 name_ +
":rotorForce",
488 mesh_.time().timeName(),
496 coeffs_.readEntry(
"rhoRef", rhoRef_);
499 trim_->correct(Uin, force);
505 if (mesh_.time().writeTime())
523 name_ +
":rotorForce",
524 mesh_.time().timeName(),
532 trim_->correct(
rho, Uin, force);
533 calculate(
rho, Uin, trim_->thetag(), force);
538 if (mesh_.time().writeTime())
549 coeffs_.readEntry(
"fields", fieldNames_);
553 omega_ =
rpmToRads(coeffs_.get<scalar>(
"rpm"));
555 coeffs_.readEntry(
"nBlades", nBlades_);
557 inletFlowTypeNames_.readEntry(
"inletFlowType", coeffs_, inletFlow_);
559 coeffs_.readEntry(
"tipEffect", tipEffect_);
561 const dictionary& flapCoeffs(coeffs_.subDict(
"flapCoeffs"));
562 flap_.beta0 =
degToRad(flapCoeffs.
get<scalar>(
"beta0"));
563 flap_.beta1c =
degToRad(flapCoeffs.
get<scalar>(
"beta1c"));
564 flap_.beta2s =
degToRad(flapCoeffs.
get<scalar>(
"beta2s"));
568 createCoordinateSystem();
575 trim_->read(coeffs_);
579 writeField(
"thetag", trim_->thetag()(),
true);
580 writeField(
"faceArea", area_,
true);
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.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Defines the attributes of an object for which implicit objectRegistry management is supported,...
virtual bool read()
Re-read model coefficients if they have changed.
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
A List with indirect addressing. Like IndirectList but does not store addressing.
Vector< Cmpt > & normalise(const scalar tol=ROOTVSMALL)
Inplace normalise the vector by its magnitude.
const List< label > & profileID() const
Return const access to the profile ID list.
const List< word > & profileName() const
Return const access to the profile name list.
A cylindrical coordinate system (r-theta-z). The coordinate system angle theta is always in radians.
virtual const vector e3() const
The local Cartesian z-axis in global coordinates.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
A special matrix type and solver, designed for finite volume solutions of scalar equations....
const dimensionSet & dimensions() const noexcept
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
Mesh data needed to do the Finite Volume discretisation.
Intermediate abstract class for handling cell-set options for the derived fvOptions.
static const Enum< selectionModeType > selectionModeTypeNames_
List of selection mode type names.
selectionModeType selectionMode() const noexcept
Return the cell selection mode.
Base abstract class for handling finite volume options (i.e. fvOption).
dictionary coeffs_
Dictionary containing source coefficients.
void resetApplied()
Resize/reset applied flag list for all fieldNames_ entries.
Applies cell-based momentum sources on velocity (i.e. U) within a specified cylindrical region to app...
static const Enum< geometryModeType > geometryModeTypeNames_
Names for geometryModeType.
void setFaceArea(vector &axis, const bool correct)
Set the face areas per cell, and optionally correct the rotor axis.
void checkData()
Check data.
inletFlowType inletFlow_
Inlet flow type.
void constructGeometry()
Construct geometry.
coordSystem::cylindrical coordSys_
Rotor local cylindrical coordinate system (r-theta-z)
virtual bool read(const dictionary &dict)
Read source dictionary.
bladeModel blade_
Blade data.
tmp< vectorField > inflowVelocity(const volVectorField &U) const
Return the inlet flow field.
void createCoordinateSystem()
Create the coordinate system.
vector inletVelocity_
Inlet velocity for specified inflow.
inletFlowType
Options for the inlet flow type specification.
virtual void addSup(fvMatrix< vector > &eqn, const label fieldi)
Add explicit contribution to momentum equation.
profileModelList profiles_
Profile data.
static const Enum< inletFlowType > inletFlowTypeNames_
Names for inletFlowType.
geometryModeType
Options for the geometry type specification.
A class representing the concept of a GeometricField of 1 used to avoid unnecessary manipulations for...
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
A patch is a list of labels that address the faces in the global face list.
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
label start() const
Return start label of this patch in the polyMesh face list.
void connectBlades(const List< word > &names, List< label > &addr) const
Set blade->profile addressing.
virtual bool write(const bool valid=true) const
Write using setting from DB.
A class for managing temporary objects.
Base class for trim models for handling blade characteristics and thrust-torque relations.
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
const volScalarField & psi
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
A special matrix type and solver, designed for finite volume solutions of scalar equations.
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)
Different types of constants.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Type gSum(const FieldField< Field, Type > &f)
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
const dimensionSet dimArea(sqr(dimLength))
dimensionedScalar sin(const dimensionedScalar &ds)
messageStream Info
Information stream (stdout output on master, null elsewhere)
static const Identity< scalar > I
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Ostream & endl(Ostream &os)
Add newline and flush stream.
constexpr scalar rpmToRads() noexcept
Multiplication factor for revolutions/minute to radians/sec.
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
errorManip< error > abort(error &err)
static constexpr const zero Zero
Global zero (0)
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
label checkData(const fvMesh &mesh, const instantList &timeDirs, wordList &objectNames)
Check if fields are good to use (available at all times)
const dimensionSet dimVolume(pow3(dimLength))
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
errorManipArg< error, int > exit(error &err, const int errNo=1)
UIndirectList< label > labelUIndList
UIndirectList of labels.
dimensionedScalar cos(const dimensionedScalar &ds)
constexpr char nl
The newline '\n' character (0x0a)
dimensionedScalar beta("beta", dimless/dimTemperature, laminarTransport)
#define forAll(list, i)
Loop across all elements in list.
Unit conversion functions.