ENH: improve, simplify, rationalize coordinate system handling (issue #863)

Previously the coordinate system functionality was split between
coordinateSystem and coordinateRotation. The coordinateRotation stored
the rotation tensor and handled all tensor transformations.

The functionality has now been revised and consolidated into the
coordinateSystem classes. The sole purpose of coordinateRotation
is now just to provide a selectable mechanism of how to define the
rotation tensor (eg, axis-angle, euler angles, local axes) for user
input, but after providing the appropriate rotation tensor it has
no further influence on the transformations.

--

The coordinateSystem class now contains an origin and a base rotation
tensor directly and various transformation methods.

  - The origin represents the "shift" for a local coordinate system.

  - The base rotation tensor represents the "tilt" or orientation
    of the local coordinate system in general (eg, for mapping
    positions), but may require position-dependent tensors when
    transforming vectors and tensors.

For some coordinate systems (currently the cylindrical coordinate system),
the rotation tensor required for rotating a vector or tensor is
position-dependent.

The new coordinateSystem and its derivates (cartesian, cylindrical,
indirect) now provide a uniform() method to define if the rotation
tensor is position dependent/independent.

The coordinateSystem transform and invTransform methods are now
available in two-parameter forms for obtaining position-dependent
rotation tensors. Eg,

      ... = cs.transform(globalPt, someVector);

In some cases it can be useful to use query uniform() to avoid
storage of redundant values.

      if (cs.uniform())
      {
          vector xx = cs.transform(someVector);
      }
      else
      {
          List<vector> xx = cs.transform(manyPoints, someVector);
      }

Support transform/invTransform for common data types:
   (scalar, vector, sphericalTensor, symmTensor, tensor).

====================
  Breaking Changes
====================

- These changes to coordinate systems and rotations may represent
  a breaking change for existing user coding.

- Relocating the rotation tensor into coordinateSystem itself means
  that the coordinate system 'R()' method now returns the rotation
  directly instead of the coordinateRotation. The method name 'R()'
  was chosen for consistency with other low-level entities (eg,
  quaternion).

  The following changes will be needed in coding:

      Old:  tensor rot = cs.R().R();
      New:  tensor rot = cs.R();

      Old:  cs.R().transform(...);
      New:  cs.transform(...);

  Accessing the runTime selectable coordinateRotation
  has moved to the rotation() method:

      Old:  Info<< "Rotation input: " << cs.R() << nl;
      New:  Info<< "Rotation input: " << cs.rotation() << nl;

- Naming consistency changes may also cause code to break.

      Old:  transformVector()
      New:  transformPrincipal()

  The old method name transformTensor() now simply becomes transform().

====================
  New methods
====================

For operations requiring caching of the coordinate rotations, the
'R()' method can be used with multiple input points:

       tensorField rots(cs.R(somePoints));

   and later

       Foam::transformList(rots, someVectors);

The rotation() method can also be used to change the rotation tensor
via a new coordinateRotation definition (issue #879).

The new methods transformPoint/invTransformPoint provide
transformations with an origin offset using Cartesian for both local
and global points. These can be used to determine the local position
based on the origin/rotation without interpreting it as a r-theta-z
value, for example.

================
  Input format
================

- Streamline dictionary input requirements

  * The default type is cartesian.
  * The default rotation type is the commonly used axes rotation
    specification (with e1/e2/3), which is assumed if the 'rotation'
    sub-dictionary does not exist.

    Example,

    Compact specification:

        coordinateSystem
        {
            origin  (0 0 0);
            e2      (0 1 0);
            e3      (0.5 0 0.866025);
        }

    Full specification (also accepts the longer 'coordinateRotation'
    sub-dictionary name):

        coordinateSystem
        {
            type    cartesian;
            origin  (0 0 0);

            rotation
            {
                type    axes;
                e2      (0 1 0);
                e3      (0.5 0 0.866025);
            }
        }

   This simplifies the input for many cases.

- Additional rotation specification 'none' (an identity rotation):

      coordinateSystem
      {
          origin  (0 0 0);
          rotation { type none; }
      }

- Additional rotation specification 'axisAngle', which is similar
  to the -rotate-angle option for transforming points (issue #660).
  For some cases this can be more intuitive.

  For example,

      rotation
      {
          type    axisAngle;
          axis    (0 1 0);
          angle   30;
      }
  vs.
      rotation
      {
          type    axes;
          e2      (0 1 0);
          e3      (0.5 0 0.866025);
      }

- shorter names (or older longer names) for the coordinate rotation
  specification.

     euler         EulerRotation
     starcd        STARCDRotation
     axes          axesRotation

================
  Coding Style
================
- use Foam::coordSystem namespace for categories of coordinate systems
  (cartesian, cylindrical, indirect). This reduces potential name
  clashes and makes a clearer declaration. Eg,

      coordSystem::cartesian csys_;

  The older names (eg, cartesianCS, etc) remain available via typedefs.

- added coordinateRotations namespace for better organization and
  reduce potential name clashes.
This commit is contained in:
Mark Olesen
2018-10-01 13:54:10 +02:00
parent e7a6095aaf
commit 6697bb4735
138 changed files with 4552 additions and 3014 deletions

View File

@ -59,17 +59,20 @@ cellFeatures/cellFeatures.C
csys = coordinate/systems
$(csys)/coordinateSystem.C
$(csys)/coordinateSystemNew.C
$(csys)/coordinateSystemTransform.C
$(csys)/coordinateSystems.C
$(csys)/cylindricalCS.C
$(csys)/cartesianCS.C
$(csys)/cylindricalCS.C
$(csys)/indirectCS.C
crot = coordinate/rotation
$(crot)/axesRotation.C
$(crot)/axisAngleRotation.C
$(crot)/coordinateRotation.C
$(crot)/coordinateRotationNew.C
$(crot)/cylindricalRotation.C
$(crot)/identityRotation.C
$(crot)/EulerCoordinateRotation.C
$(crot)/STARCDCoordinateRotation.C
$(crot)/cylindrical.C
polyMeshZipUpCells/polyMeshZipUpCells.C
primitiveMeshGeometry/primitiveMeshGeometry.C

View File

@ -31,24 +31,34 @@ License
namespace Foam
{
defineTypeNameAndDebug(EulerCoordinateRotation, 0);
addToRunTimeSelectionTable
(
coordinateRotation,
EulerCoordinateRotation,
dictionary
);
addToRunTimeSelectionTable
(
coordinateRotation,
EulerCoordinateRotation,
objectRegistry
);
namespace coordinateRotations
{
defineTypeName(euler);
// Standard short name
addNamedToRunTimeSelectionTable
(
coordinateRotation,
euler,
dictionary,
euler
);
// Longer name - Compat 1806
addNamedToRunTimeSelectionTable
(
coordinateRotation,
euler,
dictionary,
EulerRotation
);
}
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::tensor Foam::EulerCoordinateRotation::rotation
Foam::tensor Foam::coordinateRotations::euler::rotation
(
const vector& angles,
bool degrees
@ -84,174 +94,96 @@ Foam::tensor Foam::EulerCoordinateRotation::rotation
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::vector Foam::EulerCoordinateRotation::transform(const vector& st) const
{
return (R_ & st);
}
Foam::vector Foam::EulerCoordinateRotation::invTransform
(
const vector& st
) const
{
return (Rtr_ & st);
}
Foam::tmp<Foam::vectorField> Foam::EulerCoordinateRotation::transform
(
const vectorField& st
) const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::vectorField> Foam::EulerCoordinateRotation::invTransform
(
const vectorField& st
) const
{
NotImplemented;
return nullptr;
}
const Foam::tensorField& Foam::EulerCoordinateRotation::Tr() const
{
NotImplemented;
return NullObjectRef<tensorField>();
}
Foam::tmp<Foam::tensorField> Foam::EulerCoordinateRotation::transformTensor
(
const tensorField& st
) const
{
NotImplemented;
return nullptr;
}
Foam::tensor Foam::EulerCoordinateRotation::transformTensor
(
const tensor& st
) const
{
return (R_ & st & Rtr_);
}
Foam::tmp<Foam::tensorField> Foam::EulerCoordinateRotation::transformTensor
(
const tensorField& st,
const labelList& cellMap
) const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::symmTensorField> Foam::EulerCoordinateRotation::
transformVector
(
const vectorField& st
) const
{
tmp<symmTensorField> tfld(new symmTensorField(st.size()));
symmTensorField& fld = tfld.ref();
forAll(fld, i)
{
fld[i] = transformPrincipal(R_, st[i]);
}
return tfld;
}
Foam::symmTensor Foam::EulerCoordinateRotation::transformVector
(
const vector& st
) const
{
return transformPrincipal(R_, st);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::EulerCoordinateRotation::EulerCoordinateRotation()
Foam::coordinateRotations::euler::euler()
:
R_(sphericalTensor::I),
Rtr_(sphericalTensor::I)
coordinateRotation(),
angles_(Zero),
degrees_(true)
{}
Foam::EulerCoordinateRotation::EulerCoordinateRotation
(
const EulerCoordinateRotation& r
)
Foam::coordinateRotations::euler::euler(const euler& crot)
:
R_(r.R_),
Rtr_(r.Rtr_)
coordinateRotation(crot),
angles_(crot.angles_),
degrees_(crot.degrees_)
{}
Foam::EulerCoordinateRotation::EulerCoordinateRotation
Foam::coordinateRotations::euler::euler
(
const vector& phiThetaPsi,
const bool degrees
bool degrees
)
:
R_(rotation(phiThetaPsi, degrees)),
Rtr_(R_.T())
coordinateRotation(),
angles_(phiThetaPsi),
degrees_(degrees)
{}
Foam::EulerCoordinateRotation::EulerCoordinateRotation
Foam::coordinateRotations::euler::euler
(
const scalar phi,
const scalar theta,
const scalar psi,
const bool degrees
scalar phi,
scalar theta,
scalar psi,
bool degrees
)
:
R_(rotation(vector(phi, theta, psi), degrees)),
Rtr_(R_.T())
coordinateRotation(),
angles_(phi, theta, psi),
degrees_(degrees)
{}
Foam::EulerCoordinateRotation::EulerCoordinateRotation
Foam::coordinateRotations::euler::euler(const dictionary& dict)
:
coordinateRotation(),
angles_(dict.getCompat<vector>("angles", {{"rotation", 1806}})),
degrees_(dict.lookupOrDefault("degrees", true))
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::coordinateRotations::euler::clear()
{
angles_ = Zero;
degrees_ = true;
}
Foam::tensor Foam::coordinateRotations::euler::R() const
{
return euler::rotation(angles_, degrees_);
}
void Foam::coordinateRotations::euler::write(Ostream& os) const
{
os << "euler-angles(" << (degrees_ ? "deg" : "rad") << "): " << angles_;
}
void Foam::coordinateRotations::euler::writeEntry
(
const dictionary& dict
)
:
R_
(
rotation
(
dict.get<vector>("rotation"),
dict.lookupOrDefault("degrees", true)
)
),
Rtr_(R_.T())
{}
const word& keyword,
Ostream& os
) const
{
os.beginBlock(keyword);
os.writeEntry("type", type());
os.writeEntry("angles", angles_);
if (!degrees_)
{
os.writeEntry("degrees", "false");
}
Foam::EulerCoordinateRotation::EulerCoordinateRotation
(
const dictionary& dict,
const objectRegistry&
)
:
EulerCoordinateRotation(dict)
{}
os.endBlock();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -22,7 +22,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::EulerCoordinateRotation
Foam::coordinateRotations::euler
Description
A coordinateRotation defined in the z-x-z (intrinsic) Euler convention.
@ -34,24 +34,29 @@ Description
For reference and illustration, see
https://en.wikipedia.org/wiki/Euler_angles
The rotation angles are in degrees, unless otherwise explicitly specified:
\verbatim
coordinateRotation
{
type EulerRotation;
degrees false;
rotation (0 0 3.141592654);
type euler;
angles (0 0 180);
}
\endverbatim
\heading Dictionary entries
\table
Property | Description | Required | Default
type | Type name: euler (or EulerRotation) | yes |
angles | The z-x-z rotation angles | yes |
degrees | Angles are in degrees | no | true
\endtable
SourceFiles
EulerCoordinateRotation.C
\*---------------------------------------------------------------------------*/
#ifndef EulerCoordinateRotation_H
#define EulerCoordinateRotation_H
#ifndef coordinateRotations_euler_H
#define coordinateRotations_euler_H
#include "coordinateRotation.H"
@ -59,73 +64,62 @@ SourceFiles
namespace Foam
{
namespace coordinateRotations
{
/*---------------------------------------------------------------------------*\
Class EulerCoordinateRotation Declaration
Class coordinateRotations::euler Declaration
\*---------------------------------------------------------------------------*/
class EulerCoordinateRotation
class euler
:
public coordinateRotation
{
// Private Member Data
// Private Data
//- Local-to-global transformation tensor
tensor R_;
//- The rotation angles
vector angles_;
//- Global-to-Local transformation tensor
tensor Rtr_;
//- Angles measured in degrees
bool degrees_;
public:
//- Runtime type information
TypeName("EulerRotation");
TypeNameNoDebug("euler");
// Constructors
//- Construct null
EulerCoordinateRotation();
//- Construct null - an identity transform
euler();
//- Construct as copy
EulerCoordinateRotation(const EulerCoordinateRotation& r);
//- Copy construct
euler(const euler& crot);
//- Construct from rotation vector
EulerCoordinateRotation
(
const vector& phiThetaPsi,
const bool degrees
);
//- Construct from Euler rotation angles (z-x-z)
euler(const vector& phiThetaPsi, bool degrees);
//- Construct from components of rotation vector
EulerCoordinateRotation
(
const scalar phi,
const scalar theta,
const scalar psi,
const bool degrees
);
//- Construct from Euler rotation angles (z-x-z)
euler(scalar phi, scalar theta, scalar psi, bool degrees);
//- Construct from dictionary
explicit EulerCoordinateRotation(const dictionary& dict);
//- Construct from dictionary and a registry (typically a mesh)
EulerCoordinateRotation
(
const dictionary& dict,
const objectRegistry& unused
);
explicit euler(const dictionary& dict);
//- Return clone
autoPtr<coordinateRotation> clone() const
{
return
autoPtr<coordinateRotation>::NewFrom
<EulerCoordinateRotation>(*this);
<coordinateRotations::euler>(*this);
}
//- Destructor
virtual ~euler() = default;
// Static Member Functions
//- The rotation tensor calculated for the specified Euler angles
@ -135,91 +129,29 @@ public:
// Member Functions
//- Reset rotation to an identity rotation
virtual void clear()
{
R_ = sphericalTensor::I;
Rtr_ = sphericalTensor::I;
}
//- Reset specification
virtual void clear();
//- Update the rotation for a list of cells
virtual void updateCells(const polyMesh&, const labelList&)
{}
//- The rotation tensor calculated for the specified Euler angles.
virtual tensor R() const;
//- Return local-to-global transformation tensor
virtual const tensor& R() const
{
return R_;
}
//- Write information
virtual void write(Ostream& os) const;
//- Return global-to-local transformation tensor
virtual const tensor& Rtr() const
{
return Rtr_;
};
//- Return local Cartesian x-axis in global coordinates
virtual const vector e1() const
{
return Rtr_.x();
}
//- Return local Cartesian y-axis in global coordinates
virtual const vector e2() const
{
return Rtr_.y();
}
//- Return local Cartesian z-axis in global coordinates
virtual const vector e3() const
{
return Rtr_.z();
}
//- Return transformation tensor field
virtual const tensorField& Tr() const;
//- Transform vectorField using transformation tensor field
virtual tmp<vectorField> transform(const vectorField& st) const;
//- Transform vector using transformation tensor
virtual vector transform(const vector& st) const;
//- Inverse transform vectorField using transformation tensor field
virtual tmp<vectorField> invTransform(const vectorField& st) const;
//- Inverse transform vector using transformation tensor
virtual vector invTransform(const vector& st) const;
//- Transform tensor field using transformation tensorField
virtual tmp<tensorField> transformTensor(const tensorField& st) const;
//- Transform tensor using transformation tensorField
virtual tensor transformTensor(const tensor& st) const;
//- Transform tensor sub-field using transformation tensorField
virtual tmp<tensorField> transformTensor
(
const tensorField& st,
const labelList& cellMap
) const;
//- Transform vectorField using transformation tensorField and return
// symmetrical tensorField
virtual tmp<symmTensorField> transformVector
(
const vectorField& st
) const;
//- Transform vector using transformation tensor and return
// symmetrical tensor
virtual symmTensor transformVector(const vector& st) const;
//- Write dictionary entry
virtual void writeEntry(const word& keyword, Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace coordinateRotations
//- Compatibility typedef 1806
typedef coordinateRotations::euler EulerCoordinateRotation;
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -31,128 +31,37 @@ License
namespace Foam
{
defineTypeNameAndDebug(STARCDCoordinateRotation, 0);
addToRunTimeSelectionTable
(
coordinateRotation,
STARCDCoordinateRotation,
dictionary
);
addToRunTimeSelectionTable
(
coordinateRotation,
STARCDCoordinateRotation,
objectRegistry
);
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::vector Foam::STARCDCoordinateRotation::transform(const vector& st) const
{
return (R_ & st);
}
Foam::vector Foam::STARCDCoordinateRotation::invTransform
(
const vector& st
) const
{
return (Rtr_ & st);
}
Foam::tmp<Foam::vectorField> Foam::STARCDCoordinateRotation::transform
(
const vectorField& st
) const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::vectorField> Foam::STARCDCoordinateRotation::invTransform
(
const vectorField& st
) const
{
NotImplemented;
return nullptr;
}
const Foam::tensorField& Foam::STARCDCoordinateRotation::Tr() const
{
NotImplemented;
return NullObjectRef<tensorField>();
}
Foam::tmp<Foam::tensorField> Foam::STARCDCoordinateRotation::transformTensor
(
const tensorField& st
) const
{
NotImplemented;
return nullptr;
}
Foam::tensor Foam::STARCDCoordinateRotation::transformTensor
(
const tensor& st
) const
{
return (R_ & st & Rtr_);
}
Foam::tmp<Foam::tensorField> Foam::STARCDCoordinateRotation::transformTensor
(
const tensorField& st,
const labelList& cellMap
) const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::symmTensorField> Foam::STARCDCoordinateRotation::
transformVector
(
const vectorField& st
) const
{
tmp<symmTensorField> tfld(new symmTensorField(st.size()));
symmTensorField& fld = tfld.ref();
forAll(fld, i)
namespace coordinateRotations
{
fld[i] = transformPrincipal(R_, st[i]);
defineTypeName(starcd);
// Standard short name
addNamedToRunTimeSelectionTable
(
coordinateRotation,
starcd,
dictionary,
starcd
);
// Longer name - Compat 1806
addNamedToRunTimeSelectionTable
(
coordinateRotation,
starcd,
dictionary,
STARCDRotation
);
}
return tfld;
}
Foam::symmTensor Foam::STARCDCoordinateRotation::transformVector
(
const vector& st
) const
{
return transformPrincipal(R_, st);
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::tensor Foam::STARCDCoordinateRotation::rotation
Foam::tensor Foam::coordinateRotations::starcd::rotation
(
const vector& angles,
const bool degrees
bool degrees
)
{
scalar z = angles.component(vector::X); // 1. Rotate about Z
@ -170,7 +79,6 @@ Foam::tensor Foam::STARCDCoordinateRotation::rotation
const scalar cy = cos(y); const scalar sy = sin(y);
const scalar cz = cos(z); const scalar sz = sin(z);
return
tensor
(
@ -183,72 +91,94 @@ Foam::tensor Foam::STARCDCoordinateRotation::rotation
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation()
Foam::coordinateRotations::starcd::starcd()
:
R_(sphericalTensor::I),
Rtr_(sphericalTensor::I)
coordinateRotation(),
angles_(Zero),
degrees_(true)
{}
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
(
const STARCDCoordinateRotation& r
)
Foam::coordinateRotations::starcd::starcd(const starcd& crot)
:
R_(r.R_),
Rtr_(r.Rtr_)
coordinateRotation(crot),
angles_(crot.angles_),
degrees_(crot.degrees_)
{}
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
Foam::coordinateRotations::starcd::starcd
(
const vector& rotZrotXrotY,
const bool degrees
bool degrees
)
:
R_(rotation(rotZrotXrotY, degrees)),
Rtr_(R_.T())
coordinateRotation(),
angles_(rotZrotXrotY),
degrees_(degrees)
{}
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
Foam::coordinateRotations::starcd::starcd
(
const scalar rotZ,
const scalar rotX,
const scalar rotY,
const bool degrees
scalar rotZ,
scalar rotX,
scalar rotY,
bool degrees
)
:
R_(rotation(vector(rotZ, rotX, rotY), degrees)),
Rtr_(R_.T())
coordinateRotation(),
angles_(rotZ, rotX, rotY),
degrees_(degrees)
{}
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
Foam::coordinateRotations::starcd::starcd(const dictionary& dict)
:
coordinateRotation(),
angles_(dict.getCompat<vector>("angles", {{"rotation", 1806}})),
degrees_(dict.lookupOrDefault("degrees", true))
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::coordinateRotations::starcd::clear()
{
angles_ = Zero;
degrees_ = true;
}
Foam::tensor Foam::coordinateRotations::starcd::R() const
{
return starcd::rotation(angles_, degrees_);
}
void Foam::coordinateRotations::starcd::write(Ostream& os) const
{
os << "starcd-angles(" << (degrees_ ? "deg" : "rad") << "): " << angles_;
}
void Foam::coordinateRotations::starcd::writeEntry
(
const dictionary& dict
)
:
R_
(
rotation
(
dict.get<vector>("rotation"),
dict.lookupOrDefault("degrees", true)
)
),
Rtr_(R_.T())
{}
const word& keyword,
Ostream& os
) const
{
os.beginBlock(keyword);
os.writeEntry("type", type());
os.writeEntry("angles", angles_);
if (!degrees_)
{
os.writeEntry("degrees", "false");
}
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
(
const dictionary& dict,
const objectRegistry&
)
:
STARCDCoordinateRotation(dict)
{}
os.endBlock();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -22,7 +22,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::STARCDCoordinateRotation
Foam::coordinateRotations::starcd
Description
A coordinateRotation defined by the STAR-CD convention.
@ -36,19 +36,26 @@ Description
\verbatim
coordinateRotation
{
type STARCDRotation;
degrees false;
rotation (0 0 3.141592654);
type starcd;
angles (0 0 180);
}
\endverbatim
\heading Dictionary entries
\table
Property | Description | Required | Default
type | Type name: starcd (or STARCDRotation) | yes |
angles | The z-x-y rotation angles | yes |
degrees | Angles are in degrees | no | true
\endtable
SourceFiles
STARCDCoordinateRotation.C
\*---------------------------------------------------------------------------*/
#ifndef STARCDCoordinateRotation_H
#define STARCDCoordinateRotation_H
#ifndef coordinateRotations_starcd_H
#define coordinateRotations_starcd_H
#include "coordinateRotation.H"
@ -56,74 +63,62 @@ SourceFiles
namespace Foam
{
namespace coordinateRotations
{
/*---------------------------------------------------------------------------*\
Class STARCDCoordinateRotation Declaration
Class coordinateRotations::starcd Declaration
\*---------------------------------------------------------------------------*/
class STARCDCoordinateRotation
class starcd
:
public coordinateRotation
{
// Private Member Data
// Private Data
//- Local-to-Global transformation tensor
tensor R_;
//- The rotation angles
vector angles_;
//- Global-to-Local transformation tensor
tensor Rtr_;
//- Angles measured in degrees
bool degrees_;
public:
//- Runtime type information
TypeName("STARCDRotation");
TypeNameNoDebug("starcd");
// Constructors
//- Construct null
STARCDCoordinateRotation();
//- Construct null - an identity transform
starcd();
//- Construct as copy
STARCDCoordinateRotation(const STARCDCoordinateRotation& r);
//- Copy construct
starcd(const starcd& crot);
//- Construct from rotation vector
STARCDCoordinateRotation
(
const vector& rotZrotXrotY,
const bool degrees
);
starcd(const vector& rotZrotXrotY, bool degrees);
//- Construct from components of rotation vector
STARCDCoordinateRotation
(
const scalar rotZ,
const scalar rotX,
const scalar rotY,
const bool degrees
);
starcd(scalar rotZ, scalar rotX, scalar rotY, bool degrees);
//- Construct from dictionary
explicit STARCDCoordinateRotation(const dictionary& dict);
//- Construct from dictionary and a registry (typically a mesh)
STARCDCoordinateRotation
(
const dictionary& dict,
const objectRegistry& unused
);
explicit starcd(const dictionary& dict);
//- Return clone
autoPtr<coordinateRotation> clone() const
{
return
autoPtr<coordinateRotation>::NewFrom
<STARCDCoordinateRotation>(*this);
<coordinateRotations::starcd>(*this);
}
//- Destructor
virtual ~starcd() = default;
// Static Member Functions
//- The rotation tensor calculated for the specified STARCD angles
@ -133,91 +128,29 @@ public:
// Member Functions
//- Reset rotation to an identity rotation
virtual void clear()
{
R_ = sphericalTensor::I;
Rtr_ = sphericalTensor::I;
}
//- Reset specification
virtual void clear();
//- Update the rotation for a list of cells
virtual void updateCells(const polyMesh&, const labelList&)
{}
//- The rotation tensor calculated for the specified STARCD angles.
virtual tensor R() const;
//- Return local-to-global transformation tensor
virtual const tensor& R() const
{
return R_;
}
//- Write information
virtual void write(Ostream& os) const;
//- Return global-to-local transformation tensor
virtual const tensor& Rtr() const
{
return Rtr_;
};
//- Return local Cartesian x-axis in global coordinates
virtual const vector e1() const
{
return Rtr_.x();
}
//- Return local Cartesian y-axis in global coordinates
virtual const vector e2() const
{
return Rtr_.y();
}
//- Return local Cartesian z-axis in global coordinates
virtual const vector e3() const
{
return Rtr_.z();
}
//- Return transformation tensor field
virtual const tensorField& Tr() const;
//- Transform vectorField using transformation tensor field
virtual tmp<vectorField> transform(const vectorField& st) const;
//- Transform vector using transformation tensor
virtual vector transform(const vector& st) const;
//- Inverse transform vectorField using transformation tensor field
virtual tmp<vectorField> invTransform(const vectorField& st) const;
//- Inverse transform vector using transformation tensor
virtual vector invTransform(const vector& st) const;
//- Transform tensor field using transformation tensorField
virtual tmp<tensorField> transformTensor(const tensorField& st) const;
//- Transform tensor using transformation tensorField
virtual tensor transformTensor(const tensor& st) const;
//- Transform tensor sub-field using transformation tensorField
virtual tmp<tensorField> transformTensor
(
const tensorField& st,
const labelList& cellMap
) const;
//- Transform vectorField using transformation tensorField and return
// symmetrical tensorField
virtual tmp<symmTensorField> transformVector
(
const vectorField& st
) const;
//- Transform vector using transformation tensor and return
// symmetrical tensor
virtual symmTensor transformVector(const vector& st) const;
//- Write dictionary entry
virtual void writeEntry(const word& keyword, Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace coordinateRotations
//- Compatibility typedef 1806
typedef coordinateRotations::starcd STARCDCoordinateRotation;
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -31,25 +31,34 @@ License
namespace Foam
{
defineTypeNameAndDebug(axesRotation, 0);
addToRunTimeSelectionTable
(
coordinateRotation,
axesRotation,
dictionary
);
addToRunTimeSelectionTable
(
coordinateRotation,
axesRotation,
objectRegistry
);
namespace coordinateRotations
{
defineTypeName(axes);
// Standard short name
addNamedToRunTimeSelectionTable
(
coordinateRotation,
axes,
dictionary,
axes
);
// Longer name - Compat 1806
addNamedToRunTimeSelectionTable
(
coordinateRotation,
axes,
dictionary,
axesRotation
);
}
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::tensor Foam::axesRotation::rotation
Foam::tensor Foam::coordinateRotations::axes::rotation
(
const vector& axis1,
const vector& axis2,
@ -143,221 +152,193 @@ Foam::tensor Foam::axesRotation::rotation
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::axesRotation::read(const dictionary& dict)
void Foam::coordinateRotations::axes::read(const dictionary& dict)
{
vector axis1, axis2;
axisOrder order = E3_E1;
if
(
dict.readIfPresent("e1", axis1)
&& dict.readIfPresent("e2", axis2)
dict.readIfPresent("e1", axis1_)
&& dict.readIfPresent("e2", axis2_)
)
{
order = E1_E2;
order_ = E1_E2;
}
else if
(
dict.readIfPresent("e2", axis1)
&& dict.readIfPresent("e3", axis2)
dict.readIfPresent("e2", axis1_)
&& dict.readIfPresent("e3", axis2_)
)
{
order = E2_E3;
order_ = E2_E3;
}
else if
(
dict.readIfPresent("e3", axis1)
&& dict.readIfPresent("e1", axis2)
dict.readIfPresent("e3", axis1_)
&& dict.readIfPresent("e1", axis2_)
)
{
order = E3_E1;
order_ = E3_E1;
}
else if
(
dict.readIfPresent("axis", axis1)
&& dict.readIfPresent("direction", axis2)
dict.readIfPresent("axis", axis1_)
&& dict.readIfPresent("direction", axis2_)
)
{
order = E3_E1_COMPAT;
order_ = E3_E1_COMPAT;
}
else
{
FatalErrorInFunction
FatalIOErrorInFunction(dict)
<< "No entries of the type (e1, e2) or (e2, e3) or (e3, e1) found"
<< exit(FatalError);
<< exit(FatalIOError);
}
R_ = rotation(axis1, axis2, order);
Rtr_ = R_.T();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::axesRotation::axesRotation()
Foam::coordinateRotations::axes::axes()
:
R_(sphericalTensor::I),
Rtr_(sphericalTensor::I)
coordinateRotation(),
axis1_(0,0,1), // e3 = global Z
axis2_(1,0,0), // e1 = global X
order_(E3_E1)
{}
Foam::axesRotation::axesRotation(const axesRotation& r)
Foam::coordinateRotations::axes::axes(const axes& crot)
:
R_(r.R_),
Rtr_(r.Rtr_)
coordinateRotation(crot),
axis1_(crot.axis1_),
axis2_(crot.axis2_),
order_(crot.order_)
{}
Foam::axesRotation::axesRotation(const tensor& R)
Foam::coordinateRotations::axes::axes(axes&& crot)
:
R_(R),
Rtr_(R_.T())
coordinateRotation(std::move(crot)),
axis1_(std::move(crot.axis1_)),
axis2_(std::move(crot.axis2_)),
order_(crot.order_)
{}
Foam::axesRotation::axesRotation
Foam::coordinateRotations::axes::axes
(
const vector& axis,
const vector& dir,
const axisOrder& order
const vector& axis1,
const vector& axis2,
axisOrder order
)
:
R_(rotation(axis, dir, order)),
Rtr_(R_.T())
coordinateRotation(),
axis1_(axis1),
axis2_(axis2),
order_(order)
{}
Foam::axesRotation::axesRotation
(
const vector& axis
)
Foam::coordinateRotations::axes::axes(const vector& axis)
:
R_(rotation(axis, findOrthogonal(axis), E3_E1)),
Rtr_(R_.T())
coordinateRotations::axes(axis, Zero, E3_E1_COMPAT) // Guess second axis
{}
Foam::axesRotation::axesRotation
(
const dictionary& dict
)
Foam::coordinateRotations::axes::axes(const dictionary& dict)
:
R_(sphericalTensor::I),
Rtr_(sphericalTensor::I)
coordinateRotations::axes()
{
read(dict);
}
Foam::axesRotation::axesRotation
(
const dictionary& dict,
const objectRegistry&
)
:
axesRotation(dict)
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
const Foam::tensorField& Foam::axesRotation::Tr() const
void Foam::coordinateRotations::axes::clear()
{
NotImplemented;
return NullObjectRef<tensorField>();
axis1_ = vector(0,0,1); // e3 = global Z
axis2_ = vector(1,0,0); // e1 = global X
order_ = E3_E1;
}
Foam::tmp<Foam::vectorField> Foam::axesRotation::transform
(
const vectorField& st
) const
Foam::tensor Foam::coordinateRotations::axes::R() const
{
return (R_ & st);
return axes::rotation(axis1_, axis2_, order_);
}
Foam::vector Foam::axesRotation::transform(const vector& st) const
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::coordinateRotations::axes::write(Ostream& os) const
{
return (R_ & st);
}
Foam::tmp<Foam::vectorField> Foam::axesRotation::invTransform
(
const vectorField& st
) const
{
return (Rtr_ & st);
}
Foam::vector Foam::axesRotation::invTransform(const vector& st) const
{
return (Rtr_ & st);
}
Foam::tmp<Foam::tensorField> Foam::axesRotation::transformTensor
(
const tensorField& st
) const
{
NotImplemented;
return nullptr;
}
Foam::tensor Foam::axesRotation::transformTensor
(
const tensor& st
) const
{
return (R_ & st & Rtr_);
}
Foam::tmp<Foam::tensorField> Foam::axesRotation::transformTensor
(
const tensorField& st,
const labelList& cellMap
) const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::symmTensorField> Foam::axesRotation::transformVector
(
const vectorField& st
) const
{
tmp<symmTensorField> tfld(new symmTensorField(st.size()));
symmTensorField& fld = tfld.ref();
forAll(fld, i)
switch (order_)
{
fld[i] = transformPrincipal(R_, st[i]);
case E1_E2:
os << "e1: " << axis1_ << " e2: " << axis2_;
break;
case E2_E3:
os << "e2: " << axis1_ << " e3: " << axis2_;
break;
case E3_E1:
os << "e1: " << axis2_ << " e3: " << axis1_;
break;
case E3_E1_COMPAT:
os << "axis: " << axis1_ << " direction: " << axis2_;
break;
}
return tfld;
}
Foam::symmTensor Foam::axesRotation::transformVector
void Foam::coordinateRotations::axes::writeEntry
(
const vector& st
const word& keyword,
Ostream& os
) const
{
return transformPrincipal(R_, st);
}
// We permit direct embedding of the axes specification without
// requiring a sub-dictionary.
const bool subDict = !keyword.empty();
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
if (subDict)
{
os.beginBlock(keyword);
os.writeEntry("type", type());
}
void Foam::axesRotation::operator=(const dictionary& dict)
{
read(dict);
switch (order_)
{
case E1_E2:
{
os.writeEntry("e1", axis1_);
os.writeEntry("e2", axis2_);
break;
}
case E2_E3:
{
os.writeEntry("e2", axis1_);
os.writeEntry("e3", axis2_);
break;
}
case E3_E1:
{
os.writeEntry("e1", axis2_);
os.writeEntry("e3", axis1_);
break;
}
case E3_E1_COMPAT:
{
os.writeEntry("axis", axis1_);
os.writeEntry("direction", axis2_);
break;
}
}
if (subDict)
{
os.endBlock();
}
}

View File

@ -22,48 +22,59 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::axesRotation
Foam::coordinateRotations::axes
Description
A coordinate rotation specified using global axes
A coordinateRotation specified using global axes.
The rotation is defined by a combination of vectors (e1/e2), (e2/e3)
or (e3/e1). Any nonorthogonality will be absorbed into the second
vector. In terms of cylindrical coordinates, the 'axis' would
correspond to the \a z-axis and the 'direction' to the \a r-axis.
or (e3/e1). Any nonorthogonality is absorbed into the second vector.
\verbatim
axesRotation
coordinateRotation
{
type axesRotation;
type axes;
e1 (1 0 0);
e2 (0 1 0);
}
\endverbatim
\heading Dictionary entries
\table
Property | Description | Required | Default
type | type name: axes (previously axesRotation) | yes |
e1 | local x-axis | partly |
e2 | local y-axis | partly |
e3 | local z-axis | partly |
\endtable
Note
It is also possible to specify in terms of \c axis and \c direction.
For cylindrical coordinates, the \c axis would correspond to the
\a z-axis and the \c direction to the \a r-axis.
SourceFiles
axesRotation.C
\*---------------------------------------------------------------------------*/
#ifndef axesRotation_H
#define axesRotation_H
#ifndef coordinateRotations_axes_H
#define coordinateRotations_axes_H
#include "vector.H"
#include "coordinateRotation.H"
#include "dictionary.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace coordinateRotations
{
/*---------------------------------------------------------------------------*\
Class axesRotation Declaration
Class coordinateRotations::axes Declaration
\*---------------------------------------------------------------------------*/
class axesRotation
class axes
:
public coordinateRotation
{
@ -76,19 +87,22 @@ public:
E1_E2, //!< The axis1 (dominant) is local X, axis2 is local Y.
E2_E3, //!< The axis1 (dominant) is local Y, axis2 is local Z.
E3_E1, //!< The axis1 (dominant) is local Z, axis2 is local X.
E3_E1_COMPAT, //!< E3_E1 specified as axis/direction.
E3_E1_COMPAT //!< E3_E1 specified as axis/direction.
};
private:
protected:
// Private data
// Protected Data
//- Local-to-Global transformation tensor
tensor R_;
//- The primary axis
vector axis1_;
//- Global-to-Local transformation tensor
tensor Rtr_;
//- The secondary axis
vector axis2_;
//- The axis order
axisOrder order_;
// Protected Member Functions
@ -100,67 +114,52 @@ private:
public:
//- Runtime type information
TypeName("axesRotation");
TypeNameNoDebug("axes");
// Constructors
//- Construct null
axesRotation();
//- Construct null - an identity transform
axes();
//- Construct as copy
axesRotation(const axesRotation& r);
//- Copy construct
axes(const axes& crot);
//- Construct from local to global rotation matrix
explicit axesRotation(const tensor& R);
//- Move construct
axes(axes&& crot);
//- Construct from two axes (axis and direction)
axesRotation
(
const vector& axis,
const vector& dir,
const axisOrder& order = E3_E1
);
//- Construct from two axes
axes(const vector& axis1, const vector& axis2, axisOrder order=E3_E1);
//- Construct from a single axis using a best-guess for the second axis
// For the best-guess, the largest component value and sign of the
// axis determines the direction orientation.
explicit axesRotation(const vector& axis);
//- Construct from a single axis (as e3) using a best-guess for the
//- second axis.
// The largest component and its sign are used when guessing
// an appropriate orientation (direction).
explicit axes(const vector& axis);
//- Construct from dictionary
explicit axesRotation(const dictionary& dict);
//- Construct from dictionary and a registry (typically a mesh)
axesRotation
(
const dictionary& dict,
const objectRegistry& unused
);
explicit axes(const dictionary& dict);
//- Return clone
autoPtr<coordinateRotation> clone() const
{
return autoPtr<coordinateRotation>::NewFrom<axesRotation>(*this);
return
autoPtr<coordinateRotation>::NewFrom
<coordinateRotations::axes>(*this);
}
//- Destructor
virtual ~axesRotation() = default;
// Member Functions
//- Reset rotation to an identity rotation
virtual void clear()
{
R_ = sphericalTensor::I;
Rtr_ = sphericalTensor::I;
}
virtual ~axes() = default;
// Static Member Functions
//- The rotation tensor calculated from two axes and their order.
// The input axes will be normalised.
// If axis2 is zero, an axis orthogonal to axis1 will be guessed.
// The largest component and its sign are used when guessing
// an appropriate orientation (direction).
static tensor rotation
(
const vector& axis1,
@ -169,90 +168,29 @@ public:
);
//- Update the rotation for a list of cells
virtual void updateCells(const polyMesh&, const labelList&)
{}
// Member Functions
//- Return local-to-global transformation tensor
virtual const tensor& R() const
{
return R_;
}
//- Reset specification
virtual void clear();
//- Return global-to-local transformation tensor
virtual const tensor& Rtr() const
{
return Rtr_;
}
//- The rotation tensor calculated from the specified axes and order
virtual tensor R() const;
//- Return local Cartesian x-axis in global coordinates
virtual const vector e1() const
{
return Rtr_.x();
}
//- Return local Cartesian y-axis in global coordinates
virtual const vector e2() const
{
return Rtr_.y();
}
//- Return local Cartesian z-axis in global coordinates
virtual const vector e3() const
{
return Rtr_.z();
}
//- Return transformation tensor field
virtual const tensorField& Tr() const;
//- Transform vectorField using transformation tensor field
virtual tmp<vectorField> transform(const vectorField& st) const;
//- Transform vector using transformation tensor
virtual vector transform(const vector& st) const;
//- Inverse transform vectorField using transformation tensor field
virtual tmp<vectorField> invTransform(const vectorField& st) const;
//- Inverse transform vector using transformation tensor
virtual vector invTransform(const vector& st) const;
//- Transform tensor field using transformation tensorField
virtual tmp<tensorField> transformTensor(const tensorField& st) const;
//- Transform tensor using transformation tensorField
virtual tensor transformTensor(const tensor& st) const;
//- Transform tensor sub-field using transformation tensorField
virtual tmp<tensorField> transformTensor
(
const tensorField& st,
const labelList& cellMap
) const;
//- Transform vectorField using transformation tensorField and return
// symmetric tensorField
virtual tmp<symmTensorField> transformVector
(
const vectorField& st
) const;
//- Transform vector using transformation tensor and return
// symmetric tensor
virtual symmTensor transformVector(const vector& st) const;
// Member Operators
//- Assign from dictionary
void operator=(const dictionary& dict);
//- Write information
virtual void write(Ostream& os) const;
//- Write dictionary entry
virtual void writeEntry(const word& keyword, Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace coordinateRotations
// Compatibility typedef 1806
typedef coordinateRotations::axes axesRotation;
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,167 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "axisAngleRotation.H"
#include "dictionary.H"
#include "quaternion.H"
#include "unitConversion.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace coordinateRotations
{
defineTypeName(axisAngle);
addToRunTimeSelectionTable
(
coordinateRotation,
axisAngle,
dictionary
);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::coordinateRotations::axisAngle::checkSpec()
{
if (mag(angle_) < VSMALL || mag(axis_) < SMALL)
{
clear(); // identity rotation
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::coordinateRotations::axisAngle::axisAngle()
:
coordinateRotation(),
axis_ (0,0,1), // e3 = global Z
angle_(Zero),
degrees_(true)
{}
Foam::coordinateRotations::axisAngle::axisAngle(const axisAngle& crot)
:
coordinateRotation(crot),
axis_(crot.axis_),
angle_(crot.angle_),
degrees_(crot.degrees_)
{
checkSpec();
}
Foam::coordinateRotations::axisAngle::axisAngle(axisAngle&& crot)
:
coordinateRotation(std::move(crot)),
axis_(std::move(crot.axis_)),
angle_(std::move(crot.angle_)),
degrees_(crot.degrees_)
{
checkSpec();
}
Foam::coordinateRotations::axisAngle::axisAngle
(
const vector& axis,
scalar angle,
bool degrees
)
:
coordinateRotation(),
axis_(axis),
angle_(angle),
degrees_(degrees)
{
checkSpec();
}
Foam::coordinateRotations::axisAngle::axisAngle(const dictionary& dict)
:
axisAngle
(
dict.get<vector>("axis"),
dict.get<scalar>("angle"),
dict.lookupOrDefault("degrees", true)
)
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::coordinateRotations::axisAngle::clear()
{
axis_ = vector(0,0,1); // e3 = global Z
angle_ = Zero;
}
Foam::tensor Foam::coordinateRotations::axisAngle::R() const
{
if (mag(angle_) < VSMALL || mag(axis_) < SMALL)
{
return sphericalTensor::I; // identity rotation
}
return quaternion(axis_, (degrees_ ? degToRad(angle_) : angle_)).R();
}
void Foam::coordinateRotations::axisAngle::write(Ostream& os) const
{
os << "rotation axis: " << axis_
<< " angle(" << (degrees_ ? "deg" : "rad") << "): " << angle_;
}
void Foam::coordinateRotations::axisAngle::writeEntry
(
const word& keyword,
Ostream& os
) const
{
os.beginBlock(keyword);
os.writeEntry("type", type());
os.writeEntry("axis", axis_);
os.writeEntry("angle", angle_);
if (!degrees_)
{
os.writeEntry("degrees", "false");
}
os.endBlock();
}
// ************************************************************************* //

View File

@ -0,0 +1,156 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::coordinateRotations::axisAngle
Description
A coordinateRotation specified by a rotation axis and a rotation angle
about that axis.
\verbatim
coordinateRotation
{
type axisAngle;
axis (1 0 0);
angle 90;
}
\endverbatim
\heading Dictionary entries
\table
Property | Description | Required | Default
type | Type name: axisAngle | yes |
axis | Axis of rotation (vector) | yes |
angle | Rotation angle | yes |
degrees | The angle is in degrees | no | true
\endtable
Note
The rotation axis will be normalized internally.
SourceFiles
axisAngle.C
\*---------------------------------------------------------------------------*/
#ifndef coordinateRotations_axisAngle_H
#define coordinateRotations_axisAngle_H
#include "coordinateRotation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace coordinateRotations
{
/*---------------------------------------------------------------------------*\
Class coordinateRotations::axisAngle Declaration
\*---------------------------------------------------------------------------*/
class axisAngle
:
public coordinateRotation
{
// Private Data
//- The rotation axis
vector axis_;
//- The rotation angle
scalar angle_;
//- Angle measured in degrees
bool degrees_;
// Private Member Functions
//- Check specification for an identity rotation
void checkSpec();
public:
//- Runtime type information
TypeNameNoDebug("axisAngle");
// Constructors
//- Construct null
axisAngle();
//- Copy construct
axisAngle(const axisAngle& crot);
//- Move construct
axisAngle(axisAngle&& crot);
//- Construct from axis and angle
axisAngle(const vector& axis, scalar angle, bool degrees);
//- Construct from dictionary
explicit axisAngle(const dictionary& dict);
//- Return clone
autoPtr<coordinateRotation> clone() const
{
return
autoPtr<coordinateRotation>::NewFrom
<coordinateRotations::axisAngle>(*this);
}
//- Destructor
virtual ~axisAngle() = default;
// Member Functions
//- Reset specification
virtual void clear();
//- Calculate and return the rotation tensor
//- calculated from axis and angle
virtual tensor R() const;
//- Write information
virtual void write(Ostream& os) const;
//- Write dictionary entry
virtual void writeEntry(const word& keyword, Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace coordinateRotations
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -31,9 +31,8 @@ License
namespace Foam
{
defineTypeNameAndDebug(coordinateRotation, 0);
defineTypeName(coordinateRotation);
defineRunTimeSelectionTable(coordinateRotation, dictionary);
defineRunTimeSelectionTable(coordinateRotation, objectRegistry);
}
@ -64,46 +63,28 @@ Foam::vector Foam::coordinateRotation::findOrthogonal(const vector& axis)
}
Foam::symmTensor Foam::coordinateRotation::transformPrincipal
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::coordinateRotation> Foam::coordinateRotation::New
(
const tensor& tt,
const vector& v
const dictionary& dict
)
{
return symmTensor
(
tt.xx()*v.x()*tt.xx()
+ tt.xy()*v.y()*tt.xy()
+ tt.xz()*v.z()*tt.xz(),
const word modelType(dict.get<word>("type"));
tt.xx()*v.x()*tt.yx()
+ tt.xy()*v.y()*tt.yy()
+ tt.xz()*v.z()*tt.yz(),
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
tt.xx()*v.x()*tt.zx()
+ tt.xy()*v.y()*tt.zy()
+ tt.xz()*v.z()*tt.zz(),
if (!cstrIter.found())
{
FatalIOErrorInFunction(dict)
<< "Unknown coordinateRotation type "
<< modelType << nl << nl
<< "Valid types: "
<< flatOutput(dictionaryConstructorTablePtr_->sortedToc())
<< exit(FatalIOError);
}
tt.yx()*v.x()*tt.yx()
+ tt.yy()*v.y()*tt.yy()
+ tt.yz()*v.z()*tt.yz(),
tt.yx()*v.x()*tt.zx()
+ tt.yy()*v.y()*tt.zy()
+ tt.yz()*v.z()*tt.zz(),
tt.zx()*v.x()*tt.zx()
+ tt.zy()*v.y()*tt.zy()
+ tt.zz()*v.z()*tt.zz()
);
}
void Foam::coordinateRotation::write(Ostream& os) const
{
os.writeEntry("e1", e1());
os.writeEntry("e2", e2());
os.writeEntry("e3", e3());
return autoPtr<coordinateRotation>(cstrIter()(dict));
}

View File

@ -21,43 +21,47 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Namespace
Foam::coordinateRotations
Description
Namespace for coordinate system rotations.
Class
Foam::coordinateRotation
Description
Abstract base class for coordinate rotation
User specification of a coordinate rotation.
\verbatim
coordinateRotation
{
type axesRotation
e1 (1 0 0);
e2 (0 1 0);
type axes
e1 (1 0 0);
e2 (0 1 0);
}
\endverbatim
Types of coordinateRotation:
-# axesRotation
-# STARCDRotation
-# cylindrical
-# EulerCoordinateRotation
Types of coordinateRotations:
-# \link coordinateRotations::identity none \endlink
-# \link coordinateRotations::axes axes \endlink
-# \link coordinateRotations::axisAngle axisAngle \endlink
-# \link coordinateRotations::cylindrical cylindrical \endlink
-# \link coordinateRotations::euler euler \endlink
-# \link coordinateRotations::starcd starcd \endlink
SourceFiles
coordinateRotation.C
coordinateRotationNew.C
\*---------------------------------------------------------------------------*/
#ifndef coordinateRotation_H
#define coordinateRotation_H
#include "vector.H"
#include "tensor.H"
#include "vectorField.H"
#include "tensorField.H"
#include "dictionary.H"
#include "runTimeSelectionTables.H"
#include "objectRegistry.H"
#include "polyMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -65,17 +69,14 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class coordinateRotation Declaration
Class coordinateRotation Declaration
\*---------------------------------------------------------------------------*/
class coordinateRotation
{
protected:
// Protected member functions
//- Transform principal
static symmTensor transformPrincipal(const tensor&, const vector&);
// Protected Member Functions
//- Determine best-guess for an orthogonal axis
static vector findOrthogonal(const vector& axis);
@ -84,25 +85,9 @@ protected:
public:
//- Runtime type information
TypeName("coordinateRotation");
TypeNameNoDebug("coordinateRotation");
// Declare run-time constructor selection table
// for constructors with dictionary and objectRegistry
declareRunTimeSelectionTable
(
autoPtr,
coordinateRotation,
objectRegistry,
(
const dictionary& dict, const objectRegistry& obr
),
(dict, obr)
);
// Declare run-time constructor selection table
// for constructors with dictionary
// Declare run-time constructor selection table from dictionary
declareRunTimeSelectionTable
(
autoPtr,
@ -114,26 +99,19 @@ public:
(dict)
);
// Constructors
// Uses all default constructors
//- Construct and return a clone
virtual autoPtr<coordinateRotation> clone() const = 0;
// Selectors
//- Select constructed from dictionary and objectRegistry
static autoPtr<coordinateRotation> New
(
const dictionary& dict,
const objectRegistry& obr
);
//- Select constructed from dictionary
static autoPtr<coordinateRotation> New
(
const dictionary& dict
);
static autoPtr<coordinateRotation> New(const dictionary& dict);
//- Destructor
@ -142,84 +120,20 @@ public:
// Member Functions
//- Reset rotation to an identity rotation
//- Reset specification
virtual void clear() = 0;
//- Update the rotation for a list of cells
virtual void updateCells
(
const polyMesh& mesh,
const labelList& cells
) = 0;
//- Return local-to-global transformation tensor
virtual const tensor& R() const = 0;
//- Return global-to-local transformation tensor
virtual const tensor& Rtr() const = 0;
//- Return local Cartesian x-axis
virtual const vector e1() const = 0;
//- Return local Cartesian y-axis
virtual const vector e2() const = 0;
//- Return local Cartesian z-axis
virtual const vector e3() const = 0;
//- Return local-to-global transformation tensor
virtual const tensorField& Tr() const = 0;
//- Return true if the rotation tensor is uniform
virtual bool uniform() const
{
return true;
}
//- Transform vectorField using transformation tensor field
virtual tmp<vectorField> transform(const vectorField& st) const = 0;
//- Transform vector using transformation tensor
virtual vector transform(const vector& st) const = 0;
//- Inverse transform vectorField using transformation tensor field
virtual tmp<vectorField> invTransform(const vectorField& st) const = 0;
//- Inverse transform vector using transformation tensor
virtual vector invTransform(const vector& st) const = 0;
//- Transform tensor field using transformation tensorField
virtual tmp<tensorField> transformTensor
(
const tensorField& st
) const = 0;
//- Transform tensor sub-field using transformation tensorField
virtual tmp<tensorField> transformTensor
(
const tensorField& st,
const labelList& cellMap
) const = 0;
//- Transform tensor using transformation tensorField
virtual tensor transformTensor(const tensor& st) const = 0;
//- Transform vectorField using transformation tensorField and return
// symmetrical tensorField
virtual tmp<symmTensorField> transformVector
(
const vectorField& st
) const = 0;
//- Transform vector using transformation tensor and return
// symmetrical tensor
virtual symmTensor transformVector(const vector& st) const = 0;
//- Calculate and return the rotation tensor
virtual tensor R() const = 0;
// Write
//- Write coordinateRotation as e1,e2,e3 vectors
virtual void write(Ostream& os) const;
//- Write information
virtual void write(Ostream& os) const = 0;
//- Write dictionary entry
virtual void writeEntry(const word& keyword, Ostream& os) const = 0;
};

View File

@ -1,76 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "coordinateRotation.H"
#include "objectRegistry.H"
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::coordinateRotation> Foam::coordinateRotation::New
(
const dictionary& dict,
const objectRegistry& obr
)
{
const word modelType(dict.get<word>("type"));
auto cstrIter = objectRegistryConstructorTablePtr_->cfind(modelType);
if (!cstrIter.found())
{
FatalIOErrorInFunction(dict)
<< "Unknown coordinateRotation type " << modelType << nl << nl
<< "Valid types: "
<< flatOutput(objectRegistryConstructorTablePtr_->sortedToc())
<< exit(FatalIOError);
}
return autoPtr<coordinateRotation>(cstrIter()(dict, obr));
}
Foam::autoPtr<Foam::coordinateRotation> Foam::coordinateRotation::New
(
const dictionary& dict
)
{
const word modelType(dict.get<word>("type"));
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
if (!cstrIter.found())
{
FatalIOErrorInFunction(dict)
<< "Unknown coordinateRotation type " << modelType << nl << nl
<< "Valid types: "
<< flatOutput(dictionaryConstructorTablePtr_->sortedToc())
<< exit(FatalIOError);
}
return autoPtr<coordinateRotation>(cstrIter()(dict));
}
// ************************************************************************* //

View File

@ -1,360 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cylindrical.H"
#include "axesRotation.H"
#include "addToRunTimeSelectionTable.H"
#include "polyMesh.H"
#include "tensorIOField.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cylindrical, 0);
addToRunTimeSelectionTable
(
coordinateRotation,
cylindrical,
dictionary
);
addToRunTimeSelectionTable
(
coordinateRotation,
cylindrical,
objectRegistry
);
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
void Foam::cylindrical::init
(
const objectRegistry& obr,
const labelUList& cells
)
{
const polyMesh& mesh = refCast<const polyMesh>(obr);
const vectorField& cc = mesh.cellCentres();
if (cells.size())
{
Rptr_.reset(new tensorField(cells.size()));
tensorField& R = Rptr_();
forAll(cells, i)
{
const label celli = cells[i];
vector dir = cc[celli] - origin_;
dir /= mag(dir) + VSMALL;
R[i] = axesRotation(e3_, dir).R();
}
}
else
{
Rptr_.reset(new tensorField(mesh.nCells()));
tensorField& R = Rptr_();
forAll(cc, celli)
{
vector dir = cc[celli] - origin_;
dir /= mag(dir) + VSMALL;
R[celli] = axesRotation(e3_, dir).R();
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cylindrical::cylindrical(const cylindrical& r)
:
Rptr_(r.Rptr_.clone()),
origin_(r.origin_),
e3_(r.e3_)
{}
Foam::cylindrical::cylindrical(const tensorField& R)
:
Rptr_(),
origin_(Zero),
e3_(Zero)
{
Rptr_() = R;
}
Foam::cylindrical::cylindrical(const dictionary& dict)
:
Rptr_(),
origin_(Zero),
e3_(Zero)
{
FatalErrorInFunction
<< " cylindrical can not be constructed from dictionary "
<< " use the constructor : "
"("
" const dictionary&, const objectRegistry&"
")"
<< exit(FatalIOError);
}
Foam::cylindrical::cylindrical
(
const dictionary& dict,
const objectRegistry& obr
)
:
Rptr_(),
origin_(Zero),
e3_(Zero)
{
// If origin is specified in the coordinateSystem
dict.parent().readIfPresent("origin", origin_);
// Rotation axis
dict.readEntry("e3", e3_);
init(obr);
}
Foam::cylindrical::cylindrical
(
const objectRegistry& obr,
const vector& axis,
const point& origin
)
:
Rptr_(),
origin_(origin),
e3_(axis)
{
init(obr);
}
Foam::cylindrical::cylindrical
(
const objectRegistry& obr,
const vector& axis,
const point& origin,
const List<label>& cells
)
:
Rptr_(),
origin_(origin),
e3_(axis)
{
init(obr, cells);
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::cylindrical::clear()
{
Rptr_.clear();
}
void Foam::cylindrical::updateCells
(
const polyMesh& mesh,
const labelList& cells
)
{
const vectorField& cc = mesh.cellCentres();
tensorField& R = Rptr_();
forAll(cells, i)
{
const label celli = cells[i];
vector dir = cc[celli] - origin_;
dir /= mag(dir) + VSMALL;
R[celli] = axesRotation(e3_, dir).R();
}
}
Foam::tmp<Foam::vectorField> Foam::cylindrical::transform
(
const vectorField& vf
) const
{
if (Rptr_->size() != vf.size())
{
FatalErrorInFunction
<< "vectorField st has different size to tensorField "
<< abort(FatalError);
}
return (Rptr_() & vf);
}
Foam::vector Foam::cylindrical::transform(const vector& v) const
{
NotImplemented;
return Zero;
}
Foam::vector Foam::cylindrical::transform
(
const vector& v,
const label cmptI
) const
{
return (Rptr_()[cmptI] & v);
}
Foam::tmp<Foam::vectorField> Foam::cylindrical::invTransform
(
const vectorField& vf
) const
{
return (Rptr_().T() & vf);
}
Foam::vector Foam::cylindrical::invTransform(const vector& v) const
{
NotImplemented;
return Zero;
}
Foam::vector Foam::cylindrical::invTransform
(
const vector& v,
const label cmptI
) const
{
return (Rptr_()[cmptI].T() & v);
}
Foam::tmp<Foam::tensorField> Foam::cylindrical::transformTensor
(
const tensorField& tf
) const
{
if (Rptr_->size() != tf.size())
{
FatalErrorInFunction
<< "tensorField st has different size to tensorField Tr"
<< abort(FatalError);
}
return (Rptr_() & tf & Rptr_().T());
}
Foam::tensor Foam::cylindrical::transformTensor
(
const tensor& t
) const
{
NotImplemented;
return Zero;
}
Foam::tmp<Foam::tensorField> Foam::cylindrical::transformTensor
(
const tensorField& tf,
const labelList& cellMap
) const
{
if (cellMap.size() != tf.size())
{
FatalErrorInFunction
<< "tensorField tf has different size to tensorField Tr"
<< abort(FatalError);
}
const tensorField& R = Rptr_();
const tensorField Rtr(R.T());
tmp<tensorField> tt(new tensorField(cellMap.size()));
tensorField& t = tt.ref();
forAll(cellMap, i)
{
const label celli = cellMap[i];
t[i] = R[celli] & tf[i] & Rtr[celli];
}
return tt;
}
Foam::tmp<Foam::symmTensorField> Foam::cylindrical::transformVector
(
const vectorField& vf
) const
{
if (Rptr_->size() != vf.size())
{
FatalErrorInFunction
<< "tensorField vf has different size to tensorField Tr"
<< abort(FatalError);
}
tmp<symmTensorField> tfld(new symmTensorField(Rptr_->size()));
symmTensorField& fld = tfld.ref();
const tensorField& R = Rptr_();
forAll(fld, i)
{
fld[i] = transformPrincipal(R[i], vf[i]);
}
return tfld;
}
Foam::symmTensor Foam::cylindrical::transformVector
(
const vector& v
) const
{
NotImplemented;
return Zero;
}
void Foam::cylindrical::write(Ostream& os) const
{
os.writeEntry("e3", e3());
}
// ************************************************************************* //

View File

@ -1,251 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cylindrical
Description
A local coordinate rotation.
The cell based rotational field can be created in two ways:
-# Each rotational tensor is defined with two vectors (\c dir and \c e3)
where <tt>dir = cellC - origin</tt> and \c e3 is the rotation axis.
Per each cell an axesRotation type of rotation is created
(cylindrical coordinates). For example:
\verbatim
cylindrical
{
type localAxes;
e3 (0 0 1);
}
\endverbatim
-# The rotational tensor field is provided at construction.
SourceFiles
cylindrical.C
\*---------------------------------------------------------------------------*/
#ifndef cylindrical_H
#define cylindrical_H
#include "point.H"
#include "vector.H"
#include "ListOps.H"
#include "coordinateRotation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cylindrical Declaration
\*---------------------------------------------------------------------------*/
class cylindrical
:
public coordinateRotation
{
// Private data
//- An autoPtr to the transformation tensor
autoPtr<tensorField> Rptr_;
//- Origin of the coordinate system
point origin_;
//- Rotation axis
vector e3_;
// Private members
//- Init transformation tensor field
void init
(
const objectRegistry& obr,
const labelUList& cells = Foam::emptyLabelList
);
public:
//- Runtime type information
TypeName("cylindrical");
// Constructors
//- Construct as copy
cylindrical(const cylindrical& r);
//- Construct from tensor Field
explicit cylindrical(const tensorField& R);
//- Construct from dictionary - for API compatibility only
explicit cylindrical(const dictionary& dict);
//- Construct from dictionary and objectRegistry
cylindrical(const dictionary& dict, const objectRegistry& obr);
//- Construct from components for all cells
cylindrical
(
const objectRegistry& obr,
const vector& axis,
const point& origin
);
//- Construct from components for list of cells
cylindrical
(
const objectRegistry& obr,
const vector& axis,
const point& origin,
const List<label>& cells
);
//- Return clone
autoPtr<coordinateRotation> clone() const
{
return autoPtr<coordinateRotation>::NewFrom<cylindrical>(*this);
}
//- Destructor
virtual ~cylindrical() = default;
// Member Functions
//- Reset rotation to an identity rotation
virtual void clear();
//- Update the rotation for a list of cells
virtual void updateCells(const polyMesh& mesh, const labelList& cells);
//- Return local-to-global transformation tensor
virtual const tensor& R() const
{
NotImplemented;
return tensor::zero;
}
//- Return global-to-local transformation tensor
virtual const tensor& Rtr() const
{
NotImplemented;
return tensor::zero;
}
//- Return local Cartesian x-axis in global coordinates
virtual const vector e1() const
{
NotImplemented;
return vector::zero;
}
//- Return local Cartesian y-axis in global coordinates
virtual const vector e2() const
{
NotImplemented;
return vector::zero;
}
//- Return local Cartesian z-axis in global coordinates
virtual const vector e3() const
{
return e3_;
}
virtual const tensorField& Tr() const
{
return *Rptr_;
}
//- Transform vectorField using transformation tensor field
virtual tmp<vectorField> transform(const vectorField& tf) const;
//- Transform vector using transformation tensor
virtual vector transform(const vector& v) const;
//- Transform vector using transformation tensor for component
virtual vector transform(const vector& v, const label cmptI) const;
//- Inverse transform vectorField using transformation tensor field
virtual tmp<vectorField> invTransform(const vectorField& vf) const;
//- Inverse transform vector using transformation tensor
virtual vector invTransform(const vector& v) const;
//- Inverse transform vector using transformation tensor for component
virtual vector invTransform(const vector& v, const label cmptI) const;
//- Return if the rotation is uniform
virtual bool uniform() const
{
return false;
}
//- Transform tensor field using transformation tensorField
virtual tmp<tensorField> transformTensor(const tensorField& tf) const;
//- Transform tensor using transformation tensorField
virtual tensor transformTensor(const tensor& t) const;
//- Transform tensor sub-field using transformation tensorField
virtual tmp<tensorField> transformTensor
(
const tensorField& tf,
const labelList& cellMap
) const;
//- Transform vectorField using transformation tensorField and return
// symmetrical tensorField
virtual tmp<symmTensorField> transformVector
(
const vectorField& vf
) const;
//- Transform vector using transformation tensor and return
// symmetrical tensor (R & st & R.T())
virtual symmTensor transformVector(const vector& v) const;
// Write
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cylindricalRotation.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace coordinateRotations
{
defineTypeName(cylindrical);
addToRunTimeSelectionTable
(
coordinateRotation,
cylindrical,
dictionary
);
}
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::tensor Foam::coordinateRotations::cylindrical::rotation
(
const vector& axis
)
{
// Guess second axis
return axes::rotation(axis, Zero, E3_E1);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::coordinateRotations::cylindrical::cylindrical(const cylindrical& crot)
:
coordinateRotations::axes(crot)
{}
Foam::coordinateRotations::cylindrical::cylindrical(const vector& axis)
:
coordinateRotations::axes(axis) // Guess second axis
{}
Foam::coordinateRotations::cylindrical::cylindrical(const dictionary& dict)
:
cylindrical(dict.getCompat<vector>("axis", {{"e3", -1806}}))
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::coordinateRotations::cylindrical::write(Ostream& os) const
{
os << type() << " axis: " << axis1_;
}
void Foam::coordinateRotations::cylindrical::writeEntry
(
const word& keyword,
Ostream& os
) const
{
os.beginBlock(keyword);
os.writeEntry("type", type());
os.writeEntry("axis", axis1_);
os.endBlock();
}
// ************************************************************************* //

View File

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::coordinateRotations::cylindrical
Description
A special purpose coordinateRotation that is generally for use in
combination with a cylindricalCS when only the orientation of the
local Z-axis is relevant.
\heading Dictionary entries
\table
Property | Description | Required | Default
type | Type name: cylindrical | yes |
axis | The z-axis | yes |
e3 | Alias for 'axis' | no |
\endtable
SourceFiles
cylindricalRotation.C
\*---------------------------------------------------------------------------*/
#ifndef coordinateRotations_cylindrical_H
#define coordinateRotations_cylindrical_H
#include "axesRotation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace coordinateRotations
{
/*---------------------------------------------------------------------------*\
Class coordinateRotations::cylindrical Declaration
\*---------------------------------------------------------------------------*/
class cylindrical
:
public coordinateRotations::axes
{
public:
//- Runtime type information
TypeNameNoDebug("cylindrical");
// Constructors
//- Copy construct
cylindrical(const cylindrical& crot);
//- Construct from single axis (as e3) using best-guess for the
//- second axis.
explicit cylindrical(const vector& axis);
//- Construct from dictionary
explicit cylindrical(const dictionary& dict);
//- Return clone
autoPtr<coordinateRotation> clone() const
{
return
autoPtr<coordinateRotation>::NewFrom
<coordinateRotations::cylindrical>(*this);
}
//- Destructor
virtual ~cylindrical() = default;
// Static Member Functions
//- The rotation tensor calculated from axes and order.
// The input axes will be normalised.
static tensor rotation(const vector& axis);
// Member Functions
//- Write information
virtual void write(Ostream& os) const;
//- Write dictionary entry
virtual void writeEntry(const word& keyword, Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace coordinateRotations
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "identityRotation.H"
#include "dictionary.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace coordinateRotations
{
defineTypeName(identity);
addToRunTimeSelectionTable
(
coordinateRotation,
identity,
dictionary
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::coordinateRotations::identity::identity()
:
coordinateRotation()
{}
Foam::coordinateRotations::identity::identity(const identity&)
:
identity()
{}
Foam::coordinateRotations::identity::identity(const dictionary&)
:
identity()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::coordinateRotations::identity::clear()
{}
Foam::tensor Foam::coordinateRotations::identity::R() const
{
return sphericalTensor::I;
}
void Foam::coordinateRotations::identity::write(Ostream& os) const
{
os << "identity rotation";
}
void Foam::coordinateRotations::identity::writeEntry
(
const word& keyword,
Ostream& os
) const
{
os.beginBlock(keyword);
os.writeEntry("type", type());
os.endBlock();
}
// ************************************************************************* //

View File

@ -0,0 +1,124 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::coordinateRotations::identity
Description
An identity coordinateRotation.
\verbatim
coordinateRotation
{
type none;
}
\endverbatim
\heading Dictionary entries
\table
Property | Description | Required | Default
type | Type name: none | yes |
\endtable
SourceFiles
identityRotation.C
\*---------------------------------------------------------------------------*/
#ifndef coordinateRotations_identity_H
#define coordinateRotations_identity_H
#include "coordinateRotation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace coordinateRotations
{
/*---------------------------------------------------------------------------*\
Class coordinateRotations::identity Declaration
\*---------------------------------------------------------------------------*/
class identity
:
public coordinateRotation
{
public:
//- Runtime type information
TypeNameNoDebug("none");
// Constructors
//- Construct null
identity();
//- Copy construct
identity(const identity& unused);
//- Construct from dictionary
explicit identity(const dictionary& unused);
//- Return clone
autoPtr<coordinateRotation> clone() const
{
return
autoPtr<coordinateRotation>::NewFrom
<coordinateRotations::identity>(*this);
}
//- Destructor
virtual ~identity() = default;
// Member Functions
//- Reset specification (no-op)
virtual void clear();
//- Return an identity rotation tensor
virtual tensor R() const;
//- Write information
virtual void write(Ostream& os) const;
//- Write dictionary entry
virtual void writeEntry(const word& keyword, Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace coordinateRotations
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -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.
@ -24,59 +24,68 @@ License
\*---------------------------------------------------------------------------*/
#include "cartesianCS.H"
#include "one.H"
#include "mathematicalConstants.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cartesianCS, 0);
addToRunTimeSelectionTable(coordinateSystem, cartesianCS, dictionary);
namespace coordSystem
{
defineTypeName(cartesian);
addToRunTimeSelectionTable(coordinateSystem, cartesian, dictionary);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cartesianCS::cartesianCS()
Foam::coordSystem::cartesian::cartesian()
:
coordinateSystem()
{}
Foam::cartesianCS::cartesianCS
(
const coordinateSystem& cs
)
Foam::coordSystem::cartesian::cartesian(const coordinateSystem& csys)
:
coordinateSystem(cs)
coordinateSystem(csys)
{}
Foam::cartesianCS::cartesianCS
(
const word& name,
const coordinateSystem& cs
)
Foam::coordSystem::cartesian::cartesian(coordinateSystem&& csys)
:
coordinateSystem(name, cs)
coordinateSystem(std::move(csys))
{}
Foam::cartesianCS::cartesianCS
Foam::coordSystem::cartesian::cartesian(autoPtr<coordinateSystem>&& csys)
:
coordinateSystem(std::move(csys))
{}
Foam::coordSystem::cartesian::cartesian
(
const word& name,
const point& origin,
const coordinateRotation& cr
const coordinateRotation& crot
)
:
coordinateSystem(name, origin, cr)
coordinateSystem(origin, crot)
{}
Foam::cartesianCS::cartesianCS
Foam::coordSystem::cartesian::cartesian
(
const point& origin,
const vector& axis,
const vector& dirn
)
:
coordinateSystem(origin, axis, dirn)
{}
Foam::coordSystem::cartesian::cartesian
(
const word& name,
const point& origin,
@ -88,7 +97,7 @@ Foam::cartesianCS::cartesianCS
{}
Foam::cartesianCS::cartesianCS
Foam::coordSystem::cartesian::cartesian
(
const word& name,
const dictionary& dict
@ -98,63 +107,20 @@ Foam::cartesianCS::cartesianCS
{}
Foam::cartesianCS::cartesianCS
Foam::coordSystem::cartesian::cartesian(const dictionary& dict)
:
coordinateSystem(dict)
{}
Foam::coordSystem::cartesian::cartesian
(
const objectRegistry& obr,
const dictionary& dict
const dictionary& dict,
const word& dictName
)
:
coordinateSystem(obr, dict)
coordinateSystem(dict, dictName)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cartesianCS::~cartesianCS()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::vector Foam::cartesianCS::localToGlobal
(
const vector& local,
bool translate
) const
{
return coordinateSystem::localToGlobal(local, translate);
}
Foam::tmp<Foam::vectorField> Foam::cartesianCS::localToGlobal
(
const vectorField& local,
bool translate
) const
{
return coordinateSystem::localToGlobal(local, translate);
}
Foam::vector Foam::cartesianCS::globalToLocal
(
const vector& global,
bool translate
) const
{
return coordinateSystem::globalToLocal(global, translate);
}
Foam::tmp<Foam::vectorField> Foam::cartesianCS::globalToLocal
(
const vectorField& global,
bool translate
) const
{
return coordinateSystem::globalToLocal(global, translate);
}
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -22,10 +22,16 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cartesianCS
Foam::coordSystem::cartesian
Description
Cartesian coordinate system
A Cartesian coordinate system
\heading Dictionary entries
\table
Property | Description | Required | Default
type | Type name: cartesian | yes |
\endtable
SourceFiles
cartesianCS.C
@ -36,85 +42,61 @@ SourceFiles
#define cartesianCS_H
#include "coordinateSystem.H"
#include "typeInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace coordSystem
{
/*---------------------------------------------------------------------------*\
Class cartesianCS Declaration
Class coordSystem::cartesian Declaration
\*---------------------------------------------------------------------------*/
class cartesianCS
class cartesian
:
public coordinateSystem
{
protected:
// Protected Member Functions
//- Convert from local coordinate system to the global Cartesian system
// with optional translation for the origin
virtual vector localToGlobal(const vector&, bool translate) const;
//- Convert from local coordinate system to the global Cartesian system
// with optional translation for the origin
virtual tmp<vectorField> localToGlobal
(
const vectorField&,
bool translate
) const;
//- Convert from global Cartesian system to the local coordinate system
// with optional translation for the origin
virtual vector globalToLocal(const vector&, bool translate) const;
//- Convert from global Cartesian system to the local coordinate system
// with optional translation for the origin
virtual tmp<vectorField> globalToLocal
(
const vectorField&,
bool translate
) const;
public:
//- Runtime type information
TypeName("cartesian");
TypeNameNoDebug("cartesian");
// Constructors
//- Construct null
cartesianCS();
//- Construct null. This is an identity coordinateSystem.
cartesian();
//- Construct copy
cartesianCS
(
const coordinateSystem&
);
//- Copy construct
cartesian(const cartesian& csys) = default;
//- Construct copy with a different name
cartesianCS
(
const word& name,
const coordinateSystem&
);
//- Move construct
cartesian(cartesian&& csys) = default;
//- Copy construct from another coordinateSystem type
explicit cartesian(const coordinateSystem& csys);
//- Move construct from another coordinateSystem type
explicit cartesian(coordinateSystem&& csys);
//- Move construct from autoPtr of another coordinateSystem type
explicit cartesian(autoPtr<coordinateSystem>&& csys);
//- Construct from origin and rotation
cartesianCS
cartesian(const point& origin, const coordinateRotation& crot);
//- Construct from origin and 2 axes
cartesian
(
const word& name,
const point& origin,
const coordinateRotation&
const vector& axis,
const vector& dirn
);
//- Construct from origin and 2 axes
cartesianCS
cartesian
(
const word& name,
const point& origin,
@ -122,24 +104,48 @@ public:
const vector& dirn
);
//- Construct from dictionary
cartesianCS(const word&, const dictionary&);
//- Construct from dictionary with a given name
cartesian(const word& name, const dictionary& dict);
//- Construct from dictionary without a name
explicit cartesian(const dictionary& dict);
//- Construct from dictionary and objectRegistry
cartesianCS(const objectRegistry&, const dictionary&);
//- Construct from dictionary with optional subDict lookup.
//
// \param dictName If non-empty, the sub-dictionary to use.
cartesian(const dictionary& dict, const word& dictName);
//- Destructor
virtual ~cartesianCS();
virtual ~cartesian() = default;
// Member Operators
//- Copy assignment
cartesian& operator=(const cartesian&) = default;
//- Move assignment
cartesian& operator=(cartesian&&) = default;
//- Copy/move assignment from coordinateSystem, autoPtr
using coordinateSystem::operator=;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace coordSystem
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Compatibility typedef 1806
typedef coordSystem::cartesian cartesianCS;
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View File

@ -23,10 +23,12 @@ License
\*---------------------------------------------------------------------------*/
#include "coordinateSystem.H"
#include "cartesianCS.H"
#include "IOstream.H"
#include "axesRotation.H"
#include "coordinateSystem.H"
#include "coordinateSystems.H"
#include "identityRotation.H"
#include "transform.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -35,47 +37,157 @@ namespace Foam
{
defineTypeNameAndDebug(coordinateSystem, 0);
defineRunTimeSelectionTable(coordinateSystem, dictionary);
defineRunTimeSelectionTable(coordinateSystem, registry);
}
Foam::coordinateSystem Foam::coordinateSystem::dummy_(nullptr);
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
//- Is it cartesian?
// For output, can treat the base class as Cartesian too,
// since it defaults to cartesian on input.
static inline bool isCartesian(const word& modelType)
{
return
(
modelType == coordinateSystem::typeName_()
|| modelType == coordSystem::cartesian::typeName_()
);
}
} // End namespace Foam
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::coordinateSystem::assign(const dictionary& dict)
{
dict.readEntry("origin", origin_);
note_.clear();
dict.readIfPresent("note", note_);
// Non-recursive, no pattern search for "rotation"
// or "coordinateRotation" (older) sub-dictionary.
// Don't warn about older naming for now (OCT-2018)
const auto finder = dict.csearchCompat
(
"rotation", {{"coordinateRotation", -1806}},
false, false
);
if (finder.isDict())
{
spec_ = coordinateRotation::New(finder.dict());
}
else
{
// Fall through to expecting e1/e2/e3 specification in the dictionary
spec_.reset(new coordinateRotations::axes(dict));
}
rot_ = spec_->R();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::coordinateSystem::coordinateSystem(std::nullptr_t)
:
spec_(),
origin_(Zero),
rot_(sphericalTensor::I),
name_(),
note_()
{}
Foam::coordinateSystem::coordinateSystem()
:
name_(),
note_(),
spec_(new coordinateRotations::identity()),
origin_(Zero),
R_(new axesRotation(sphericalTensor::I))
rot_(sphericalTensor::I),
name_(),
note_()
{}
Foam::coordinateSystem::coordinateSystem(const coordinateSystem& cs)
Foam::coordinateSystem::coordinateSystem(const coordinateRotation& crot)
:
name_(cs.name_),
note_(cs.note_),
origin_(cs.origin_),
R_(cs.R_.clone())
coordinateSystem(word::null, point::zero, crot)
{}
Foam::coordinateSystem::coordinateSystem(coordinateSystem&& cs)
Foam::coordinateSystem::coordinateSystem(coordinateRotation&& crot)
:
name_(std::move(cs.name_)),
note_(std::move(cs.note_)),
origin_(std::move(cs.origin_)),
R_(std::move(cs.R_))
coordinateSystem(word::null, point::zero, std::move(crot))
{}
Foam::coordinateSystem::coordinateSystem(const coordinateSystem& csys)
:
spec_(csys.spec_.clone()),
origin_(csys.origin_),
rot_(csys.rot_),
name_(csys.name_),
note_(csys.note_)
{}
Foam::coordinateSystem::coordinateSystem(coordinateSystem&& csys)
:
spec_(std::move(csys.spec_)),
origin_(std::move(csys.origin_)),
rot_(std::move(csys.rot_)),
name_(std::move(csys.name_)),
note_(std::move(csys.note_))
{}
Foam::coordinateSystem::coordinateSystem(autoPtr<coordinateSystem>&& csys)
:
coordinateSystem(nullptr)
{
if (csys)
{
// Has valid autoPtr - move.
coordinateSystem::operator=(std::move(*csys));
csys.clear();
}
else
{
// No valid autoPtr - treat like identity
spec_.reset(new coordinateRotations::identity());
}
}
Foam::coordinateSystem::coordinateSystem
(
const word& name,
const coordinateSystem& cs
const coordinateSystem& csys
)
:
spec_(csys.spec_.clone()),
origin_(csys.origin_),
rot_(csys.rot_),
name_(name),
note_(cs.note_),
origin_(cs.origin_),
R_(cs.R_.clone())
note_(csys.note_)
{}
Foam::coordinateSystem::coordinateSystem
(
const point& origin,
const coordinateRotation& crot
)
:
coordinateSystem(word::null, origin, crot)
{}
@ -83,13 +195,25 @@ Foam::coordinateSystem::coordinateSystem
(
const word& name,
const point& origin,
const coordinateRotation& cr
const coordinateRotation& crot
)
:
name_(name),
note_(),
spec_(crot.clone()),
origin_(origin),
R_(cr.clone())
rot_(spec_->R()),
name_(name),
note_()
{}
Foam::coordinateSystem::coordinateSystem
(
const point& origin,
const vector& axis,
const vector& dirn
)
:
coordinateSystem(word::null, origin, axis, dirn)
{}
@ -101,10 +225,11 @@ Foam::coordinateSystem::coordinateSystem
const vector& dirn
)
:
name_(name),
note_(),
spec_(new coordinateRotations::axes(axis, dirn)),
origin_(origin),
R_(new axesRotation(axis, dirn))
rot_(spec_->R()),
name_(name),
note_()
{}
@ -114,119 +239,91 @@ Foam::coordinateSystem::coordinateSystem
const dictionary& dict
)
:
name_(name),
note_(),
spec_(nullptr),
origin_(Zero),
R_()
rot_(sphericalTensor::I),
name_(name),
note_()
{
init(dict);
assign(dict);
}
Foam::coordinateSystem::coordinateSystem(const dictionary& dict)
:
name_(),
note_(),
origin_(Zero),
R_()
{
init(dict);
}
coordinateSystem(word::null, dict)
{}
Foam::coordinateSystem::coordinateSystem
(
const objectRegistry& obr,
const dictionary& dict
const dictionary& dict,
const word& dictName
)
:
name_(),
note_(),
origin_(Zero),
R_()
coordinateSystem(nullptr)
{
const entry* entryPtr = dict.lookupEntryPtr(typeName_(), false, false);
if (!entryPtr)
if (dictName.size())
{
// No 'coordinateSystem' entry
init(dict, obr);
}
else if (entryPtr->isDict())
{
// 'coordinateSystem' as dictionary entry - use it
init(entryPtr->dict(), obr);
assign(dict.subDict(dictName));
}
else
{
// 'coordinateSystem' as non-dictionary entry
// - this is a lookup into global coordinateSystems
keyType key(entryPtr->stream());
const coordinateSystems& lst = coordinateSystems::New(obr);
const label index = lst.findIndex(key);
if (debug)
{
InfoInFunction
<< "Using global coordinate system: "
<< key << "=" << index << endl;
}
if (index < 0)
{
FatalErrorInFunction
<< "could not find coordinate system: " << key << nl
<< "available coordinate systems: " << lst.toc() << nl << nl
<< exit(FatalError);
}
// Copy from coordinateSystem, but assign the name as the typeName
// to avoid strange things in writeDict()
operator=(lst[index]);
name_ = typeName_();
assign(dict);
}
}
Foam::coordinateSystem::coordinateSystem(Istream& is)
:
name_(is),
note_(),
origin_(Zero),
R_()
{
dictionary dict(is);
init(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::dictionary Foam::coordinateSystem::dict(bool ignoreType) const
void Foam::coordinateSystem::clear()
{
dictionary dict;
spec_->clear();
origin_ = Zero;
rot_ = sphericalTensor::I;
note_.clear();
}
dict.add("name", name_);
// Only write type for derived types
if (!ignoreType && type() != typeName_())
{
dict.add("type", type());
}
Foam::tensor Foam::coordinateSystem::R(const point& global) const
{
return rot_;
}
// The note entry is optional
if (note_.size())
{
dict.add("note", note_);
}
dict.add("origin", origin_);
dict.add("e1", R_->e1());
dict.add("e3", R_->e3());
Foam::tmp<Foam::tensorField> Foam::coordinateSystem::R
(
const UList<point>& global
) const
{
return rotationsImpl(global);
}
return dict;
Foam::tmp<Foam::tensorField> Foam::coordinateSystem::R
(
const pointUIndList& global
) const
{
return rotationsImpl(global);
}
Foam::point Foam::coordinateSystem::transformPoint
(
const point& localCart
) const
{
return Foam::transform(rot_, localCart) + origin_;
}
Foam::point Foam::coordinateSystem::invTransformPoint
(
const point& global
) const
{
return Foam::invTransform(rot_, global - origin_);
}
@ -238,10 +335,10 @@ Foam::vector Foam::coordinateSystem::localToGlobal
{
if (translate)
{
return (R_->transform(local)) + origin_;
return this->transform(local) + origin_;
}
return R_->transform(local);
return this->transform(local);
}
@ -253,10 +350,10 @@ Foam::tmp<Foam::vectorField> Foam::coordinateSystem::localToGlobal
{
if (translate)
{
return (R_->transform(local)) + origin_;
return this->transform(local) + origin_;
}
return R_->transform(local);
return this->transform(local);
}
@ -268,10 +365,10 @@ Foam::vector Foam::coordinateSystem::globalToLocal
{
if (translate)
{
return R_->invTransform(global - origin_);
return this->invTransform(global - origin_);
}
return R_->invTransform(global);
return this->invTransform(global);
}
@ -283,54 +380,74 @@ Foam::tmp<Foam::vectorField> Foam::coordinateSystem::globalToLocal
{
if (translate)
{
return R_->invTransform(global - origin_);
return this->invTransform(global - origin_);
}
return R_->invTransform(global);
return this->invTransform(global);
}
void Foam::coordinateSystem::clear()
void Foam::coordinateSystem::rotation(autoPtr<coordinateRotation>&& crot)
{
note_.clear();
origin_ = Zero;
R_->clear();
}
void Foam::coordinateSystem::transfer(coordinateSystem& cs)
{
name_ = std::move(cs.name_);
note_ = std::move(cs.note_);
origin_ = std::move(cs.origin_);
R_ = std::move(cs.R_);
spec_.reset(std::move(crot));
if (spec_)
{
rot_ = spec_->R();
}
else
{
rot_ = sphericalTensor::I;
}
}
void Foam::coordinateSystem::write(Ostream& os) const
{
os << type() << " origin: " << origin() << nl;
R_->write(os);
if (!valid())
{
return;
}
// Suppress output of type for Cartesian
if (!isCartesian(type()))
{
os << type() << ' ';
}
os << "origin: " << origin_ << ' ';
spec_->write(os);
}
void Foam::coordinateSystem::writeDict(Ostream& os, bool subDict) const
void Foam::coordinateSystem::writeEntry(const word& keyword, Ostream& os) const
{
if (subDict)
if (!valid())
{
os.beginBlock(name_);
return;
}
os.writeEntry("type", type());
const bool subDict = !keyword.empty();
if (note_.size())
if (subDict)
{
// The 'note' is optional
os.writeEntry("note", note_);
os.beginBlock(keyword);
// Suppress output of type for Cartesian
if (!isCartesian(type()))
{
os.writeEntry<word>("type", type());
}
if (note_.size())
{
// The 'note' is optional
os.writeEntry("note", note_);
}
}
os.writeEntry("origin", origin_);
R_->write(os);
spec_->writeEntry("rotation", os);
if (subDict)
{
@ -341,71 +458,64 @@ void Foam::coordinateSystem::writeDict(Ostream& os, bool subDict) const
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::coordinateSystem::operator=(const coordinateSystem& cs)
void Foam::coordinateSystem::operator=(const coordinateSystem& csys)
{
name_ = cs.name_;
note_ = cs.note_;
origin_ = cs.origin_;
name_ = csys.name_;
note_ = csys.note_;
origin_ = csys.origin_;
// Some extra safety
if (cs.R_.valid())
if (csys.spec_)
{
R_ = cs.R_.clone();
rotation(csys.spec_.clone());
}
else
{
R_.reset(new axesRotation(sphericalTensor::I));
spec_.reset(new coordinateRotations::identity());
rot_ = sphericalTensor::I;
}
}
void Foam::coordinateSystem::operator=(coordinateSystem&& cs)
void Foam::coordinateSystem::operator=(coordinateSystem&& csys)
{
transfer(cs);
name_ = std::move(csys.name_);
note_ = std::move(csys.note_);
spec_ = std::move(csys.spec_);
origin_ = csys.origin_;
rot_ = csys.rot_;
}
void Foam::coordinateSystem::init(const dictionary& dict)
void Foam::coordinateSystem::operator=(const autoPtr<coordinateSystem>& csys)
{
dict.readEntry("origin", origin_);
note_.clear();
dict.readIfPresent("note", note_);
R_ = coordinateRotation::New(dict.subDict("coordinateRotation"));
coordinateSystem::operator=(*csys);
}
void Foam::coordinateSystem::init
(
const dictionary& dict,
const objectRegistry& obr
)
void Foam::coordinateSystem::operator=(autoPtr<coordinateSystem>&& csys)
{
dict.readEntry("origin", origin_);
// The 'note' entry is optional
note_.clear();
dict.readIfPresent("note", note_);
R_ = coordinateRotation::New(dict.subDict("coordinateRotation"), obr);
coordinateSystem::operator=(std::move(*csys));
csys.clear();
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
bool Foam::operator!=(const coordinateSystem& a, const coordinateSystem& b)
{
return
(
a.origin() != b.origin()
|| a.type() != b.type()
|| a.R().R() != b.R().R()
a.type() != b.type()
|| a.origin() != b.origin()
|| a.R() != b.R()
);
}
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const coordinateSystem& cs)
Foam::Ostream& Foam::operator<<(Ostream& os, const coordinateSystem& csys)
{
cs.write(os);
csys.write(os);
os.check(FUNCTION_NAME);
return os;
}

View File

@ -21,40 +21,66 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Namespace
Foam::coordSystem
Description
Namespace for coordinate systems.
Class
Foam::coordinateSystem
Description
Base class for other coordinate system specifications.
Base class for coordinate system specification,
the default coordinate system type is
\link coordSystem::cartesian cartesian \endlink.
All systems are defined by an origin point and a co-ordinate rotation.
All systems are defined by an origin point and a coordinate rotation
By default, the \link coordinateRotations::axes axes \endlink
specification can be used directly as part of the
coordinate system specification. For example,
\verbatim
coordinateSystem
{
origin (0 0 0);
e1 (0 1 0);
e3 (1 0 0);
}
\endverbatim
The same, but in more verbose format:
\verbatim
coordinateSystem
{
type cartesian;
origin (0 0 0);
coordinateRotation
rotation
{
type cylindrical;
e3 (0 0 1);
type axes;
e1 (0 1 0);
e3 (1 0 0);
}
}
\endverbatim
Types of coordinateRotation:
-# axesRotation
-# \link STARCDCoordinateRotation STARCDRotation \endlink
-# cylindricalCS cylindrical
-# EulerCoordinateRotation
Type of co-ordinates:
-# \link cartesianCS cartesian \endlink
-# \link coordinateRotations::identity none \endlink
-# \link coordinateRotations::axes axes \endlink
-# \link coordinateRotations::axisAngle axisAngle \endlink
-# \link coordinateRotations::euler euler \endlink
-# \link coordinateRotations::starcd starcd \endlink
Type of coordinateSystem:
-# \link coordSystem::cartesian cartesian \endlink
-# \link coordSystem::cylindrical cylindrical \endlink
-# \link coordSystem::indirect indirect \endlink (references
an entry in coordinateSystems).
SourceFiles
coordinateSystem.C
coordinateSystemNew.C
coordinateSystemTransform.C
\*---------------------------------------------------------------------------*/
@ -66,79 +92,151 @@ SourceFiles
#include "tensor.H"
#include "vectorField.H"
#include "pointField.H"
#include "tmp.H"
#include "tensorField.H"
#include "pointIndList.H"
#include "coordinateRotation.H"
#include "objectRegistry.H"
#include "autoPtr.H"
#include "tmp.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
// Forward Declarations
class coordinateSystem;
class objectRegistry;
bool operator!=(const coordinateSystem&, const coordinateSystem&);
Ostream& operator<<(Ostream&, const coordinateSystem&);
namespace coordSystem
{
class indirect;
}
/*---------------------------------------------------------------------------*\
Class coordinateSystem Declaration
Class coordinateSystem Declaration
\*---------------------------------------------------------------------------*/
class coordinateSystem
{
// Private data
// Private Member Functions
//- Name of coordinate system
word name_;
//- Optional note
string note_;
//- Origin
point origin_;
//- Local-to-Global transformation tensor.
// May be invalid after a move assignment or transfer
autoPtr<coordinateRotation> R_;
//- Use 'coordinateSystem' sub-dictionary if present
static const dictionary* subDictCompat(const dictionary* dictPtr);
protected:
//- Friendship with indirect for dispatching to its underlying system
friend coordSystem::indirect;
// Protected Data
//- User specification of the coordinate rotation
// May be invalid after a move assignment or transfer
autoPtr<coordinateRotation> spec_;
//- The coordinate system origin
point origin_;
//- The rotation tensor
tensor rot_;
//- The name of the coordinate system (optional)
word name_;
//- An optional note describing the coordinate system
string note_;
//- Dummy coordinate system for suppressed manipulation
static coordinateSystem dummy_;
// Protected Member Functions
//- Convert from local coordinate system to the global Cartesian system
//- with optional translation for the origin
virtual vector localToGlobal(const vector&, bool translate) const;
//- Implementation for R() methods
template<class PointField>
tmp<tensorField> rotationsImpl(const PointField& global) const;
//- Convert from local coordinate system to the global Cartesian system
//- Implementation for transformPoint() methods
template<class PointField>
tmp<pointField> transformPointImpl(const PointField& localCart) const;
//- Implementation for transformPosition() methods
template<class PointField>
tmp<pointField> invTransformPointImpl(const PointField& global) const;
//- Apply single transform tensor for multiple inputs
template<class RetType, class Type, class BinaryOp>
static tmp<Field<RetType>> manyTimesImpl
(
const tensor& tt,
const UList<Type>& input,
const BinaryOp& bop
);
//- Use position-dependent transform tensors for multiple inputs
template<class RetType, class PointField, class Type, class BinaryOp>
tmp<Field<RetType>> oneToOneImpl
(
const PointField& global,
const UList<Type>& input,
const BinaryOp& bop
) const;
//- Use position-dependent transform tensors for single input
template<class RetType, class PointField, class Type, class BinaryOp>
tmp<Field<RetType>> oneToManyImpl
(
const PointField& global,
const Type& input,
const BinaryOp& bop
) const;
//- From local coordinate system to the global Cartesian system
//- with optional translation for the origin
virtual vector localToGlobal
(
const vector& local,
bool translate
) const;
//- From local coordinate system to the global Cartesian system
//- with optional translation for the origin
virtual tmp<vectorField> localToGlobal
(
const vectorField&,
const vectorField& local,
bool translate
) const;
//- Convert from global Cartesian system to the local coordinate system
//- From global Cartesian system to the local coordinate system
//- with optional translation for the origin
virtual vector globalToLocal(const vector&, bool translate) const;
virtual vector globalToLocal
(
const vector& global,
bool translate
) const;
//- Convert from global Cartesian system to the local coordinate system
//- From global Cartesian system to the local coordinate system
//- with optional translation for the origin
virtual tmp<vectorField> globalToLocal
(
const vectorField&,
const vectorField& global,
bool translate
) const;
//- Init from dict and obr
void init(const dictionary& dict);
//- Init from dictionary
void init(const dictionary& dict, const objectRegistry& obr);
//- Assign from dictionary content
void assign(const dictionary& dict);
// Constructors
//- Construct null, without allocating a coordinateRotation
//- specification.
coordinateSystem(std::nullptr_t);
public:
@ -146,23 +244,57 @@ public:
//- Runtime type information
TypeName("coordinateSystem");
//- Helper for construction of coordinateSystem PtrList
// The Istream contains a word followed by a dictionary
struct iNew
{
autoPtr<coordinateSystem> operator()(Istream& is) const
{
return coordinateSystem::New(is);
}
};
// Constructors
//- Construct null. This is equivalent to an identity coordinateSystem
//- Construct null. This is an identity coordinateSystem.
coordinateSystem();
//- Copy construct from rotation with origin=0
explicit coordinateSystem(const coordinateRotation& crot);
//- Move construct from rotation with origin=0
explicit coordinateSystem(coordinateRotation&& crot);
//- Copy construct
coordinateSystem(const coordinateSystem& cs);
coordinateSystem(const coordinateSystem& csys);
//- Move construct
coordinateSystem(coordinateSystem&& cs);
coordinateSystem(coordinateSystem&& csys);
//- Move construct from autoPtr
explicit coordinateSystem(autoPtr<coordinateSystem>&& csys);
//- Copy construct with a different name
coordinateSystem
(
const word& name,
const coordinateSystem& cs
const coordinateSystem& csys
);
//- Construct from origin and rotation
coordinateSystem
(
const point& origin,
const coordinateRotation& crot
);
//- Construct from origin and 2 axes
coordinateSystem
(
const point& origin,
const vector& axis,
const vector& dirn
);
//- Construct from origin and rotation
@ -170,7 +302,7 @@ public:
(
const word& name,
const point& origin,
const coordinateRotation&
const coordinateRotation& crot
);
//- Construct from origin and 2 axes
@ -185,16 +317,13 @@ public:
//- Construct from dictionary with a given name
coordinateSystem(const word& name, const dictionary& dict);
//- Construct from dictionary with default name
//- Construct from dictionary without a name
explicit coordinateSystem(const dictionary& dict);
//- Construct from dictionary (default name)
// With the ability to reference global coordinateSystems
coordinateSystem(const objectRegistry& obr, const dictionary& dict);
//- Construct from Istream
// The Istream contains a word followed by a dictionary
coordinateSystem(Istream& is);
//- Construct from dictionary with optional subDict lookup.
//
// \param dictName If non-empty, the sub-dictionary to use.
coordinateSystem(const dictionary& dict, const word& dictName);
//- Return clone
@ -210,6 +339,18 @@ public:
autoPtr,
coordinateSystem,
dictionary,
(
const dictionary& dict
),
(dict)
);
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
coordinateSystem,
registry,
(
const objectRegistry& obr,
const dictionary& dict
@ -220,20 +361,57 @@ public:
// Selectors
//- Select constructed from dictionary and objectRegistry
//- Select construct the specified coordinate system type
//- with reference to objectRegistry for indirect entries.
//
// An empty modelType will be treated as "cartesian"
static autoPtr<coordinateSystem> New
(
word modelType,
const objectRegistry& obr,
const dictionary& dict
);
//- Select constructed from dictionary
//- Select construct the specified coordinate system type
//
// An empty modelType will be treated as "cartesian"
static autoPtr<coordinateSystem> New
(
word modelType,
const dictionary& dict
);
//- Select construct from dictionary with reference to objectRegistry
//- for indirect entries.
//
// \param dictName If non-empty, the sub-dictionary name to use
// for the coordinate system description.
//
// \note When the dictName is empty, it includes an implicit search
// for a "coordinateSystem" sub-dictionary for convenience and
// compatibility with previous versions (1806 and earlier).
static autoPtr<coordinateSystem> New
(
const objectRegistry& obr,
const dictionary& dict,
const word& dictName = ""
);
//- Select constructed from dictionary
// \param dictName If non-empty, the sub-dictionary name to use
// for the coordinate system description.
//
// \note When the dictName is empty, it includes an implicit search
// for a "coordinateSystem" sub-dictionary for convenience and
// compatibility with previous versions (1806 and earlier).
static autoPtr<coordinateSystem> New
(
const dictionary& dict,
const word& dictName = ""
);
//- Select constructed from Istream
// Expects a name/dictionary as input
static autoPtr<coordinateSystem> New(Istream& is);
@ -243,183 +421,308 @@ public:
// Member Functions
// Access
// Access
//- Return name
const word& name() const
{
return name_;
}
//- Considered valid if it has a specification
virtual bool valid() const
{
return spec_.valid();
}
//- Return non-constant access to the optional note
string& note()
{
return note_;
}
//- True if the rotation tensor is uniform for all locations
virtual bool uniform() const
{
return true;
}
//- Return the optional note
const string& note() const
{
return note_;
}
//- The rotation specification
virtual const coordinateRotation& rotation() const
{
return *spec_;
}
//- Return origin
const point& origin() const
{
return origin_;
}
//- Return the name
virtual const word& name() const
{
return name_;
}
//- Return const reference to co-ordinate rotation
const coordinateRotation& R() const
{
return *R_;
}
//- Return the optional note
virtual const string& note() const
{
return note_;
}
//- Return non const reference to co-ordinate rotation
coordinateRotation& R()
{
return *R_;
}
//- Return origin
virtual const point& origin() const
{
return origin_;
}
//- Update and return the co-ordinate rotation for a list of cells
const coordinateRotation& R
(
const polyMesh& mesh,
const labelList& cells
)
{
R_->updateCells(mesh, cells);
return *R_;
}
//- Return const reference to the rotation tensor
virtual const tensor& R() const
{
return rot_;
}
//- Return as dictionary of entries
// \param[in] ignoreType drop type (cartesian, cylindrical, etc)
// when generating the dictionary
virtual dictionary dict(bool ignoreType=false) const;
//- The local Cartesian x-axis in global coordinates
virtual const vector e1() const
{
return rot_.cx();
}
//- The local Cartesian y-axis in global coordinates
virtual const vector e2() const
{
return rot_.cy();
}
//- The local Cartesian z-axis in global coordinates
virtual const vector e3() const
{
return rot_.cz();
}
// Edit
// Edit
//- Rename
void rename(const word& newName)
{
name_ = newName;
}
//- Rename
virtual void rename(const word& newName)
{
name_ = newName;
}
//- Edit access to origin
point& origin()
{
return origin_;
}
//- Provide non-constant access to the optional note
virtual string& note()
{
return note_;
}
//- Reset origin and rotation to an identity coordinateSystem
// Also resets the note
virtual void clear();
//- Edit access to origin
virtual point& origin()
{
return origin_;
}
//- Transfer contents from parameter
void transfer(coordinateSystem& cs);
//- Reset origin and rotation to an identity coordinateSystem
// Also resets the note
virtual void clear();
//- Change the rotation
virtual void rotation(autoPtr<coordinateRotation>&& crot);
// Write
// Write
//- Write
virtual void write(Ostream& os) const;
//- Write
virtual void write(Ostream& os) const;
//- Write dictionary
void writeDict(Ostream& os, bool subDict=true) const;
// Transformations
//- Convert from position in local coordinate system to global
// Cartesian position
point globalPosition(const point& local) const
{
return localToGlobal(local, true);
}
//- Convert from position in local coordinate system to global
// Cartesian position
tmp<pointField> globalPosition(const pointField& local) const
{
return localToGlobal(local, true);
}
//- Convert from vector components in local coordinate system to
// global Cartesian vector
vector globalVector(const vector& local) const
{
return localToGlobal(local, false);
}
//- Convert from vector components in local coordinate system to
// global Cartesian vector
tmp<vectorField> globalVector(const vectorField& local) const
{
return localToGlobal(local, false);
}
//- Convert from global Cartesian position to position in local
// coordinate system
point localPosition(const point& global) const
{
return globalToLocal(global, true);
}
//- Convert from global Cartesian position to position in local
// coordinate system
tmp<pointField> localPosition(const pointField& global) const
{
return globalToLocal(global, true);
}
//- Convert from global Cartesian vector to components in local
// coordinate system
vector localVector(const vector& global) const
{
return globalToLocal(global, false);
}
//- Convert from global Cartesian vector to components in local
// coordinate system
tmp<vectorField> localVector(const vectorField& global) const
{
return globalToLocal(global, false);
}
//- Write dictionary entry
virtual void writeEntry(const word& keyword, Ostream& os) const;
// Member Operators
//- Copy assignment
void operator=(const coordinateSystem& cs);
void operator=(const coordinateSystem& csys);
//- Move assignment
void operator=(coordinateSystem&& cs);
void operator=(coordinateSystem&& csys);
//- Copy assignment from autoPtr
void operator=(const autoPtr<coordinateSystem>& csys);
//- Move assignment from autoPtr
void operator=(autoPtr<coordinateSystem>&& csys);
// Friend Operators
// Rotation
friend bool operator!=
(
const coordinateSystem& a,
const coordinateSystem& b
);
//- Position-dependent rotation tensor (when uniform = false)
//- \return tensor
virtual tensor R(const point& global) const;
//- Position-dependent rotation tensors (when uniform = false)
//- \return tensorField
virtual tmp<tensorField> R(const UList<point>& global) const;
//- Position-dependent rotation tensors (when uniform = false)
//- \return tensorField
virtual tmp<tensorField> R(const pointUIndList& global) const;
// IOstream Operators
// Position
friend Ostream& operator<<
(
Ostream& os,
const coordinateSystem& cs
);
//- Transform point and add origin offset.
// Corresponds to a local-to-global transformation using Cartesian
// coordinates for both local and global.
point transformPoint(const point& localCart) const;
//- Transform points and add origin offset.
tmp<pointField> transformPoint(const UList<point>& localCart) const;
//- Transform points and add origin offset.
tmp<pointField> transformPoint(const pointUIndList& localCart) const;
//- Remove origin offset and inverse transform point.
// Corresponds to a global-to-local transformation using Cartesian
// coordinates for both local and global.
point invTransformPoint(const point& global) const;
//- Remove origin offset and inverse transform points.
tmp<pointField> invTransformPoint(const UList<point>& global) const;
//- Remove origin offset and inverse transform points.
tmp<pointField> invTransformPoint(const pointUIndList& global) const;
// Transformations with change of coordinate types
//- From local coordinate position to global (cartesian) position
point globalPosition(const point& local) const
{
return localToGlobal(local, true);
}
//- From local coordinate position to global (cartesian) position
tmp<pointField> globalPosition(const pointField& local) const
{
return localToGlobal(local, true);
}
//- From global (cartesian) position to local coordinate position
point localPosition(const point& global) const
{
return globalToLocal(global, true);
}
//- From global (cartesian) position to local coordinate position
tmp<pointField> localPosition(const pointField& global) const
{
return globalToLocal(global, true);
}
//- From local to global (cartesian) vector components
vector globalVector(const vector& local) const
{
return localToGlobal(local, false);
}
//- From local to global (cartesian) vector components
tmp<vectorField> globalVector(const vectorField& local) const
{
return localToGlobal(local, false);
}
//- From global (cartesian) to local vector components
vector localVector(const vector& global) const
{
return globalToLocal(global, false);
}
//- From global (cartesian) to local vector components
tmp<vectorField> localVector(const vectorField& global) const
{
return globalToLocal(global, false);
}
// Transformations (input and output are Cartesian)
#undef defineCoordinateSystemTransform
#define defineCoordinateSystemTransform(Op, RetType, Type) \
\
/**! With constant rotation tensor */ \
virtual RetType Op(const Type& input) const; \
\
/**! With constant rotation tensor */ \
virtual tmp<Field<RetType>> Op(const UList<Type>& input) const; \
\
/**! With rotation tensor at given global position */ \
virtual RetType Op(const point& global, const Type& input) const; \
\
/**! With rotation tensors at given global positions */ \
virtual tmp<Field<RetType>> Op \
( \
const UList<point>& global, \
const Type& input \
) const; \
\
/**! With rotation tensors at given global positions */ \
virtual tmp<Field<RetType>> Op \
( \
const pointUIndList& global, \
const Type& input \
) const; \
\
/**! With rotation tensors at given global positions */ \
virtual tmp<Field<RetType>> Op \
( \
const UList<point>& global, \
const UList<Type>& input \
) const; \
\
/**! With rotation tensors at given global positions */ \
virtual tmp<Field<RetType>> Op \
( \
const pointUIndList& global, \
const UList<Type>& input \
) const;
defineCoordinateSystemTransform(transformPrincipal, symmTensor, vector);
defineCoordinateSystemTransform(transform, scalar, scalar);
defineCoordinateSystemTransform(transform, vector, vector);
defineCoordinateSystemTransform
(
transform,
sphericalTensor,
sphericalTensor
);
defineCoordinateSystemTransform(transform, symmTensor, symmTensor);
defineCoordinateSystemTransform(transform, tensor, tensor);
defineCoordinateSystemTransform(invTransform, scalar, scalar);
defineCoordinateSystemTransform(invTransform, vector, vector);
defineCoordinateSystemTransform
(
invTransform,
sphericalTensor,
sphericalTensor
);
defineCoordinateSystemTransform(invTransform, symmTensor, symmTensor);
defineCoordinateSystemTransform(invTransform, tensor, tensor);
#undef defineCoordinateSystemTransform
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Global Operators
//- Compare inequality
bool operator!=(const coordinateSystem& a, const coordinateSystem& b);
//- Output operator
Ostream& operator<<(Ostream& os, const coordinateSystem& csys);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "coordinateSystemTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -23,58 +23,188 @@ License
\*---------------------------------------------------------------------------*/
#include "coordinateSystem.H"
#include "dictionary.H"
#include "objectRegistry.H"
#include "cartesianCS.H"
#include "indirectCS.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
//- Handle a 'coordinateSystem' sub-dictionary
// In 1806 and earlier, this was handled (rather poorly) in the
// coordinateSystem constructor itself.
const Foam::dictionary* Foam::coordinateSystem::subDictCompat
(
const dictionary* dictPtr
)
{
if (dictPtr)
{
// Non-recursive, no pattern matching in the search
const auto finder =
dictPtr->csearch(coordinateSystem::typeName_(), false, false);
if (finder.isDict())
{
return finder.dictPtr();
}
else if (finder.found())
{
const word csName(finder.ref().stream());
// Deprecated, unsupported syntax
std::cerr
<< "--> FOAM IOWarning :" << nl
<< " Ignoring 'coordinateSystem' as a keyword."
" Perhaps you meant this instead?" << nl
<< '{' << nl
<< " type " << coordSystem::indirect::typeName_()
<< ';' << nl
<< " name " << csName << ';' << nl
<< '}' << nl
<< std::endl;
error::warnAboutAge("syntax change", 1806);
}
}
return dictPtr;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::coordinateSystem> Foam::coordinateSystem::New
(
word modelType,
const objectRegistry& obr,
const dictionary& dict
)
{
const dictionary& coordDict = dict.subDict(typeName_());
const word modelType(coordDict.get<word>("type"));
if (modelType.empty())
{
modelType = coordSystem::cartesian::typeName_();
}
auto cstrIter1 = registryConstructorTablePtr_->cfind(modelType);
if (cstrIter1.found())
{
return autoPtr<coordinateSystem>(cstrIter1()(obr, dict));
}
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
// Everything with a registry constructor also has a dictionary
// constructor, so just need to print those.
if (!cstrIter.found())
{
FatalIOErrorInFunction
(
dict
) << "Unknown coordinateSystem type "
FatalIOErrorInFunction(dict)
<< "Unknown coordinate system type "
<< modelType << nl << nl
<< "Valid types: "
<< flatOutput(dictionaryConstructorTablePtr_->sortedToc())
<< exit(FatalIOError);
}
return autoPtr<coordinateSystem>(cstrIter()(obr, coordDict));
return autoPtr<coordinateSystem>(cstrIter()(dict));
}
Foam::autoPtr<Foam::coordinateSystem> Foam::coordinateSystem::New
(
word modelType,
const dictionary& dict
)
{
const dictionary& coordDict = dict.subDict(typeName_());
if (modelType.empty())
{
modelType = coordSystem::cartesian::typeName_();
}
return autoPtr<coordinateSystem>::New(coordDict);
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
if (!cstrIter.found())
{
FatalIOErrorInFunction(dict)
<< "Unknown coordinate system type "
<< modelType << nl << nl
<< "Valid types: "
<< flatOutput(dictionaryConstructorTablePtr_->sortedToc())
<< exit(FatalIOError);
}
return autoPtr<coordinateSystem>(cstrIter()(dict));
}
Foam::autoPtr<Foam::coordinateSystem> Foam::coordinateSystem::New
(
Istream& is
const objectRegistry& obr,
const dictionary& dict,
const word& dictName
)
{
const word name(is);
const dictionary* dictPtr = &dict;
if (dictName.size())
{
dictPtr = &(dictPtr->subDict(dictName));
}
else
{
// Use 'coordinateSystem' subDict if present
dictPtr = coordinateSystem::subDictCompat(dictPtr);
}
word modelType = dictPtr->lookupOrDefault<word>
(
"type",
coordSystem::cartesian::typeName_()
);
return coordinateSystem::New(modelType, obr, *dictPtr);
}
Foam::autoPtr<Foam::coordinateSystem> Foam::coordinateSystem::New
(
const dictionary& dict,
const word& dictName
)
{
const dictionary* dictPtr = &dict;
if (dictName.size())
{
dictPtr = &(dictPtr->subDict(dictName));
}
else
{
// Use 'coordinateSystem' subDict if present
dictPtr = coordinateSystem::subDictCompat(dictPtr);
}
word modelType = dictPtr->lookupOrDefault<word>
(
"type",
coordSystem::cartesian::typeName_()
);
return coordinateSystem::New(modelType, *dictPtr);
}
Foam::autoPtr<Foam::coordinateSystem> Foam::coordinateSystem::New(Istream& is)
{
const word csName(is);
const dictionary dict(is);
return autoPtr<coordinateSystem>::New(name, dict);
auto cs = coordinateSystem::New(dict, word::null);
cs->rename(csName);
return cs;
}

View File

@ -0,0 +1,161 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "coordinateSystem.H"
#include "transform.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class PointField>
Foam::tmp<Foam::tensorField>
Foam::coordinateSystem::rotationsImpl(const PointField& global) const
{
const label len = global.size();
auto tresult = tmp<tensorField>::New(len);
auto& result = tresult.ref();
for (label i=0; i<len; ++i)
{
result[i] = this->R(global[i]);
}
return tresult;
}
template<class PointField>
Foam::tmp<Foam::pointField>
Foam::coordinateSystem::transformPointImpl(const PointField& localCart) const
{
const label len = localCart.size();
auto tresult = tmp<pointField>::New(len);
auto& result = tresult.ref();
for (label i=0; i<len; ++i)
{
result[i] = Foam::transform(rot_, localCart[i]) + origin_;
}
return tresult;
}
template<class PointField>
Foam::tmp<Foam::pointField>
Foam::coordinateSystem::invTransformPointImpl(const PointField& global) const
{
const label len = global.size();
auto tresult = tmp<pointField>::New(len);
auto& result = tresult.ref();
for (label i=0; i<len; ++i)
{
result[i] = Foam::invTransform(rot_, global[i] - origin_);
}
return tresult;
}
template<class RetType, class Type, class BinaryOp>
Foam::tmp<Foam::Field<RetType>>
Foam::coordinateSystem::manyTimesImpl
(
const tensor& tt,
const UList<Type>& input,
const BinaryOp& bop
)
{
const label len = input.size();
auto tresult = tmp<Field<RetType>>::New(len);
auto& result = tresult.ref();
for (label i=0; i<len; ++i)
{
result[i] = bop(tt, input[i]);
}
return tresult;
}
template<class RetType, class PointField, class Type, class BinaryOp>
Foam::tmp<Foam::Field<RetType>>
Foam::coordinateSystem::oneToOneImpl
(
const PointField& global,
const UList<Type>& input,
const BinaryOp& bop
) const
{
const label len = input.size();
if (len != global.size())
{
FatalErrorInFunction
<< "positions has different size from input field"
<< abort(FatalError);
}
auto tresult = tmp<Field<RetType>>::New(len);
auto& result = tresult.ref();
for (label i=0; i<len; ++i)
{
result[i] = bop(this->R(global[i]), input[i]);
}
return tresult;
}
template<class RetType, class PointField, class Type, class BinaryOp>
Foam::tmp<Foam::Field<RetType>>
Foam::coordinateSystem::oneToManyImpl
(
const PointField& global,
const Type& input,
const BinaryOp& bop
) const
{
const label len = global.size();
auto tresult = tmp<Field<RetType>>::New(len);
auto& result = tresult.ref();
for (label i=0; i<len; ++i)
{
result[i] = bop(this->R(global[i]), input);
}
return tresult;
}
// ************************************************************************* //

View File

@ -0,0 +1,217 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "coordinateSystem.H"
#include "transform.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Resolve templated global functions via local non-templated function.
// Lambda functions in the caller is a much messier solution.
#undef makeTransform
#define makeTransform(Op, Type) \
static inline Type Op##_##Type(const tensor& tt, const Type& in) \
{ \
return Op(tt, in); \
}
makeTransform(transform, scalar);
makeTransform(transform, vector);
makeTransform(transform, sphericalTensor);
makeTransform(transform, symmTensor);
makeTransform(transform, tensor);
makeTransform(invTransform, scalar);
makeTransform(invTransform, vector);
makeTransform(invTransform, sphericalTensor);
makeTransform(invTransform, symmTensor);
makeTransform(invTransform, tensor);
#undef makeTransform
//- Transform principal.
static inline symmTensor transformPrincipal_vector
(
const tensor& tt,
const vector& v
)
{
return symmTensor
(
tt.xx()*v.x()*tt.xx()
+ tt.xy()*v.y()*tt.xy()
+ tt.xz()*v.z()*tt.xz(),
tt.xx()*v.x()*tt.yx()
+ tt.xy()*v.y()*tt.yy()
+ tt.xz()*v.z()*tt.yz(),
tt.xx()*v.x()*tt.zx()
+ tt.xy()*v.y()*tt.zy()
+ tt.xz()*v.z()*tt.zz(),
tt.yx()*v.x()*tt.yx()
+ tt.yy()*v.y()*tt.yy()
+ tt.yz()*v.z()*tt.yz(),
tt.yx()*v.x()*tt.zx()
+ tt.yy()*v.y()*tt.zy()
+ tt.yz()*v.z()*tt.zz(),
tt.zx()*v.x()*tt.zx()
+ tt.zy()*v.y()*tt.zy()
+ tt.zz()*v.z()*tt.zz()
);
}
} // End namespace Foam
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::pointField> Foam::coordinateSystem::transformPoint
(
const UList<point>& localCart
) const
{
return transformPointImpl(localCart);
}
Foam::tmp<Foam::pointField> Foam::coordinateSystem::transformPoint
(
const pointUIndList& localCart
) const
{
return transformPointImpl(localCart);
}
Foam::tmp<Foam::pointField> Foam::coordinateSystem::invTransformPoint
(
const UList<point>& global
) const
{
return invTransformPointImpl(global);
}
Foam::tmp<Foam::pointField> Foam::coordinateSystem::invTransformPoint
(
const pointUIndList& global
) const
{
return invTransformPointImpl(global);
}
// Transformations
#undef makeCoordinateSystemTransform
#define makeCoordinateSystemTransform(Op, RetType, Type) \
Foam::RetType Foam::coordinateSystem::Op \
( \
const Type& input \
) const \
{ \
return Op##_##Type(rot_, input); \
} \
\
Foam::tmp<Foam::Field<Foam::RetType>> Foam::coordinateSystem::Op \
( \
const UList<Type>& input \
) const \
{ \
return manyTimesImpl<RetType>(rot_, input, Op##_##Type); \
} \
\
Foam::RetType Foam::coordinateSystem::Op \
( \
const point& global, \
const Type& input \
) const \
{ \
return Op##_##Type(this->R(global), input); \
} \
\
Foam::tmp<Foam::Field<Foam::RetType>> Foam::coordinateSystem::Op \
( \
const UList<point>& global, \
const Type& input \
) const \
{ \
return oneToManyImpl<RetType>(global, input, Op##_##Type); \
} \
\
Foam::tmp<Foam::Field<Foam::RetType>> Foam::coordinateSystem::Op \
( \
const pointUIndList& global, \
const Type& input \
) const \
{ \
return oneToManyImpl<RetType>(global, input, Op##_##Type); \
} \
\
Foam::tmp<Foam::Field<Foam::RetType>> Foam::coordinateSystem::Op \
( \
const UList<point>& global, \
const UList<Type>& input \
) const \
{ \
return oneToOneImpl<RetType>(global, input, Op##_##Type); \
} \
\
Foam::tmp<Foam::Field<Foam::RetType>> Foam::coordinateSystem::Op \
( \
const pointUIndList& global, \
const UList<Type>& input \
) const \
{ \
return oneToOneImpl<RetType>(global, input, Op##_##Type); \
}
makeCoordinateSystemTransform(transformPrincipal, symmTensor, vector);
makeCoordinateSystemTransform(transform, scalar, scalar);
makeCoordinateSystemTransform(transform, vector, vector);
makeCoordinateSystemTransform(transform, sphericalTensor, sphericalTensor);
makeCoordinateSystemTransform(transform, symmTensor, symmTensor);
makeCoordinateSystemTransform(transform, tensor, tensor);
makeCoordinateSystemTransform(invTransform, scalar, scalar);
makeCoordinateSystemTransform(invTransform, vector, vector);
makeCoordinateSystemTransform(invTransform, sphericalTensor, sphericalTensor);
makeCoordinateSystemTransform(invTransform, symmTensor, symmTensor);
makeCoordinateSystemTransform(invTransform, tensor, tensor);
#undef makeCoordinateSystemTransform
// ************************************************************************* //

View File

@ -24,18 +24,20 @@ License
\*---------------------------------------------------------------------------*/
#include "coordinateSystems.H"
#include "IOPtrList.H"
#include "Time.H"
#include "stringListOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(coordinateSystems, 0);
defineTemplateTypeNameAndDebug(IOPtrList<coordinateSystem>, 0);
defineTypeName(coordinateSystems);
}
// File-local
//- Header name for 1806 and earlier
static const char* headerTypeCompat = "IOPtrList<coordinateSystem>";
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
@ -127,12 +129,77 @@ namespace Foam
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::coordinateSystems::readFromStream(const bool valid)
{
Istream& is = readStream(word::null, valid);
if (valid)
{
if (headerClassName() == typeName)
{
this->readIstream(is, coordinateSystem::iNew());
close();
}
else if (headerClassName() == headerTypeCompat)
{
// Older (1806 and earlier) header name
std::cerr
<< "--> FOAM IOWarning :" << nl
<< " Found header class name '" << headerTypeCompat
<< "' instead of '" << typeName << "'" << nl;
error::warnAboutAge("header class", 1806);
this->readIstream(is, coordinateSystem::iNew());
close();
}
else
{
FatalIOErrorInFunction
(
is
) << "unexpected class name " << headerClassName()
<< " expected " << typeName
<< " or " << headerTypeCompat << nl
<< " while reading object " << name()
<< exit(FatalIOError);
}
}
}
bool Foam::coordinateSystems::readObject(const IOobject& io)
{
if
(
(
io.readOpt() == IOobject::MUST_READ
|| io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
)
|| (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
)
{
readFromStream();
return true;
}
return false;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::coordinateSystems::coordinateSystems(const IOobject& io)
:
IOPtrList<coordinateSystem>(io)
{}
regIOobject(io),
PtrList<coordinateSystem>()
{
readObject(io);
}
Foam::coordinateSystems::coordinateSystems
@ -141,8 +208,14 @@ Foam::coordinateSystems::coordinateSystems
const PtrList<coordinateSystem>& content
)
:
IOPtrList<coordinateSystem>(io, content)
{}
regIOobject(io),
PtrList<coordinateSystem>()
{
if (!readObject(io))
{
static_cast<PtrList<coordinateSystem>&>(*this) = content;
}
}
Foam::coordinateSystems::coordinateSystems
@ -151,8 +224,11 @@ Foam::coordinateSystems::coordinateSystems
PtrList<coordinateSystem>&& content
)
:
IOPtrList<coordinateSystem>(io, std::move(content))
{}
regIOobject(io),
PtrList<coordinateSystem>(std::move(content))
{
readObject(io);
}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
@ -253,18 +329,64 @@ bool Foam::coordinateSystems::found(const keyType& key) const
}
Foam::wordList Foam::coordinateSystems::names() const
const Foam::coordinateSystem*
Foam::coordinateSystems::lookupPtr(const word& name) const
{
const PtrList<coordinateSystem>& systems = *this;
const label index = this->findIndex(name);
wordList list(systems.size());
forAll(systems, i)
if (coordinateSystem::debug)
{
list[i] = systems[i].name();
InfoInFunction
<< "Global coordinate system: "
<< name << "=" << index << endl;
}
return list;
if (index < 0)
{
return nullptr;
}
return this->operator()(index);
}
const Foam::coordinateSystem&
Foam::coordinateSystems::lookup(const word& name) const
{
const label index = this->findIndex(name);
if (index < 0)
{
FatalErrorInFunction
<< "Could not find coordinate system: " << name << nl
<< "available coordinate systems: "
<< flatOutput(names()) << nl << nl
<< exit(FatalError);
}
if (coordinateSystem::debug)
{
InfoInFunction
<< "Global coordinate system: "
<< name << "=" << index << endl;
}
return this->operator[](index);
}
Foam::wordList Foam::coordinateSystems::names() const
{
const PtrList<coordinateSystem>& list = *this;
wordList result(list.size());
forAll(list, i)
{
result[i] = list[i].name();
}
return result;
// return ListOps::create<word>(list, nameOp<coordinateSystem>());
}
@ -303,12 +425,14 @@ Foam::wordList Foam::coordinateSystems::names(const wordRes& matcher) const
bool Foam::coordinateSystems::writeData(Ostream& os) const
{
const PtrList<coordinateSystem>& list = *this;
os << nl << size() << nl << token::BEGIN_LIST;
forAll(*this, i)
for (const coordinateSystem& csys : list)
{
os << nl;
operator[](i).writeDict(os, true);
csys.writeEntry(csys.name(), os);
}
os << token::END_LIST << nl;
@ -317,4 +441,23 @@ bool Foam::coordinateSystems::writeData(Ostream& os) const
}
bool Foam::coordinateSystems::writeObject
(
IOstream::streamFormat,
IOstream::versionNumber ver,
IOstream::compressionType,
const bool valid
) const
{
// Force ASCII writing
return regIOobject::writeObject
(
IOstream::ASCII,
ver,
IOstream::UNCOMPRESSED,
valid
);
}
// ************************************************************************* //

View File

@ -25,30 +25,31 @@ Class
Foam::coordinateSystems
Description
Provides a centralized coordinateSystem collection.
A centralized collection of named coordinate systems.
Note
Mixing normal constructors and the coordinateSystems::New constructor
may yield unexpected results.
\verbatim
1
(
cat1
cat1
{
coordinateSystem
{
coordinateSystem system_10;
porosity 0.781;
Darcy
{
d d [0 -2 0 0 0] (-1000 -1000 0.50753e+08);
f f [0 -1 0 0 0] (-1000 -1000 12.83);
}
type indirect;
name _10;
}
)
porosity 0.781;
Darcy
{
d d [0 -2 0 0 0] (-1000 -1000 0.50753e+08);
f f [0 -1 0 0 0] (-1000 -1000 12.83);
}
}
\endverbatim
For this to work correctly, the coordinateSystem constructor must be
supplied with both a dictionary and an objectRegistry.
supplied with an objectRegistry as well as the dictionary.
SourceFiles
coordinateSystems.C
@ -57,8 +58,9 @@ SourceFiles
#ifndef coordinateSystems_H
#define coordinateSystems_H
#include "regIOobject.H"
#include "PtrList.H"
#include "coordinateSystem.H"
#include "IOPtrList.H"
#include "wordRes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -72,10 +74,19 @@ namespace Foam
class coordinateSystems
:
public IOPtrList<coordinateSystem>
public regIOobject,
public PtrList<coordinateSystem>
{
// Private Member Functions
//- Read "coordinateSystems" or older "IOPtrList<coordinateSystem>"
void readFromStream(const bool valid = true);
//- Attempt read if MUST_READ.., or READ_IF_PRESENT and has header
// \return False if no read should have been attempted
bool readObject(const IOobject& io);
//- No copy construct
coordinateSystems(const coordinateSystems&) = delete;
@ -86,21 +97,22 @@ class coordinateSystems
public:
//- Runtime type information
TypeName("coordinateSystems");
TypeNameNoDebug("coordinateSystems");
// Constructors
//- Read construct from IOobject
explicit coordinateSystems(const IOobject& io);
//- Construct from IOobject and a PtrList
//- Construct from IOobject and PtrList content
coordinateSystems
(
const IOobject& io,
const PtrList<coordinateSystem>& content
);
//- Construct from IOobject and transferring the PtrList content
//- Construct from IOobject and transferring PtrList content
coordinateSystems
(
const IOobject& io,
@ -111,7 +123,7 @@ public:
// Selectors
//- Return previously registered or read construct from "constant"
static const coordinateSystems& New(const objectRegistry&);
static const coordinateSystems& New(const objectRegistry& obr);
// Member Functions
@ -131,6 +143,12 @@ public:
//- Search if given key exists
bool found(const keyType& key) const;
//- Return reference to named coordinateSystem or FatalErrror
const coordinateSystem& lookup(const word& name) const;
//- Return pointer to named coordinateSystem or nullptr on error
const coordinateSystem* lookupPtr(const word& name) const;
//- A list of the coordinate-system names
wordList names() const;
@ -149,8 +167,20 @@ public:
return names();
}
// IO
//- Write data
bool writeData(Ostream&) const;
bool writeData(Ostream& os) const;
//- Write data
virtual bool writeObject
(
IOstream::streamFormat,
IOstream::versionNumber ver,
IOstream::compressionType,
const bool valid = true
) const;
// Housekeeping

View File

@ -26,6 +26,18 @@ License
#include "cylindricalCS.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace coordSystem
{
defineTypeName(cylindrical);
addToRunTimeSelectionTable(coordinateSystem, cylindrical, dictionary);
}
}
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
@ -65,43 +77,52 @@ static inline vector toCartesian(const vector& v)
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cylindricalCS::cylindricalCS()
Foam::coordSystem::cylindrical::cylindrical()
:
coordinateSystem()
{}
Foam::cylindricalCS::cylindricalCS
(
const coordinateSystem& cs
)
Foam::coordSystem::cylindrical::cylindrical(const coordinateSystem& csys)
:
coordinateSystem(cs)
coordinateSystem(csys)
{}
Foam::cylindricalCS::cylindricalCS
(
const word& name,
const coordinateSystem& cs
)
Foam::coordSystem::cylindrical::cylindrical(coordinateSystem&& csys)
:
coordinateSystem(name, cs)
coordinateSystem(std::move(csys))
{}
Foam::cylindricalCS::cylindricalCS
Foam::coordSystem::cylindrical::cylindrical(autoPtr<coordinateSystem>&& csys)
:
coordinateSystem(std::move(csys))
{}
Foam::coordSystem::cylindrical::cylindrical
(
const word& name,
const point& origin,
const coordinateRotation& cr
const coordinateRotation& crot
)
:
coordinateSystem(name, origin, cr)
coordinateSystem(origin, crot)
{}
Foam::cylindricalCS::cylindricalCS
Foam::coordSystem::cylindrical::cylindrical
(
const point& origin,
const vector& axis,
const vector& dirn
)
:
coordinateSystem(origin, axis, dirn)
{}
Foam::coordSystem::cylindrical::cylindrical
(
const word& name,
const point& origin,
@ -113,7 +134,7 @@ Foam::cylindricalCS::cylindricalCS
{}
Foam::cylindricalCS::cylindricalCS
Foam::coordSystem::cylindrical::cylindrical
(
const word& name,
const dictionary& dict
@ -128,13 +149,9 @@ Foam::cylindricalCS::cylindricalCS
}
Foam::cylindricalCS::cylindricalCS
(
const objectRegistry& obr,
const dictionary& dict
)
Foam::coordSystem::cylindrical::cylindrical(const dictionary& dict)
:
coordinateSystem(obr, dict)
coordinateSystem(dict)
{
if (dict.lookupOrDefault("degrees", false))
{
@ -143,9 +160,65 @@ Foam::cylindricalCS::cylindricalCS
}
Foam::coordSystem::cylindrical::cylindrical
(
const dictionary& dict,
const word& dictName
)
:
coordinateSystem(dict, dictName)
{
const dictionary* dictPtr =
(
dictName.size()
? &(dict.subDict(dictName))
: &(dict)
);
if (dictPtr->lookupOrDefault("degrees", false))
{
warnCompatDegrees(dict);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::vector Foam::cylindricalCS::localToGlobal
Foam::tensor Foam::coordSystem::cylindrical::R(const point& global) const
{
// Robuster version of coordinateRotations::axes::rotation()
// using an E3_E1 order and falling back to the top-level rotation
// tensor if the directional input is borderline.
tensor rotTensor(rot_);
const vector ax1 = rotTensor.col<2>(); // == e3 (already normalized)
vector ax2(global - origin_);
// Remove colinear component
ax2 -= ((ax1 & ax2) * ax1);
const scalar magAxis2(mag(ax2));
// Trap zero size and colinearity
if (magAxis2 < SMALL)
{
return rotTensor;
}
ax2 /= magAxis2; // normalise
// Replace with updated local axes
rotTensor.col<0>(ax2);
rotTensor.col<1>(ax1^ax2);
return rotTensor;
}
Foam::vector Foam::coordSystem::cylindrical::localToGlobal
(
const vector& local,
bool translate
@ -159,7 +232,7 @@ Foam::vector Foam::cylindricalCS::localToGlobal
}
Foam::tmp<Foam::vectorField> Foam::cylindricalCS::localToGlobal
Foam::tmp<Foam::vectorField> Foam::coordSystem::cylindrical::localToGlobal
(
const vectorField& local,
bool translate
@ -184,7 +257,7 @@ Foam::tmp<Foam::vectorField> Foam::cylindricalCS::localToGlobal
}
Foam::vector Foam::cylindricalCS::globalToLocal
Foam::vector Foam::coordSystem::cylindrical::globalToLocal
(
const vector& global,
bool translate
@ -197,7 +270,7 @@ Foam::vector Foam::cylindricalCS::globalToLocal
}
Foam::tmp<Foam::vectorField> Foam::cylindricalCS::globalToLocal
Foam::tmp<Foam::vectorField> Foam::coordSystem::cylindrical::globalToLocal
(
const vectorField& global,
bool translate
@ -220,4 +293,5 @@ Foam::tmp<Foam::vectorField> Foam::cylindricalCS::globalToLocal
}
// ************************************************************************* //

View File

@ -22,13 +22,21 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cylindricalCS
Foam::coordSystem::cylindrical
Description
Cylindrical coordinate system, always in radians.
A cylindrical coordinate system (r-theta-z).
The coordinate system angle theta is always in radians.
\heading Dictionary entries
\table
Property | Description | Required | Default
type | type name: cylindrical | yes |
\endtable
SourceFiles
cylindricalCS.C
cylindricalCSTransform.C
\*---------------------------------------------------------------------------*/
@ -41,12 +49,14 @@ SourceFiles
namespace Foam
{
namespace coordSystem
{
/*---------------------------------------------------------------------------*\
Class cylindricalCS Declaration
Class coordSystem::cylindrical Declaration
\*---------------------------------------------------------------------------*/
class cylindricalCS
class cylindrical
:
public coordinateSystem
{
@ -54,63 +64,78 @@ protected:
// Protected Member Functions
//- From local coordinate system to the global Cartesian system
//- with optional translation for the origin
virtual vector localToGlobal
(
const vector& local,
bool translate
) const;
//- Convert from local coordinate system to the global Cartesian system
// with optional translation for the origin
virtual vector localToGlobal(const vector&, bool translate) const;
//- Convert from local coordinate system to the global Cartesian system
// with optional translation for the origin
//- From local coordinate system to the global Cartesian system
//- with optional translation for the origin
virtual tmp<vectorField> localToGlobal
(
const vectorField&,
const vectorField& local,
bool translate
) const;
//- From global Cartesian system to the local coordinate system
//- with optional translation for the origin
virtual vector globalToLocal
(
const vector& global,
bool translate
) const;
//- Convert from global Cartesian system to the local coordinate system
// with optional translation for the origin
virtual vector globalToLocal(const vector&, bool translate) const;
//- Convert from global Cartesian system to the local coordinate system
// with optional translation for the origin
//- with optional translation for the origin
virtual tmp<vectorField> globalToLocal
(
const vectorField&,
const vectorField& global,
bool translate
) const;
public:
//- Runtime type information
TypeNameNoDebug("cylindrical");
// Constructors
//- Construct null
cylindricalCS();
//- Construct null (identity coordinateSystem)
cylindrical();
//- Construct copy
cylindricalCS
(
const coordinateSystem&
);
//- Copy construct
cylindrical(const cylindrical& csys) = default;
//- Construct copy with a different name
cylindricalCS
(
const word& name,
const coordinateSystem&
);
//- Move construct
cylindrical(cylindrical&& csys) = default;
//- Copy construct from another coordinateSystem type
explicit cylindrical(const coordinateSystem& csys);
//- Move construct from another coordinateSystem type
explicit cylindrical(coordinateSystem&& csys);
//- Move construct from autoPtr of another coordinateSystem type
explicit cylindrical(autoPtr<coordinateSystem>&& csys);
//- Construct from origin and rotation
cylindricalCS
cylindrical(const point& origin, const coordinateRotation& crot);
//- Construct from origin and 2 axes
cylindrical
(
const word& name,
const point& origin,
const coordinateRotation&
const vector& axis,
const vector& dirn
);
//- Construct from origin and 2 axes
cylindricalCS
cylindrical
(
const word& name,
const point& origin,
@ -118,18 +143,59 @@ public:
const vector& dirn
);
//- Construct from dictionary and name
cylindricalCS(const word&, const dictionary&);
//- Construct from dictionary with a given name
cylindrical(const word& name, const dictionary& dict);
//- Construct from dictionary and objectRegistry
cylindricalCS(const objectRegistry&, const dictionary&);
//- Construct from dictionary without a name
explicit cylindrical(const dictionary& dict);
//- Construct from dictionary with optional subDict lookup.
//
// \param dictName If non-empty, the sub-dictionary to use.
cylindrical(const dictionary& dict, const word& dictName);
//- Destructor
virtual ~cylindricalCS() = default;
virtual ~cylindrical() = default;
// Member Functions
//- Treat the rotation tensor as non-uniform
virtual bool uniform() const
{
return false;
}
// Rotations
//- Position-dependent rotation tensors at multiple points
using coordinateSystem::R;
//- Position-dependent rotation tensor at a single point
//- \return tensor
virtual tensor R(const point& global) const;
// Member Operators
//- Copy assignment
cylindrical& operator=(const cylindrical&) = default;
//- Move assignment
cylindrical& operator=(cylindrical&&) = default;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace coordSystem
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Compatibility typedef 1806
typedef coordSystem::cylindrical cylindricalCS;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -0,0 +1,113 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "indirectCS.H"
#include "coordinateSystems.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace coordSystem
{
defineTypeNameAndDebug(indirect, 0);
addToRunTimeSelectionTable(coordinateSystem, indirect, registry);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::coordSystem::indirect::indirect(const indirect& csys)
:
coordinateSystem(),
backend_(csys.backend_)
{}
Foam::coordSystem::indirect::indirect(indirect&& csys)
:
coordinateSystem(),
backend_(std::move(csys.backend_))
{}
// Use lookup() instead of lookupPtr() to trigger FatalError on any problems
Foam::coordSystem::indirect::indirect
(
const objectRegistry& obr,
const word& name
)
:
coordinateSystem(),
backend_(&(coordinateSystems::New(obr).lookup(name)))
{}
Foam::coordSystem::indirect::indirect
(
const objectRegistry& obr,
const dictionary& dict
)
:
indirect(obr, dict.get<word>("name"))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::coordSystem::indirect::write(Ostream& os) const
{
writeEntry(coordinateSystem::typeName_(), os);
}
void Foam::coordSystem::indirect::writeEntry
(
const word& keyword,
Ostream& os
) const
{
if (!valid())
{
return;
}
const bool subDict = !keyword.empty();
if (subDict)
{
os.beginBlock(keyword);
os.writeEntry("type", type());
os.writeEntry("name", name());
os.endBlock();
}
}
// ************************************************************************* //

View File

@ -0,0 +1,298 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::coordSystem::indirect
Description
A coordinate system forward to a global coordinate system that is
normally provided by the constant/coordinateSystems file.
\heading Dictionary entries
\table
Property | Description | Required | Default
type | Type name: indirect | yes |
name | Name of the referenced system | yes |
\endtable
SourceFiles
indirectCS.C
\*---------------------------------------------------------------------------*/
#ifndef indirectCS_H
#define indirectCS_H
#include "coordinateSystem.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace coordSystem
{
/*---------------------------------------------------------------------------*\
Class coordSystem::indirect Declaration
\*---------------------------------------------------------------------------*/
class indirect
:
public coordinateSystem
{
// Private Data
//- The real coordinate system
const coordinateSystem* backend_;
// Private Member Functions
//- Construct null is disallowed
indirect() = delete;
protected:
// Protected Member Functions
//- Convert from local coordinate system to the global Cartesian system
//- with optional translation for the origin
virtual vector localToGlobal
(
const vector& local,
bool translate
) const
{
return backend_->localToGlobal(local, translate);
}
//- Convert from local coordinate system to the global Cartesian system
//- with optional translation for the origin
virtual tmp<vectorField> localToGlobal
(
const vectorField& local,
bool translate
) const
{
return backend_->localToGlobal(local, translate);
}
//- Convert from global Cartesian system to the local coordinate system
//- with optional translation for the origin
virtual vector globalToLocal
(
const vector& global,
bool translate
) const
{
return backend_->globalToLocal(global, translate);
}
//- Convert from global Cartesian system to the local coordinate system
//- with optional translation for the origin
virtual tmp<vectorField> globalToLocal
(
const vectorField& global,
bool translate
) const
{
return backend_->globalToLocal(global, translate);
}
public:
//- Runtime type information
TypeName("indirect");
// Constructors
//- Copy construct
indirect(const indirect& csys);
//- Move construct
indirect(indirect&& csys);
//- Construct from global lookup
indirect(const objectRegistry& obr, const word& name);
//- Construct from global lookup
indirect(const objectRegistry& obr, const dictionary& dict);
//- Destructor
virtual ~indirect() = default;
// Member Functions
// Access
//- Reference to the underlying coordinate system
virtual const coordinateSystem& cs() const
{
return *backend_;
}
//- Is the coordinate system valid?
virtual bool valid() const
{
return backend_ && backend_->valid();
}
//- True if the rotation tensor is uniform for all positions
virtual bool uniform() const
{
return backend_->uniform();
}
//- The rotation specification
virtual const coordinateRotation& rotation() const
{
return backend_->rotation();
}
//- Return the name
virtual const word& name() const
{
return backend_->name_;
}
//- Return the optional note
virtual const string& note() const
{
return backend_->note();
}
//- Return origin
virtual const point& origin() const
{
return backend_->origin();
}
//- Return const reference to the rotation tensor
virtual const tensor& R() const
{
return backend_->R();
}
//- The local Cartesian x-axis in global coordinates
virtual const vector e1() const
{
return backend_->e1();
}
//- The local Cartesian y-axis in global coordinates
virtual const vector e2() const
{
return backend_->e2();
}
//- The local Cartesian z-axis in global coordinates
virtual const vector e3() const
{
return backend_->e3();
}
// Edit
//- Rename (ignored)
void rename(const word& newName) {}
//- Provide non-constant access to the optional note
string& note()
{
NotImplemented;
return dummy_.note();
}
//- Edit access to origin (disallowed)
virtual point& origin()
{
NotImplemented;
return dummy_.origin();
}
//- Clear (ignored)
virtual void clear() {}
//- Change the rotation (disallowed)
virtual void rotation(autoPtr<coordinateRotation>&& crot)
{
NotImplemented;
}
// Write
//- Write
virtual void write(Ostream& os) const;
//- Write dictionary entry
virtual void writeEntry(const word& keyword, Ostream& os) const;
// Member Operators
//- No copy assignment
void operator=(const coordinateSystem& csys) = delete;
//- No move assignment
void operator=(coordinateSystem&& csys) = delete;
// Rotations
//- Position-dependent rotation tensor at a single point
virtual tensor R(const point& global) const
{
return backend_->R(global);
}
//- Position-dependent rotation tensors at multiple points
virtual tmp<tensorField> R(const UList<point>& global) const
{
return backend_->R(global);
}
//- Position-dependent rotation tensors at multiple points
virtual tmp<tensorField> R(const pointUIndList& global) const
{
return backend_->R(global);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace coordSystem
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -25,7 +25,6 @@ License
#include "searchableRotatedBox.H"
#include "addToRunTimeSelectionTable.H"
#include "axesRotation.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

View File

@ -201,7 +201,8 @@ Foam::searchableSurfaceCollection::searchableSurfaceCollection
surfI,
coordinateSystem::New
(
subDict.subDict("transform")
subDict,
"transform"
)
);
@ -229,7 +230,7 @@ Foam::searchableSurfaceCollection::searchableSurfaceCollection
Info<< " instance : " << instance_[surfI] << endl;
Info<< " surface : " << s.name() << endl;
Info<< " scale : " << scale_[surfI] << endl;
Info<< " coordsys : " << transform_[surfI] << endl;
Info<< " transform: " << transform_[surfI] << endl;
surfI++;
}