46 template<>
const char*
56 template<>
const char*
71 void Foam::fv::rotorDiskSource::readCoeffs()
73 UName_ = coeffs().lookupOrDefault<word>(
"U",
"U");
76 scalar rpm(coeffs().lookup<scalar>(
"rpm"));
79 coeffs().lookup(
"nBlades") >> nBlades_;
81 inletFlow_ = inletFlowTypeNames_.read(coeffs().lookup(
"inletFlowType"));
83 coeffs().lookup(
"tipEffect") >> tipEffect_;
85 const dictionary& flapCoeffs(coeffs().subDict(
"flapCoeffs"));
86 flapCoeffs.lookup(
"beta0") >> flap_.beta0;
87 flapCoeffs.lookup(
"beta1c") >> flap_.beta1c;
88 flapCoeffs.lookup(
"beta2s") >> flap_.beta2s;
90 flap_.beta1c =
degToRad(flap_.beta1c);
91 flap_.beta2s =
degToRad(flap_.beta2s);
94 createCoordinateSystem();
101 trim_->read(coeffs());
105 writeField(
"thetag", trim_->thetag()(),
true);
106 writeField(
"faceArea", area_,
true);
111 void Foam::fv::rotorDiskSource::checkData()
114 switch (set_.selectionType())
121 profiles_.connectBlades(blade_.profileName(), blade_.profileID());
126 coeffs().lookup(
"inletVelocity") >> inletVelocity_;
129 case inletFlowType::surfaceNormal:
133 coeffs().lookup<scalar>(
"inletNormalVelocity")
135 inletVelocity_ = -coordSys_.R().e3()*UIn;
138 case inletFlowType::local:
153 <<
"Source cannot be used with '"
155 <<
"' mode. Please use one of: " <<
nl
168 void Foam::fv::rotorDiskSource::setFaceArea(
vector& axis,
const bool correct)
172 static const scalar tol = 0.8;
174 const label nInternalFaces = mesh().nInternalFaces();
175 const polyBoundaryMesh& pbm = mesh().boundaryMesh();
183 UIndirectList<label>(cellAddr, set_.cells()) =
185 labelList nbrFaceCellAddr(mesh().nFaces() - nInternalFaces, -1);
188 const polyPatch& pp = pbm[
patchi];
194 label facei = pp.start() + i;
195 label nbrFacei = facei - nInternalFaces;
196 label own = mesh().faceOwner()[facei];
197 nbrFaceCellAddr[nbrFacei] = cellAddr[own];
206 for (
label facei = 0; facei < nInternalFaces; facei++)
208 const label own = cellAddr[mesh().faceOwner()[facei]];
209 const label nbr = cellAddr[mesh().faceNeighbour()[facei]];
211 if ((own != -1) && (nbr == -1))
213 vector nf = Sf[facei]/magSf[facei];
215 if ((nf & axis) > tol)
217 area_[own] += magSf[facei];
221 else if ((own == -1) && (nbr != -1))
223 vector nf = Sf[facei]/magSf[facei];
225 if ((-nf & axis) > tol)
227 area_[nbr] += magSf[facei];
237 const polyPatch& pp = pbm[
patchi];
245 const label facei = pp.start() + j;
246 const label own = cellAddr[mesh().faceOwner()[facei]];
247 const label nbr = nbrFaceCellAddr[facei - nInternalFaces];
248 const vector nf = Sfp[j]/magSfp[j];
250 if ((own != -1) && (nbr == -1) && ((nf & axis) > tol))
252 area_[own] += magSfp[j];
261 const label facei = pp.start() + j;
262 const label own = cellAddr[mesh().faceOwner()[facei]];
263 const vector nf = Sfp[j]/magSfp[j];
265 if ((own != -1) && ((nf & axis) > tol))
267 area_[own] += magSfp[j];
287 mesh().time().
name(),
295 UIndirectList<scalar>(area.primitiveField(), set_.cells()) = area_;
297 Info<<
type() <<
": " <<
name() <<
" writing field " << area.name()
305 void Foam::fv::rotorDiskSource::createCoordinateSystem()
312 geometryModeType gm =
313 geometryModeTypeNames_.read(coeffs().lookup(
"geometryMode"));
317 case geometryModeType::automatic:
330 origin += V[celli]*
C[celli];
332 reduce(origin, sumOp<vector>());
333 reduce(sumV, sumOp<scalar>());
338 scalar magR = -great;
342 vector test =
C[celli] - origin;
343 if (
mag(test) > magR)
349 reduce(dx1, maxMagSqrOp<vector>());
356 vector dx2 =
C[celli] - origin;
357 if (
mag(dx2) > 0.5*magR)
360 if (
mag(axis) > small)
366 reduce(axis, maxMagSqrOp<vector>());
371 vector pointAbove(coeffs().lookup(
"pointAbove"));
372 vector dir = pointAbove - origin;
374 if ((dir & axis) < 0)
380 coeffs().lookup(
"refDirection") >> refDir;
384 new cylindrical(axis, origin, UIndirectList<vector>(
C,
cells)())
389 setFaceArea(axis,
true);
393 case geometryModeType::specified:
395 coeffs().lookup(
"origin") >> origin;
396 coeffs().lookup(
"axis") >> axis;
397 coeffs().lookup(
"refDirection") >> refDir;
405 UIndirectList<vector>(mesh().
C(), set_.cells())()
409 setFaceArea(axis,
false);
415 coordSys_ = coordinateSystems::cylindrical
424 const scalar sumArea =
gSum(area_);
426 Info<<
" Rotor geometry:" <<
nl
427 <<
" - disk diameter = " << diameter <<
nl
428 <<
" - disk area = " << sumArea <<
nl
429 <<
" - origin = " << coordSys_.origin() <<
nl
430 <<
" - r-axis = " << coordSys_.R().e1() <<
nl
431 <<
" - psi-axis = " << coordSys_.R().e2() <<
nl
432 <<
" - z-axis = " << coordSys_.R().e3() <<
endl;
436 void Foam::fv::rotorDiskSource::constructGeometry()
444 if (area_[i] > rootVSmall)
449 x_[i] = coordSys_.localPosition(
C[celli]);
452 rMax_ =
max(rMax_, x_[i].
x());
455 scalar
psi = x_[i].y();
459 flap_.beta0 - flap_.beta1c*
cos(
psi) - flap_.beta2s*
sin(
psi);
463 scalar
c =
cos(beta);
464 scalar
s =
sin(beta);
466 invR_[i] = R_[i].T();
480 case inletFlowType::surfaceNormal:
482 return tmp<vectorField>
489 case inletFlowType::local:
491 return U.primitiveField();
511 const word& modelType,
517 set_(mesh, coeffs()),
522 inletVelocity_(
Zero),
525 x_(set_.nCells(),
Zero),
526 R_(set_.nCells(),
I),
527 invR_(set_.nCells(),
I),
528 area_(set_.nCells(),
Zero),
533 blade_(coeffs().subDict(
"blade")),
534 profiles_(coeffs().subDict(
"profiles")),
558 const word& fieldName
565 name() +
":rotorForce",
566 mesh().time().
name(),
579 coeffs().lookup(
"rhoRef") >> rhoRef_;
582 trim_->correct(Uin, force);
588 if (mesh().time().writeTime())
599 const word& fieldName
606 name() +
":rotorForce",
607 mesh().time().
name(),
620 trim_->correct(
rho, Uin, force);
626 if (mesh().time().writeTime())
642 set_.topoChange(map);
654 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.
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 wordList addSupFields() const
Return the list of fields for which the fvModel adds source term.
static const NamedEnum< inletFlowType, 3 > inletFlowTypeNames_
rotorDiskSource(const word &name, const word &modelType, const fvMesh &mesh, const dictionary &dict)
Construct from components.
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 addSup(fvMatrix< vector > &eqn, const word &fieldName) const
Source term to momentum equation.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
virtual ~rotorDiskSource()
Destructor.
static const NamedEnum< geometryModeType, 2 > geometryModeTypeNames_
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 scalar twoPi(2 *pi)
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)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
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.
Tensor< scalar > tensor
Tensor of scalars.
Ostream & endl(Ostream &os)
Add newline and flush stream.
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.
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.
word name(const complex &)
Return a string representation of a complex.
UList< label > labelUList
dimensionedScalar cos(const dimensionedScalar &ds)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)