60 {
"auto",
"specified"};
64 {
"fixed",
"surfaceNormal",
"local"};
76 void Foam::fv::rotorDisk::readCoeffs()
78 UName_ = coeffs().lookupOrDefault<word>(
"U",
"U");
82 coeffs().lookup(
"nBlades") >> nBlades_;
84 inletFlow_ = inletFlowTypeNames_.read(coeffs().lookup(
"inletFlowType"));
86 coeffs().lookup(
"tipEffect") >> tipEffect_;
88 const dictionary& flapCoeffs(coeffs().subDict(
"flapCoeffs"));
89 flap_.beta0 = flapCoeffs.lookup<scalar>(
"beta0",
unitDegrees);
90 flap_.beta1c = flapCoeffs.lookup<scalar>(
"beta1c",
unitDegrees);
91 flap_.beta2s = flapCoeffs.lookup<scalar>(
"beta2s",
unitDegrees);
94 createCoordinateSystem();
101 trim_->read(coeffs());
105 writeField(
"thetag", trim_->thetag()());
106 writeField(
"faceArea", area_);
111 void Foam::fv::rotorDisk::checkData()
114 switch (set_.selectionType())
121 profiles_.connectBlades
123 blade_.profileName(),
124 blade_.profileIndex()
130 coeffs().lookup(
"inletVelocity") >> inletVelocity_;
133 case inletFlowType::surfaceNormal:
137 coeffs().lookup<scalar>(
"inletNormalVelocity")
139 inletVelocity_ = -coordSys_.R().e3()*UIn;
142 case inletFlowType::local:
157 <<
"Source cannot be used with '"
159 <<
"' mode. Please use one of: " <<
nl
172 void Foam::fv::rotorDisk::setFaceArea(
vector& axis,
const bool correct)
176 static const scalar tol = 0.8;
178 const label nInternalFaces = mesh().nInternalFaces();
179 const polyBoundaryMesh& pbm = mesh().boundaryMesh();
187 UIndirectList<label>(cellAddr, set_.cells()) =
189 labelList nbrFaceCellAddr(mesh().nFaces() - nInternalFaces, -1);
192 const polyPatch& pp = pbm[
patchi];
198 label facei = pp.start() + i;
199 label nbrFacei = facei - nInternalFaces;
200 label own = mesh().faceOwner()[facei];
201 nbrFaceCellAddr[nbrFacei] = cellAddr[own];
210 for (
label facei = 0; facei < nInternalFaces; facei++)
212 const label own = cellAddr[mesh().faceOwner()[facei]];
213 const label nbr = cellAddr[mesh().faceNeighbour()[facei]];
215 if ((own != -1) && (nbr == -1))
217 vector nf = Sf[facei]/magSf[facei];
219 if ((nf & axis) > tol)
221 area_[own] += magSf[facei];
225 else if ((own == -1) && (nbr != -1))
227 vector nf = Sf[facei]/magSf[facei];
229 if ((-nf & axis) > tol)
231 area_[nbr] += magSf[facei];
241 const polyPatch& pp = pbm[
patchi];
249 const label facei = pp.start() + j;
250 const label own = cellAddr[mesh().faceOwner()[facei]];
251 const label nbr = nbrFaceCellAddr[facei - nInternalFaces];
252 const vector nf = Sfp[j]/magSfp[j];
254 if ((own != -1) && (nbr == -1) && ((nf & axis) > tol))
256 area_[own] += magSfp[j];
265 const label facei = pp.start() + j;
266 const label own = cellAddr[mesh().faceOwner()[facei]];
267 const vector nf = Sfp[j]/magSfp[j];
269 if ((own != -1) && ((nf & axis) > tol))
271 area_[own] += magSfp[j];
291 mesh().time().
name(),
299 UIndirectList<scalar>(area.primitiveField(), set_.cells()) = area_;
301 Info<<
type() <<
": " <<
name() <<
" writing field " << area.name()
309 void Foam::fv::rotorDisk::createCoordinateSystem()
316 geometryModeType gm =
317 geometryModeTypeNames_.read(coeffs().lookup(
"geometryMode"));
321 case geometryModeType::automatic:
334 origin += V[celli]*
C[celli];
336 reduce(origin, sumOp<vector>());
337 reduce(sumV, sumOp<scalar>());
342 scalar magR = -great;
346 vector test =
C[celli] - origin;
347 if (
mag(test) > magR)
353 reduce(dx1, maxMagSqrOp<vector>());
360 vector dx2 =
C[celli] - origin;
361 if (
mag(dx2) > 0.5*magR)
364 if (
mag(axis) > small)
370 reduce(axis, maxMagSqrOp<vector>());
375 vector pointAbove(coeffs().lookup(
"pointAbove"));
376 vector dir = pointAbove - origin;
378 if ((dir & axis) < 0)
384 coeffs().lookup(
"refDirection") >> refDir;
388 new cylindrical(axis, origin, UIndirectList<vector>(
C,
cells)())
393 setFaceArea(axis,
true);
397 case geometryModeType::specified:
399 coeffs().lookup(
"origin") >> origin;
400 coeffs().lookup(
"axis") >> axis;
401 coeffs().lookup(
"refDirection") >> refDir;
409 UIndirectList<vector>(mesh().
C(), set_.cells())()
413 setFaceArea(axis,
false);
420 coordinateSystems::cylindrical(
"rotorCoordSys", origin, axis, refDir);
422 const scalar sumArea =
gSum(area_);
424 Info<<
" Rotor geometry:" <<
nl
425 <<
" - disk diameter = " << diameter <<
nl
426 <<
" - disk area = " << sumArea <<
nl
427 <<
" - origin = " << coordSys_.origin() <<
nl
428 <<
" - r-axis = " << coordSys_.R().e1() <<
nl
429 <<
" - psi-axis = " << coordSys_.R().e2() <<
nl
430 <<
" - z-axis = " << coordSys_.R().e3() <<
endl;
434 void Foam::fv::rotorDisk::constructGeometry()
442 if (area_[i] > rootVSmall)
447 x_[i] = coordSys_.localPosition(
C[celli]);
450 rMax_ =
max(rMax_, x_[i].
x());
453 scalar
psi = x_[i].y();
457 flap_.beta0 - flap_.beta1c*
cos(
psi) - flap_.beta2s*
sin(
psi);
461 scalar
c =
cos(beta);
462 scalar
s =
sin(beta);
464 invR_[i] = R_[i].T();
478 case inletFlowType::surfaceNormal:
480 return tmp<vectorField>
487 case inletFlowType::local:
489 return U.primitiveField();
509 const word& modelType,
515 set_(mesh, coeffs()),
520 inletVelocity_(
Zero),
523 x_(set_.nCells(),
Zero),
524 R_(set_.nCells(),
I),
525 invR_(set_.nCells(),
I),
526 area_(set_.nCells(),
Zero),
531 blade_(coeffs().subDict(
"blade")),
532 profiles_(coeffs().subDict(
"profiles")),
563 name() +
":rotorForce",
564 mesh().time().
name(),
577 coeffs().lookup(
"rhoRef") >> rhoRef_;
580 trim_->correct(Uin, force);
586 if (mesh().time().writeTime())
604 name() +
":rotorForce",
605 mesh().time().
name(),
618 trim_->correct(
rho, Uin, force);
624 if (mesh().time().writeTime())
640 set_.topoChange(map);
652 set_.distribute(map);
static const Foam::dimensionedScalar C("C", Foam::dimTemperature, 234.5)
#define forAll(list, i)
Loop across all elements in list.
Macros for easy insertion into run-time selection tables.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Generic GeometricField class.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Initialise the NamedEnum HashTable from the static list of names.
virtual Ostream & write(const char)=0
Write character.
Templated 3D SphericalTensor derived from VectorSpace adding construction from 1 component,...
A coordinate rotation specified using global axis.
A list of keyword definitions, which are a keyword followed by any number of values (e....
A special matrix type and solver, designed for finite volume solutions of scalar equations....
const dimensionSet & dimensions() const
Mesh data needed to do the Finite Volume discretisation.
Finite volume model abstract base class.
virtual bool read(const dictionary &dict)
Read source dictionary.
Cell based momentum source which approximates the mean effects of rotor forces on a cylindrical regio...
virtual bool movePoints()
Update for mesh motion.
virtual void addSup(const volVectorField &U, fvMatrix< vector > &eqn) const
Source term to momentum equation.
virtual wordList addSupFields() const
Return the list of fields for which the fvModel adds source term.
rotorDisk(const word &name, const word &modelType, const fvMesh &mesh, const dictionary &dict)
Construct from components.
static const NamedEnum< inletFlowType, 3 > inletFlowTypeNames_
static const NamedEnum< geometryModeType, 2 > geometryModeTypeNames_
virtual void topoChange(const polyTopoChangeMap &)
Update topology using the given map.
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
virtual bool read(const dictionary &dict)
Read source dictionary.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
virtual ~rotorDisk()
Destructor.
A class representing the concept of a GeometricField of 1 used to avoid unnecessary manipulations for...
static const NamedEnum< selectionTypes, 4 > selectionTypeNames
Word list of selection type names.
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
virtual bool write(const bool write=true) const
Write using setting from DB.
A class for managing temporary objects.
A class for handling words, derived from string.
A class representing the concept of 0 used to avoid unnecessary manipulations for objects that are kn...
#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;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const volScalarField & psi
void correct(const RdeltaTType &rDeltaT, const RhoType &rho, volScalarField &psi, const surfaceScalarField &phiCorr, const SpType &Sp, const SuType &Su)
const dimensionedScalar c
Speed of light in a vacuum.
label calculate(const fvMesh &mesh, const labelHashSet &patchIDs, const scalar minFaceFraction, GeometricField< scalar, PatchField, GeoMesh > &distance)
Calculate distance data from patches.
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< word > wordList
A List of words.
Type gSum(const FieldField< Field, Type > &f)
VolField< vector > volVectorField
List< label > labelList
A List of labels.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
addToRunTimeSelectionTable(polyPatch, mergedCyclicPolyPatch, word)
Tensor< scalar > tensor
Tensor of scalars.
Ostream & endl(Ostream &os)
Add newline and flush stream.
word name(const bool)
Return a word representation of a bool.
errorManip< error > abort(error &err)
dimensionedScalar sin(const dimensionedScalar &ds)
IOstream & fixed(IOstream &io)
static const Identity< scalar > I
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
addBackwardCompatibleToRunTimeSelectionTable(fvPatchScalarField, coupledTemperatureFvPatchScalarField, patchMapper, turbulentTemperatureCoupledBaffleMixed, "compressible::turbulentTemperatureCoupledBaffleMixed")
Vector< scalar > vector
A scalar version of the templated Vector.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
dimensionedScalar sqrt(const dimensionedScalar &ds)
const dimensionSet dimVolume
VolField< scalar > volScalarField
dimensioned< scalar > mag(const dimensioned< Type > &)
defineTypeNameAndDebug(combustionModel, 0)
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
Field< vector > vectorField
Specialisation of Field<T> for vector.
const dimensionSet dimArea
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
UList< label > labelUList
dimensionedScalar cos(const dimensionedScalar &ds)
const unitConversion unitDegrees
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.