ENH: additional Field normalise method (#2444)

- for most field types this is a no-op, but for a field of floatVector
  or doubleVector (eg, vector and solveVector) it will normalise each
  element with divide-by-zero protection.

  More reliable and efficient than dividing a field by the mag of itself
  (even with VSMALL protection).
  Applied to FieldField and GeometricField as well.

  Eg,
      fld.normalise();
  vs.
      fld /= mag(fld) + VSMALL;

ENH: support optional tolerance for vector::normalise

- for cases where tolerances larger than ROOTVSMALL are preferable.
  Not currently available for the field method (a templating question).

ENH: vector::removeCollinear method

- when working with geometries it is frequently necessary to have a
  normal vector without any collinear components. The removeCollinear
  method provides for clearer, compacter code.

  Eg,
      vector edgeNorm = ...;

      const vector edgeDirn = e.unitVec(points());

      edgeNorm.removeCollinear(edgeDirn);
      edgeNorm.normalise();

  vs.
      vector edgeNorm = ...;

      const vector edgeDirn = e.unitVec(points());

      edgeNorm -= edgeDirn*(edgeDirn & edgeNorm);
      edgeNorm /= mag(edgeNorm);
This commit is contained in:
Mark Olesen
2022-04-14 09:53:20 +02:00
parent b59a5b1188
commit 8e6f2ca5de
23 changed files with 406 additions and 114 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2021 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,7 +31,7 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "vector.H" #include "vectorField.H"
#include "IOstreams.H" #include "IOstreams.H"
#include <algorithm> #include <algorithm>
#include <random> #include <random>
@ -110,6 +110,16 @@ void testData(const VecSpace& vs)
} }
template<class Type>
void testNormalise(Field<Type>& fld)
{
Info<< nl << pTraits<Type>::typeName << " Field" << nl
<< " orig: " << fld << nl;
fld.normalise();
Info<< " norm: " << fld << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program: // Main program:
@ -138,6 +148,38 @@ int main(int argc, char *argv[])
Info<< "shuffled: " << vec2 << nl; Info<< "shuffled: " << vec2 << nl;
} }
// Basic tests for fields
{
scalarField sfld1
({
0.0,
1.0,
2.0
});
testNormalise(sfld1);
Field<floatVector> vfld1
({
floatVector(0.0, 1.0, 2.0),
floatVector(0, 0, floatScalarSMALL),
floatVector(0, 0, floatScalarVSMALL),
floatVector(0, 2, 1),
});
testNormalise(vfld1);
Field<doubleVector> vfld2
({
doubleVector(0.0, 1.0, 2.0),
doubleVector(0, 0, doubleScalarSMALL),
doubleVector(0, 0, doubleScalarVSMALL),
doubleVector(0, 2, 1),
});
testNormalise(vfld2);
}
Info<< "\nEnd\n" << nl; Info<< "\nEnd\n" << nl;
return 0; return 0;

View File

@ -726,6 +726,7 @@ $(Fields)/labelField/labelFieldIOField.C
$(Fields)/scalarField/scalarField.C $(Fields)/scalarField/scalarField.C
$(Fields)/scalarField/scalarIOField.C $(Fields)/scalarField/scalarIOField.C
$(Fields)/scalarField/scalarFieldIOField.C $(Fields)/scalarField/scalarFieldIOField.C
$(Fields)/vectorField/vectorField.C
$(Fields)/vectorField/vectorIOField.C $(Fields)/vectorField/vectorIOField.C
$(Fields)/vectorField/vectorFieldIOField.C $(Fields)/vectorField/vectorFieldIOField.C
$(Fields)/vector2DField/vector2DIOField.C $(Fields)/vector2DField/vector2DIOField.C

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -225,6 +225,16 @@ void FieldField<Field, Type>::negate()
} }
template<template<class> class Field, class Type>
void FieldField<Field, Type>::normalise()
{
forAll(*this, i)
{
this->operator[](i).normalise();
}
}
template<template<class> class Field, class Type> template<template<class> class Field, class Type>
tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType>> tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType>>
FieldField<Field, Type>::component FieldField<Field, Type>::component

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -34,8 +35,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef FieldField_H #ifndef Foam_FieldField_H
#define FieldField_H #define Foam_FieldField_H
#include "tmp.H" #include "tmp.H"
#include "PtrList.H" #include "PtrList.H"
@ -48,7 +49,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
template<template<class> class Field, class Type> template<template<class> class Field, class Type>
class FieldField; class FieldField;
@ -131,11 +132,14 @@ public:
); );
// Member functions // Member Functions
//- Negate this field //- Negate this field. See notes in Field
void negate(); void negate();
//- Normalise this field. See notes in Field
void normalise();
//- Return a component field of the field //- Return a component field of the field
tmp<FieldField<Field, cmptType>> component(const direction) const; tmp<FieldField<Field, cmptType>> component(const direction) const;

View File

@ -533,6 +533,12 @@ void Foam::Field<Type>::negate()
} }
// A no-op except for vector specialization
template<class Type>
void Foam::Field<Type>::normalise()
{}
template<class Type> template<class Type>
Foam::tmp<Foam::Field<typename Foam::Field<Type>::cmptType>> Foam::tmp<Foam::Field<typename Foam::Field<Type>::cmptType>>
Foam::Field<Type>::component Foam::Field<Type>::component

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2021 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -42,8 +42,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef Field_H #ifndef Foam_Field_H
#define Field_H #define Foam_Field_H
#include "tmp.H" #include "tmp.H"
#include "direction.H" #include "direction.H"
@ -340,10 +340,16 @@ public:
const UList<scalar>& weights const UList<scalar>& weights
); );
//- Negate this field (negative). //- Inplace negate this field (negative).
// Inverts the state for a bool field. // Inverts the state for a bool field.
void negate(); void negate();
//- Inplace normalise this field.
//- Generally a no-op except for vector fields.
// Vector fields are normalised by their magnitude.
// Small vectors (mag less than ROOTVSMALL) are set to zero.
void normalise();
//- Return a component field of the field //- Return a component field of the field
tmp<Field<cmptType>> component(const direction) const; tmp<Field<cmptType>> component(const direction) const;

View File

@ -0,0 +1,112 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 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 "vectorField.H"
// * * * * * * * * * * * * * * * Specializations * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Note: the mag of vector and division is written out to avoid any casting
// between float and double.
//
// This enables specialization for floatVector and doubleVector independent
// of the definition of 'scalar' or 'vector' - useful for mixed-precision
// operation.
template<>
void Field<Vector<float>>::normalise()
{
typedef float cmptType;
constexpr float tol = floatScalarROOTVSMALL;
for (Vector<cmptType>& v : *this)
{
// Foam::mag but using cmptType instead of scalar
cmptType s
(
::sqrt(magSqr(v.x()) + magSqr(v.y()) + magSqr(v.z()))
);
if (s < tol)
{
v.x() = 0;
v.y() = 0;
v.z() = 0;
}
else
{
v.x() /= s;
v.y() /= s;
v.z() /= s;
}
}
}
template<>
void Field<Vector<double>>::normalise()
{
typedef double cmptType;
constexpr double tol = doubleScalarROOTVSMALL;
for (Vector<cmptType>& v : *this)
{
// Foam::mag but using cmptType instead of scalar
cmptType s
(
::sqrt(magSqr(v.x()) + magSqr(v.y()) + magSqr(v.z()))
);
if (s < tol)
{
v.x() = 0;
v.y() = 0;
v.z() = 0;
}
else
{
v.x() /= s;
v.y() /= s;
v.z() /= s;
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -35,8 +35,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef vectorField_H #ifndef Foam_vectorField_H
#define vectorField_H #define Foam_vectorField_H
#include "scalarField.H" #include "scalarField.H"
#include "vector.H" #include "vector.H"
@ -52,6 +52,13 @@ typedef Field<vector> vectorField;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Inplace normalise (float) vector field
template<> void Field<Vector<float>>::normalise();
//- Inplace normalise (double) vector field
template<> void Field<Vector<double>>::normalise();
//- Zip together vector field from components //- Zip together vector field from components
template<class Cmpt> template<class Cmpt>
void zip void zip

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2021 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -1193,6 +1193,14 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::negate()
} }
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::normalise()
{
primitiveFieldRef().normalise();
boundaryFieldRef().normalise();
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -527,9 +527,12 @@ public:
// Member Function *this Operators // Member Function *this Operators
//- Negate the field inplace //- Negate the field inplace. See notes in Field
void negate(); void negate();
//- Normalise the field inplace. See notes in Field
void normalise();
//- Replace specified field component with content from another field //- Replace specified field component with content from another field
void replace void replace
( (

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -42,8 +42,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef pointPatchField_H #ifndef Foam_pointPatchField_H
#define pointPatchField_H #define Foam_pointPatchField_H
#include "pointPatch.H" #include "pointPatch.H"
#include "DimensionedField.H" #include "DimensionedField.H"
@ -54,7 +54,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
class objectRegistry; class objectRegistry;
class dictionary; class dictionary;
@ -75,7 +75,7 @@ Ostream& operator<<(Ostream&, const pointPatchField<Type>&);
template<class Type> template<class Type>
class pointPatchField class pointPatchField
{ {
// Private data // Private Data
//- Reference to patch //- Reference to patch
const pointPatch& patch_; const pointPatch& patch_;
@ -471,14 +471,13 @@ public:
); );
// Housekeeping // Other Methods
// Includes some dummy methods to ensure that various //- Negate the field inplace. Dummy placeholder for FieldField
// FieldFieldFunctions will be definable.
//- Negate the field inplace
// [dummy placeholder for FieldField] (2019-11)
void negate() {} void negate() {}
//- Normalise the field inplace. Dummy placeholder for FieldField
void normalise() {}
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -41,8 +41,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef Vector_H #ifndef Foam_Vector_H
#define Vector_H #define Foam_Vector_H
#include "contiguous.H" #include "contiguous.H"
#include "VectorSpace.H" #include "VectorSpace.H"
@ -130,15 +130,20 @@ public:
//- Access to the vector z component //- Access to the vector z component
inline Cmpt& z(); inline Cmpt& z();
//- Inplace normalise the vector by its magnitude
// For small magnitudes (less than ROOTVSMALL) set to zero.
// Will not be particularly useful for a vector of labels
inline Vector<Cmpt>& normalise(const scalar tol = ROOTVSMALL);
//- Normalise the vector by its magnitude //- Inplace removal of components that are collinear to the given
inline Vector<Cmpt>& normalise(); //- unit vector.
inline Vector<Cmpt>& removeCollinear(const Vector<Cmpt>& unitVec);
//- Return *this (used for point which is a typedef to Vector<scalar>. //- Return *this (used for point which is a typedef to Vector<scalar>.
inline const Vector<Cmpt>& centre inline const Vector<Cmpt>& centre
( (
const Foam::List<Vector<Cmpt>>& const Foam::UList<Vector<Cmpt>>& /* (unused) */
) const; ) const;
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2020 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -112,7 +112,7 @@ inline Cmpt& Foam::Vector<Cmpt>::z()
template<class Cmpt> template<class Cmpt>
inline const Foam::Vector<Cmpt>& Foam::Vector<Cmpt>::centre inline const Foam::Vector<Cmpt>& Foam::Vector<Cmpt>::centre
( (
const Foam::List<Vector<Cmpt>>& const Foam::UList<Vector<Cmpt>>&
) const ) const
{ {
return *this; return *this;
@ -120,11 +120,11 @@ inline const Foam::Vector<Cmpt>& Foam::Vector<Cmpt>::centre
template<class Cmpt> template<class Cmpt>
inline Foam::Vector<Cmpt>& Foam::Vector<Cmpt>::normalise() inline Foam::Vector<Cmpt>& Foam::Vector<Cmpt>::normalise(const scalar tol)
{ {
const scalar s(Foam::mag(*this)); const scalar s(Foam::mag(*this));
if (s < ROOTVSMALL) if (s < tol)
{ {
*this = Zero; *this = Zero;
} }
@ -137,6 +137,15 @@ inline Foam::Vector<Cmpt>& Foam::Vector<Cmpt>::normalise()
} }
template<class Cmpt>
inline Foam::Vector<Cmpt>&
Foam::Vector<Cmpt>::removeCollinear(const Vector<Cmpt>& unitVec)
{
*this -= (*this & unitVec) * unitVec;
return *this;
}
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
namespace Foam namespace Foam

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -37,8 +37,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef Vector2D_H #ifndef Foam_Vector2D_H
#define Vector2D_H #define Foam_Vector2D_H
#include "contiguous.H" #include "contiguous.H"
#include "VectorSpace.H" #include "VectorSpace.H"
@ -116,8 +116,16 @@ public:
//- Access to the vector y component //- Access to the vector y component
inline Cmpt& y(); inline Cmpt& y();
//- Normalise the vector by its magnitude //- Normalise the vector by its magnitude
inline Vector2D<Cmpt>& normalise(); // For small magnitudes (less than ROOTVSMALL) set to zero.
// Will not be particularly useful for a vector of labels
inline Vector2D<Cmpt>& normalise(const scalar tol = ROOTVSMALL);
//- Inplace removal of components that are collinear to the given
//- unit vector.
inline Vector2D<Cmpt>& removeCollinear(const Vector2D<Cmpt>& unitVec);
//- Perp dot product (dot product with perpendicular vector) //- Perp dot product (dot product with perpendicular vector)
inline scalar perp(const Vector2D<Cmpt>& b) const; inline scalar perp(const Vector2D<Cmpt>& b) const;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -91,11 +91,11 @@ inline Cmpt& Foam::Vector2D<Cmpt>::y()
template<class Cmpt> template<class Cmpt>
inline Foam::Vector2D<Cmpt>& Foam::Vector2D<Cmpt>::normalise() inline Foam::Vector2D<Cmpt>& Foam::Vector2D<Cmpt>::normalise(const scalar tol)
{ {
const scalar s(Foam::mag(*this)); const scalar s(Foam::mag(*this));
if (s < ROOTVSMALL) if (s < tol)
{ {
*this = Zero; *this = Zero;
} }
@ -108,6 +108,15 @@ inline Foam::Vector2D<Cmpt>& Foam::Vector2D<Cmpt>::normalise()
} }
template<class Cmpt>
inline Foam::Vector2D<Cmpt>&
Foam::Vector2D<Cmpt>::removeCollinear(const Vector2D<Cmpt>& unitVec)
{
*this -= (*this & unitVec) * unitVec;
return *this;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam

View File

@ -482,6 +482,8 @@ inline scalar mag
} }
//- Return the vector type normalised by its magnitude
// For small magnitudes (less than ROOTVSMALL) return zero.
template<class Form, class Cmpt, direction Ncmpts> template<class Form, class Cmpt, direction Ncmpts>
inline VectorSpace<Form, Cmpt, Ncmpts> normalised inline VectorSpace<Form, Cmpt, Ncmpts> normalised
( (

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2020 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,14 +36,15 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef quaternion_H #ifndef Foam_quaternion_H
#define quaternion_H #define Foam_quaternion_H
#include "scalar.H" #include "scalar.H"
#include "vector.H" #include "vector.H"
#include "tensor.H" #include "tensor.H"
#include "word.H" #include "word.H"
#include "Enum.H" #include "Enum.H"
#include "stdFoam.H" // For deprecation macros
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -141,7 +142,7 @@ public:
// Constructors // Constructors
//- Construct zero initialized //- Construct initialized to zero
inline quaternion(const Foam::zero); inline quaternion(const Foam::zero);
//- Construct given scalar and vector parts //- Construct given scalar and vector parts
@ -151,12 +152,12 @@ public:
inline quaternion(const vector& d, const scalar theta); inline quaternion(const vector& d, const scalar theta);
//- Construct a rotation quaternion given direction d //- Construct a rotation quaternion given direction d
//- and cosine angle cosTheta and flag if d is normalized //- and cosine angle cosTheta and flag if d is normalised
inline quaternion inline quaternion
( (
const vector& d, const vector& d,
const scalar cosTheta, const scalar cosTheta,
const bool normalized const bool isNormalised
); );
//- Construct a real quaternion from the given scalar part, //- Construct a real quaternion from the given scalar part,
@ -186,10 +187,10 @@ public:
// Access // Access
//- Scalar part of the quaternion ( = cos(theta/2) for rotation) //- Scalar part of the quaternion ( = cos(theta/2) for rotation)
inline scalar w() const; inline scalar w() const noexcept;
//- Vector part of the quaternion ( = axis of rotation) //- Vector part of the quaternion ( = axis of rotation)
inline const vector& v() const; inline const vector& v() const noexcept;
//- The rotation tensor corresponding to the quaternion //- The rotation tensor corresponding to the quaternion
inline tensor R() const; inline tensor R() const;
@ -198,20 +199,18 @@ public:
//- specified rotation order //- specified rotation order
inline vector eulerAngles(const eulerOrder order) const; inline vector eulerAngles(const eulerOrder order) const;
//- Return the quaternion normalized by its magnitude
inline quaternion normalized() const;
// Edit // Edit
//- Scalar part of the quaternion ( = cos(theta/2) for rotation) //- Scalar part of the quaternion ( = cos(theta/2) for rotation)
inline scalar& w(); inline scalar& w() noexcept;
//- Vector part of the quaternion ( = axis of rotation) //- Vector part of the quaternion ( = axis of rotation)
inline vector& v(); inline vector& v() noexcept;
//- Normalize the quaternion by its magnitude //- Inplace normalise the quaternion by its magnitude
inline void normalize(); // For small magnitudes (less than ROOTVSMALL) set to zero.
inline quaternion& normalise();
// Transform // Transform
@ -222,10 +221,10 @@ public:
//- Rotate the given vector anti-clockwise //- Rotate the given vector anti-clockwise
inline vector invTransform(const vector& v) const; inline vector invTransform(const vector& v) const;
//- Rotate the given quaternion (and normalize) //- Rotate the given quaternion (and normalise)
inline quaternion transform(const quaternion& q) const; inline quaternion transform(const quaternion& q) const;
//- Rotate the given quaternion anti-clockwise (and normalize) //- Rotate the given quaternion anti-clockwise (and normalise)
inline quaternion invTransform(const quaternion& q) const; inline quaternion invTransform(const quaternion& q) const;
@ -242,8 +241,27 @@ public:
//- Change vector portion only //- Change vector portion only
inline void operator=(const vector& v); inline void operator=(const vector& v);
//- Assign scalar and vector to zero
inline void operator=(const Foam::zero);
inline void operator*=(const scalar s); inline void operator*=(const scalar s);
inline void operator/=(const scalar s); inline void operator/=(const scalar s);
// Housekeeping
//- Inplace normalise the quaternion by its magnitude
FOAM_DEPRECATED_FOR(2022-04, "normalise() method")
void normalize() { this->normalise(); }
//- Return the quaternion normalised by its magnitude
FOAM_DEPRECATED_FOR(2022-04, "Use Foam::normalised() function")
quaternion normalized() const
{
quaternion q(*this);
q.normalise();
return q;
}
}; };
@ -264,8 +282,12 @@ inline scalar mag(const quaternion& q);
//- Return the conjugate of the given quaternion //- Return the conjugate of the given quaternion
inline quaternion conjugate(const quaternion& q); inline quaternion conjugate(const quaternion& q);
//- Return the normalized (unit) quaternion of the given quaternion //- Return the normalised (unit) quaternion of the given quaternion
inline quaternion normalize(const quaternion& q); inline quaternion normalised(const quaternion& q);
//- Return the normalised (unit) quaternion of the given quaternion
FOAM_DEPRECATED_FOR(2022-04, "Use Foam::normalised() function")
inline quaternion normalize(const quaternion& q) { return Foam::normalised(q); }
//- Return the inverse of the given quaternion //- Return the inverse of the given quaternion
inline quaternion inv(const quaternion& q); inline quaternion inv(const quaternion& q);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2020 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -45,7 +45,7 @@ inline Foam::quaternion::quaternion(const scalar w, const vector& v)
inline Foam::quaternion::quaternion(const vector& d, const scalar theta) inline Foam::quaternion::quaternion(const vector& d, const scalar theta)
: :
w_(cos(0.5*theta)), w_(cos(0.5*theta)),
v_((sin(0.5*theta)/mag(d))*d) v_(sin(0.5*theta)*Foam::normalised(d))
{} {}
@ -53,19 +53,19 @@ inline Foam::quaternion::quaternion
( (
const vector& d, const vector& d,
const scalar cosTheta, const scalar cosTheta,
const bool normalized const bool isNormalised
) )
{ {
scalar cosHalfTheta2 = 0.5*(cosTheta + 1); const scalar cosHalfTheta2 = 0.5*(cosTheta + 1);
w_ = sqrt(cosHalfTheta2); w_ = sqrt(cosHalfTheta2);
if (normalized) if (isNormalised)
{ {
v_ = sqrt(1 - cosHalfTheta2)*d; v_ = sqrt(1 - cosHalfTheta2)*d;
} }
else else
{ {
v_ = (sqrt(1 - cosHalfTheta2)/mag(d))*d; v_ = sqrt(1 - cosHalfTheta2)*Foam::normalised(d);
} }
} }
@ -282,39 +282,43 @@ inline Foam::quaternion::quaternion
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::scalar Foam::quaternion::w() const inline Foam::scalar Foam::quaternion::w() const noexcept
{ {
return w_; return w_;
} }
inline const Foam::vector& Foam::quaternion::v() const inline const Foam::vector& Foam::quaternion::v() const noexcept
{ {
return v_; return v_;
} }
inline Foam::scalar& Foam::quaternion::w() inline Foam::scalar& Foam::quaternion::w() noexcept
{ {
return w_; return w_;
} }
inline Foam::vector& Foam::quaternion::v() inline Foam::vector& Foam::quaternion::v() noexcept
{ {
return v_; return v_;
} }
inline Foam::quaternion Foam::quaternion::normalized() const inline Foam::quaternion& Foam::quaternion::normalise()
{ {
return *this/mag(*this); const scalar s(Foam::mag(*this));
if (s < ROOTVSMALL)
{
*this = Zero;
} }
else
inline void Foam::quaternion::normalize()
{ {
operator/=(mag(*this)); *this /= s;
}
return *this;
} }
@ -338,7 +342,7 @@ inline Foam::vector Foam::quaternion::invTransform(const vector& u) const
inline Foam::quaternion Foam::quaternion::transform(const quaternion& q) const inline Foam::quaternion Foam::quaternion::transform(const quaternion& q) const
{ {
return Foam::normalize((*this)*q); return Foam::normalised((*this)*q);
} }
@ -347,7 +351,7 @@ inline Foam::quaternion Foam::quaternion::invTransform
const quaternion& q const quaternion& q
) const ) const
{ {
return Foam::normalize(conjugate(*this)*q); return Foam::normalised(conjugate(*this)*q);
} }
@ -618,6 +622,13 @@ inline void Foam::quaternion::operator=(const vector& v)
} }
inline void Foam::quaternion::operator=(const Foam::zero)
{
w_ = 0;
v_ = Zero;
}
inline void Foam::quaternion::operator*=(const scalar s) inline void Foam::quaternion::operator*=(const scalar s)
{ {
w_ *= s; w_ *= s;
@ -653,14 +664,31 @@ inline Foam::quaternion Foam::conjugate(const quaternion& q)
inline Foam::quaternion Foam::inv(const quaternion& q) inline Foam::quaternion Foam::inv(const quaternion& q)
{ {
scalar magSqrq = magSqr(q); const scalar s(Foam::magSqr(q));
return quaternion(q.w()/magSqrq, -q.v()/magSqrq);
if (s < VSMALL)
{
return Zero;
}
else
{
return quaternion(q.w()/s, -q.v()/s);
}
} }
inline Foam::quaternion Foam::normalize(const quaternion& q) inline Foam::quaternion Foam::normalised(const quaternion& q)
{ {
return q/mag(q); const scalar s(Foam::mag(q));
if (s < ROOTVSMALL)
{
return Zero;
}
else
{
return q/s;
}
} }

View File

@ -94,7 +94,7 @@ Foam::septernion Foam::average
} }
} }
sa.r().normalize(); sa.r().normalise();
return sa; return sa;
} }

View File

@ -99,7 +99,7 @@ Foam::triad::triad(const quaternion& q)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::triad::orthogonalize() void Foam::triad::orthogonalise()
{ {
// Hack for 2D z-slab cases // Hack for 2D z-slab cases
// if (!set(2)) // if (!set(2))

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -40,8 +40,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef triad_H #ifndef Foam_triad_H
#define triad_H #define Foam_triad_H
#include "vector.H" #include "vector.H"
#include "tensor.H" #include "tensor.H"
@ -70,7 +70,7 @@ public:
// Constructors // Constructors
//- Construct null //- Default construct
inline triad(); inline triad();
//- Construct from components //- Construct from components
@ -112,11 +112,12 @@ public:
//- Return the vector orthogonal to the two provided //- Return the vector orthogonal to the two provided
static inline vector orthogonal(const vector& v1, const vector& v2); static inline vector orthogonal(const vector& v1, const vector& v2);
//- Orthogonalize this triad so that it is ortho-normal //- Inplace orthogonalise so that it is ortho-normal
void orthogonalize(); void orthogonalise();
//- Normalize each set axis vector to have a unit magnitude //- Normalise each set axis vector to have a unit magnitude
void normalize(); // Uses vector::normalise with handling of small magnitudes.
void normalise();
//- Align this triad with the given vector v //- Align this triad with the given vector v
// by rotating the most aligned axis to be coincident with v // by rotating the most aligned axis to be coincident with v
@ -151,7 +152,7 @@ public:
inline void operator=(const tensor& t); inline void operator=(const tensor& t);
//- Add the triad t2 to this triad //- Add the triad t2 to this triad
// without normalizing or orthogonalizing // without normalising or orthogonalising
void operator+=(const triad& t2); void operator+=(const triad& t2);
@ -159,6 +160,15 @@ public:
friend Istream& operator>>(Istream&, triad&); friend Istream& operator>>(Istream&, triad&);
friend Ostream& operator<<(Ostream&, const triad&); friend Ostream& operator<<(Ostream&, const triad&);
// Housekeeping
//- Same as orthogonalise
void orthogonalize() { this->orthogonalise(); }
//- Same as normalise
void normalize() { this->normalise(); }
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -117,11 +117,11 @@ inline Foam::vector Foam::triad::orthogonal
} }
inline void Foam::triad::normalize() inline void Foam::triad::normalise()
{ {
if (set(0)) operator[](0) /= mag(operator[](0)); if (set(0)) (*this)[0].normalise();
if (set(1)) operator[](1) /= mag(operator[](1)); if (set(1)) (*this)[1].normalise();
if (set(2)) operator[](2) /= mag(operator[](2)); if (set(2)) (*this)[2].normalise();
} }

View File

@ -78,8 +78,9 @@ void Foam::RBD::rigidBodySolver::correctQuaternionJoints()
// Transform the previous time unit quaternion // Transform the previous time unit quaternion
quaternion quat quaternion quat
( (
normalize(model_.joints()[i].unitQuaternion(q0())*dQuat) model_.joints()[i].unitQuaternion(q0())*dQuat
); );
quat.normalise();
// Update the joint unit quaternion // Update the joint unit quaternion
model_.joints()[i].unitQuaternion(quat, q()); model_.joints()[i].unitQuaternion(quat, q());