Commit dcc1dc13 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: cylindricalCS is now in radians only (issue #863)

- this provides internal consistency and allows direct use of the
  coordinate angle with sin(), cos() functions.
  It eliminates potential issues that could otherwise arise from
  alternative user input.

  Eg, in mixerFvMesh it would have previously been possible to specify
  the coordinate system to use degrees or radians, but these units were
  not checked when determining the tangential sweep positions.

NOTE: this may represent a breaking change if user coding has been
relying on cylindrical coordinate system in degrees.
parent efaa9f84
......@@ -381,7 +381,7 @@ void Foam::fv::rotorDiskSource::createCoordinateSystem()
}
}
coordSys_ = cylindricalCS("rotorCoordSys", origin, axis, refDir, false);
coordSys_ = cylindricalCS("rotorCS", origin, axis, refDir);
const scalar sumArea = gSum(area_);
const scalar diameter = Foam::sqrt(4.0*sumArea/mathematical::pi);
......@@ -483,7 +483,7 @@ Foam::fv::rotorDiskSource::rotorDiskSource
R_(cells_.size(), I),
invR_(cells_.size(), I),
area_(cells_.size(), 0.0),
coordSys_(false),
coordSys_(),
cylindrical_(),
rMax_(0.0),
trim_(trimModel::New(*this, coeffs_)),
......
......@@ -196,7 +196,7 @@ protected:
//- Area [m2]
List<scalar> area_;
//- Rotor local cylindrical coordinate system (r, theta, z)
//- Rotor local cylindrical coordinate system (r-theta-z)
cylindricalCS coordSys_;
//- Rotor transformation coordinate system
......@@ -279,7 +279,7 @@ public:
// (Cylindrical r, theta, z)
inline const List<point>& x() const;
//- Return the rotor coordinate system (r, theta, z)
//- Return the rotor coordinate system (r-theta-z)
inline const cylindricalCS& coordSys() const;
......
......@@ -207,7 +207,7 @@ void Foam::ParticleCollector<CloudType>::initConcentricCircles()
faces_.setSize(nFace);
area_.setSize(nFace);
coordSys_ = cylindricalCS("coordSys", origin, normal_[0], refDir, false);
coordSys_ = cylindricalCS("collector", origin, normal_[0], refDir);
List<label> ptIDs(identity(nPointPerRadius));
......@@ -539,7 +539,7 @@ Foam::ParticleCollector<CloudType>::ParticleCollector
faceTris_(),
nSector_(0),
radius_(),
coordSys_(false),
coordSys_(),
normal_(),
negateParcelsOppositeNormal_
(
......
......@@ -98,8 +98,8 @@ Foam::cylindricalCS Foam::blockEdges::arcEdge::calcAngle()
radius_ = mag(r3);
// The corresponding local cylindrical coordinate system (degrees)
return cylindricalCS("arcEdgeCS", centre, arcAxis, r1, true);
// The corresponding local cylindrical coordinate system (radians)
return cylindricalCS("arc", centre, arcAxis, r1);
}
......@@ -158,13 +158,14 @@ Foam::point Foam::blockEdges::arcEdge::position(const scalar lambda) const
return p3_;
}
return cs_.globalPosition(vector(radius_, lambda*angle_, 0.0));
// The angle is degrees, the coordinate system in radians
return cs_.globalPosition(vector(radius_, degToRad(lambda*angle_), 0));
}
Foam::scalar Foam::blockEdges::arcEdge::length() const
{
return degToRad(angle_*radius_);
return degToRad(radius_*angle_);
}
......
......@@ -64,7 +64,7 @@ class arcEdge
//- The arc radius
scalar radius_;
//- The local cylindrical coordinate system (degrees)
//- The local cylindrical coordinate system
cylindricalCS cs_;
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -24,41 +24,69 @@ License
\*---------------------------------------------------------------------------*/
#include "cylindricalCS.H"
#include "one.H"
#include "mathematicalConstants.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Issue warning if 'degrees' keyword was specified and true.
// Compatibility change after 1806.
static inline void warnCompatDegrees(const Foam::dictionary& dict)
{
if (Pstream::parRun() ? Pstream::master() : true)
{
std::cerr
<< "--> FOAM IOWarning :" << nl
<< " Found [v1806] 'degrees' keyword in dictionary \""
<< dict.name().c_str() << "\" Ignored, now radians only." << nl
<< std::endl;
}
}
//- Convert from Cartesian (to Cylindrical)
static inline vector fromCartesian(const vector& v)
{
return vector(hypot(v.x(), v.y()), atan2(v.y(), v.x()), v.z());
}
//- Convert to Cartesian (from Cylindrical)
static inline vector toCartesian(const vector& v)
{
return vector(v.x()*cos(v.y()), v.x()*sin(v.y()), v.z());
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cylindricalCS::cylindricalCS(const bool inDegrees)
Foam::cylindricalCS::cylindricalCS()
:
coordinateSystem(),
inDegrees_(inDegrees)
coordinateSystem()
{}
Foam::cylindricalCS::cylindricalCS
(
const coordinateSystem& cs,
const bool inDegrees
const coordinateSystem& cs
)
:
coordinateSystem(cs),
inDegrees_(inDegrees)
coordinateSystem(cs)
{}
Foam::cylindricalCS::cylindricalCS
(
const word& name,
const coordinateSystem& cs,
const bool inDegrees
const coordinateSystem& cs
)
:
coordinateSystem(name, cs),
inDegrees_(inDegrees)
coordinateSystem(name, cs)
{}
......@@ -66,12 +94,10 @@ Foam::cylindricalCS::cylindricalCS
(
const word& name,
const point& origin,
const coordinateRotation& cr,
const bool inDegrees
const coordinateRotation& cr
)
:
coordinateSystem(name, origin, cr),
inDegrees_(inDegrees)
coordinateSystem(name, origin, cr)
{}
......@@ -80,12 +106,10 @@ Foam::cylindricalCS::cylindricalCS
const word& name,
const point& origin,
const vector& axis,
const vector& dirn,
const bool inDegrees
const vector& dirn
)
:
coordinateSystem(name, origin, axis, dirn),
inDegrees_(inDegrees)
coordinateSystem(name, origin, axis, dirn)
{}
......@@ -95,9 +119,13 @@ Foam::cylindricalCS::cylindricalCS
const dictionary& dict
)
:
coordinateSystem(name, dict),
inDegrees_(dict.lookupOrDefault("degrees", true))
{}
coordinateSystem(name, dict)
{
if (dict.lookupOrDefault("degrees", false))
{
warnCompatDegrees(dict);
}
}
Foam::cylindricalCS::cylindricalCS
......@@ -106,30 +134,16 @@ Foam::cylindricalCS::cylindricalCS
const dictionary& dict
)
:
coordinateSystem(obr, dict),
inDegrees_(dict.lookupOrDefault("degrees", true))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cylindricalCS::~cylindricalCS()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::cylindricalCS::inDegrees() const
coordinateSystem(obr, dict)
{
return inDegrees_;
if (dict.lookupOrDefault("degrees", false))
{
warnCompatDegrees(dict);
}
}
bool& Foam::cylindricalCS::inDegrees()
{
return inDegrees_;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::vector Foam::cylindricalCS::localToGlobal
(
......@@ -137,14 +151,9 @@ Foam::vector Foam::cylindricalCS::localToGlobal
bool translate
) const
{
scalar theta
(
local.y()*(inDegrees_ ? constant::mathematical::pi/180.0 : 1.0)
);
return coordinateSystem::localToGlobal
(
vector(local.x()*cos(theta), local.x()*sin(theta), local.z()),
toCartesian(local),
translate
);
}
......@@ -156,19 +165,22 @@ Foam::tmp<Foam::vectorField> Foam::cylindricalCS::localToGlobal
bool translate
) const
{
scalarField theta
(
local.component(vector::Y)
*(inDegrees_ ? constant::mathematical::pi/180.0 : 1.0)
);
const label len = local.size();
auto tresult = tmp<vectorField>::New(len);
auto& result = tresult.ref();
vectorField lc(local.size());
lc.replace(vector::X, local.component(vector::X)*cos(theta));
lc.replace(vector::Y, local.component(vector::X)*sin(theta));
lc.replace(vector::Z, local.component(vector::Z));
for (label i=0; i<len; ++i)
{
result[i] =
coordinateSystem::localToGlobal
(
toCartesian(local[i]),
translate
);
}
return coordinateSystem::localToGlobal(lc, translate);
return tresult;
}
......@@ -178,21 +190,10 @@ Foam::vector Foam::cylindricalCS::globalToLocal
bool translate
) const
{
const vector lc
return fromCartesian
(
coordinateSystem::globalToLocal(global, translate)
);
return vector
(
sqrt(sqr(lc.x()) + sqr(lc.y())),
atan2
(
lc.y(),
lc.x()
)*(inDegrees_ ? 180.0/constant::mathematical::pi : 1.0),
lc.z()
);
}
......@@ -202,31 +203,18 @@ Foam::tmp<Foam::vectorField> Foam::cylindricalCS::globalToLocal
bool translate
) const
{
const vectorField lc
(
coordinateSystem::globalToLocal(global, translate)
);
tmp<vectorField> tresult(new vectorField(lc.size()));
vectorField& result = tresult.ref();
result.replace
(
vector::X,
sqrt(sqr(lc.component(vector::X)) + sqr(lc.component(vector::Y)))
);
const label len = global.size();
result.replace
tmp<vectorField> tresult
(
vector::Y,
atan2
(
lc.component(vector::Y),
lc.component(vector::X)
)*(inDegrees_ ? 180.0/constant::mathematical::pi : 1.0)
coordinateSystem::globalToLocal(global, translate)
);
auto& result = tresult.ref();
result.replace(vector::Z, lc.component(vector::Z));
for (label i=0; i<len; ++i)
{
result[i] = fromCartesian(result[i]);
}
return tresult;
}
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -25,7 +25,7 @@ Class
Foam::cylindricalCS
Description
Cylindrical coordinate system
Cylindrical coordinate system, always in radians.
SourceFiles
cylindricalCS.C
......@@ -50,12 +50,6 @@ class cylindricalCS
:
public coordinateSystem
{
// Private data members
//- Are angles in degrees? (default = true)
bool inDegrees_;
protected:
// Protected Member Functions
......@@ -92,21 +86,19 @@ public:
// Constructors
//- Construct null
cylindricalCS(const bool inDegrees=true);
cylindricalCS();
//- Construct copy
cylindricalCS
(
const coordinateSystem&,
const bool inDegrees=true
const coordinateSystem&
);
//- Construct copy with a different name
cylindricalCS
(
const word& name,
const coordinateSystem&,
const bool inDegrees=true
const coordinateSystem&
);
//- Construct from origin and rotation
......@@ -114,8 +106,7 @@ public:
(
const word& name,
const point& origin,
const coordinateRotation&,
const bool inDegrees=true
const coordinateRotation&
);
//- Construct from origin and 2 axes
......@@ -124,8 +115,7 @@ public:
const word& name,
const point& origin,
const vector& axis,
const vector& dirn,
const bool inDegrees=true
const vector& dirn
);
//- Construct from dictionary and name
......@@ -136,16 +126,7 @@ public:
//- Destructor
virtual ~cylindricalCS();
// Member Functions
//- Are angles in degrees?
bool inDegrees() const;
//- Non-const access to inDegrees
bool& inDegrees();
virtual ~cylindricalCS() = default;
};
......
......@@ -269,13 +269,10 @@ Foam::mixerFvMesh::mixerFvMesh
),
csPtr_
(
coordinateSystem::New
(
"coordinateSystem",
motionDict_.subDict("coordinateSystem")
)
// Caution: must be a cylindricalCS
coordinateSystem::New(*this, motionDict_, "coordinateSystem")
),
rpm_(readScalar(motionDict_.lookup("rpm"))),
rpm_(motionDict_.get<scalar>("rpm")),
movingPointsMaskPtr_(nullptr)
{
addZonesAndModifiers();
......@@ -294,6 +291,7 @@ Foam::mixerFvMesh::~mixerFvMesh()
deleteDemandDrivenData(movingPointsMaskPtr_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Return moving points mask. Moving points marked with 1
......@@ -310,13 +308,15 @@ const Foam::scalarField& Foam::mixerFvMesh::movingPointsMask() const
bool Foam::mixerFvMesh::update()
{
// Rotational speed needs to be converted from rpm
// The tangential sweep (radians)
const vector theta(0, rpmToRads(rpm_)*time().deltaTValue(), 0);
movePoints
(
csPtr_->globalPosition
(
csPtr_->localPosition(points())
+ vector(0, rpm_*360.0*time().deltaTValue()/60.0, 0)
+ theta
*movingPointsMask()
)
);
......@@ -339,7 +339,7 @@ bool Foam::mixerFvMesh::update()
csPtr_->globalPosition
(
csPtr_->localPosition(oldPoints())
+ vector(0, rpm_*360.0*time().deltaTValue()/60.0, 0)
+ theta
*movingPointsMask()
)
);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment