ENH: define transform(symmTensor, int/float) as no-op

- avoids implicit promotion of label to scalar for no-op,
  or alternatively promotion of symmTensor to tensor for no-op
  (ie, ambiguous).

- fix incorrect transform(.., symmTensor, ...) declarations.
This commit is contained in:
Mark Olesen
2023-01-13 18:15:13 +01:00
parent 0fa129e83c
commit a50d32b587
11 changed files with 271 additions and 175 deletions

View File

@ -36,8 +36,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef transformFieldField_H
#define transformFieldField_H
#ifndef Foam_transformFieldField_H
#define Foam_transformFieldField_H
#include "transform.H"
#include "tensorFieldField.H"

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,132 +29,130 @@ License
#include "symmTransformField.H"
#include "FieldM.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class Type>
void transform
void Foam::transform
(
Field<Type>& rtf,
const symmTensorField& trf,
const Field<Type>& tf
Field<Type>& result,
const symmTensor& rot,
const Field<Type>& fld
)
{
if (trf.size() == 1)
{
return transform(rtf, trf[0], tf);
TFOR_ALL_F_OP_FUNC_S_F
(
Type, result, =, transform, symmTensor, rot, Type, fld
);
}
else
template<class Type>
void Foam::transform
(
Field<Type>& result,
const symmTensorField& rot,
const Field<Type>& fld
)
{
if (rot.size() == 1)
{
return transform(result, rot.front(), fld);
}
TFOR_ALL_F_OP_FUNC_F_F
(
Type, rtf, =, transform, symmTensor, trf, Type, tf
)
}
Type, result, =, transform, symmTensor, rot, Type, fld
);
}
template<class Type>
tmp<Field<Type>> transform
Foam::tmp<Foam::Field<Type>>
Foam::transform
(
const symmTensorField& trf,
const Field<Type>& tf
const symmTensorField& rot,
const Field<Type>& fld
)
{
auto tresult = tmp<Field<Type>>::New(tf.size());
transform(tresult.ref(), trf, tf);
auto tresult = tmp<Field<Type>>::New(fld.size());
transform(tresult.ref(), rot, fld);
return tresult;
}
template<class Type>
tmp<Field<Type>> transform
Foam::tmp<Foam::Field<Type>>
Foam::transform
(
const symmTensorField& trf,
const tmp<Field<Type>>& ttf
const symmTensorField& rot,
const tmp<Field<Type>>& tfld
)
{
tmp<Field<Type>> tresult = New(ttf);
transform(tresult.ref(), trf, ttf());
ttf.clear();
tmp<Field<Type>> tresult = New(tfld);
transform(tresult.ref(), rot, tfld());
tfld.clear();
return tresult;
}
template<class Type>
tmp<Field<Type>> transform
Foam::tmp<Foam::Field<Type>>
Foam::transform
(
const tmp<symmTensorField>& ttrf,
const Field<Type>& tf
const tmp<symmTensorField>& trot,
const Field<Type>& fld
)
{
auto tresult = tmp<Field<Type>>::New(tf.size());
transform(tresult.ref(), ttrf(), tf);
ttrf.clear();
auto tresult = tmp<Field<Type>>::New(fld.size());
transform(tresult.ref(), trot(), fld);
trot.clear();
return tresult;
}
template<class Type>
tmp<Field<Type>> transform
Foam::tmp<Foam::Field<Type>>
Foam::transform
(
const tmp<symmTensorField>& ttrf,
const tmp<Field<Type>>& ttf
const tmp<symmTensorField>& trot,
const tmp<Field<Type>>& tfld
)
{
tmp<Field<Type>> tresult = New(ttf);
transform(tresult.ref(), ttrf(), ttf());
ttf.clear();
ttrf.clear();
tmp<Field<Type>> tresult = New(tfld);
transform(tresult.ref(), trot(), tfld());
trot.clear();
tfld.clear();
return tresult;
}
template<class Type>
void transform
Foam::tmp<Foam::Field<Type>>
Foam::transform
(
Field<Type>& rtf,
const symmTensor& t,
const Field<Type>& tf
const symmTensor& rot,
const Field<Type>& fld
)
{
TFOR_ALL_F_OP_FUNC_S_F(Type, rtf, =, transform, tensor, t, Type, tf)
}
template<class Type>
tmp<Field<Type>> transform
(
const symmTensor& t,
const Field<Type>& tf
)
{
auto tresult = tmp<Field<Type>>::New(tf.size());
transform(tresult.ref(), t, tf);
auto tresult = tmp<Field<Type>>::New(fld.size());
transform(tresult.ref(), rot, fld);
return tresult;
}
template<class Type>
tmp<Field<Type>> transform
Foam::tmp<Foam::Field<Type>>
Foam::transform
(
const symmTensor& t,
const tmp<Field<Type>>& ttf
const symmTensor& rot,
const tmp<Field<Type>>& tfld
)
{
tmp<Field<Type>> tresult = New(ttf);
transform(tresult.ref(), t, ttf());
ttf.clear();
tmp<Field<Type>> tresult = New(tfld);
transform(tresult.ref(), rot, tfld());
tfld.clear();
return tresult;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -34,8 +35,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef symmTransformField_H
#define symmTransformField_H
#ifndef Foam_symmTransformField_H
#define Foam_symmTransformField_H
#include "symmTransform.H"
#include "symmTensorField.H"
@ -48,73 +49,96 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
void transform(Field<Type>&, const symmTensorField&, const Field<Type>&);
// transform()
template<class Type>
tmp<Field<Type>> transform(const symmTensorField&, const Field<Type>&);
void transform
(
Field<Type>& result,
const symmTensor& rot,
const Field<Type>& fld
);
template<class Type>
tmp<Field<Type>> transform(const symmTensorField&, const tmp<Field<Type>>&);
void transform
(
Field<Type>& result,
const symmTensorField& rot,
const Field<Type>& fld
);
template<class Type>
tmp<Field<Type>> transform(const tmp<symmTensorField>&, const Field<Type>&);
template<class Type>
tmp<Field<Type>> transform
(
const tmp<symmTensorField>&,
const tmp<Field<Type>>&
const symmTensorField& rot,
const Field<Type>& fld
);
template<class Type>
tmp<Field<Type>> transform
(
const symmTensorField& rot,
const tmp<Field<Type>>& tfld
);
template<class Type>
tmp<Field<Type>> transform
(
const tmp<symmTensorField>& trot,
const Field<Type>& tfld
);
template<class Type>
tmp<Field<Type>> transform
(
const tmp<symmTensorField>& trot,
const tmp<Field<Type>>& tfld
);
template<class Type>
void transform(Field<Type>&, const tensor&, const Field<Type>&);
tmp<Field<Type>> transform
(
const symmTensor& rot,
const Field<Type>& fld
);
template<class Type>
tmp<Field<Type>> transform(const tensor&, const Field<Type>&);
template<class Type>
tmp<Field<Type>> transform(const tensor&, const tmp<Field<Type>>&);
template<>
tmp<Field<sphericalTensor>> transformFieldMask<sphericalTensor>
tmp<Field<Type>> transform
(
const symmTensorField&
);
template<>
tmp<Field<sphericalTensor>> transformFieldMask<sphericalTensor>
(
const tmp<symmTensorField>&
const symmTensor& rot,
const tmp<Field<Type>>& tfld
);
template<>
tmp<Field<symmTensor>> transformFieldMask<symmTensor>
(
const symmTensorField&
);
// Specializations
template<>
tmp<Field<symmTensor>> transformFieldMask<symmTensor>
(
const tmp<symmTensorField>&
);
tmp<Field<sphericalTensor>>
transformFieldMask<sphericalTensor>(const symmTensorField&);
template<>
tmp<Field<sphericalTensor>>
transformFieldMask<sphericalTensor>(const tmp<symmTensorField>&);
template<>
tmp<Field<tensor>> transformFieldMask<tensor>
(
const symmTensorField&
);
tmp<Field<symmTensor>>
transformFieldMask<symmTensor>(const symmTensorField&);
template<>
tmp<Field<tensor>> transformFieldMask<tensor>
(
const tmp<symmTensorField>&
);
tmp<Field<symmTensor>>
transformFieldMask<symmTensor>(const tmp<symmTensorField>&);
template<>
tmp<Field<tensor>>
transformFieldMask<tensor>(const symmTensorField&);
template<>
tmp<Field<tensor>>
transformFieldMask<tensor>(const tmp<symmTensorField>&);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -35,8 +35,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef transformField_H
#define transformField_H
#ifndef Foam_transformField_H
#define Foam_transformField_H
#include "transform.H"
#include "quaternion.H"
@ -177,6 +177,7 @@ tmp<Field<Type>> invTransform
);
// transformFieldMask()
template<class Type1, class Type2>
tmp<Field<Type1>> transformFieldMask(const Field<Type2>& fld);

View File

@ -56,7 +56,7 @@ void Foam::transform
{
if (rot.size() == 1)
{
return transform(result, rot.first(), fld);
return transform(result, rot.front(), fld);
}
TFOR_ALL_F_OP_FUNC_F_F
@ -180,7 +180,7 @@ void Foam::invTransform
{
if (rot.size() == 1)
{
return invTransform(result, rot.first(), fld);
return invTransform(result, rot.front(), fld);
}
TFOR_ALL_F_OP_FUNC_F_F

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,9 +37,12 @@ Foam::List<T> Foam::transform
const UList<T>& field
)
{
List<T> result(field.size());
const label loopLen = field.size();
forAll(field, i)
List<T> result(loopLen);
/* pragmas... */
for (label i = 0; i < loopLen; ++i)
{
result[i] = transform(rotTensor, field[i]);
}
@ -51,7 +54,10 @@ Foam::List<T> Foam::transform
template<class T>
void Foam::transformList(const tensor& rotTensor, UList<T>& field)
{
forAll(field, i)
const label loopLen = field.size();
/* pragmas... */
for (label i = 0; i < loopLen; ++i)
{
field[i] = transform(rotTensor, field[i]);
}
@ -63,11 +69,14 @@ void Foam::transformList(const tensorField& rotTensor, UList<T>& field)
{
if (rotTensor.size() == 1)
{
transformList(rotTensor[0], field);
transformList(rotTensor.front(), field);
}
else if (rotTensor.size() == field.size())
{
forAll(field, i)
const label loopLen = field.size();
/* pragmas... */
for (label i = 0; i < loopLen; ++i)
{
field[i] = transform(rotTensor[i], field[i]);
}
@ -98,7 +107,7 @@ void Foam::transformList(const tensorField& rotTensor, Map<T>& field)
{
if (rotTensor.size() == 1)
{
transformList(rotTensor[0], field);
transformList(rotTensor.front(), field);
}
else
{
@ -126,7 +135,7 @@ void Foam::transformList(const tensorField& rotTensor, EdgeMap<T>& field)
{
if (rotTensor.size() == 1)
{
transformList(rotTensor[0], field);
transformList(rotTensor.front(), field);
}
else
{

View File

@ -35,8 +35,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef transformList_H
#define transformList_H
#ifndef Foam_transformList_H
#define Foam_transformList_H
#include "transform.H"
#include "List.H"
@ -67,7 +67,7 @@ void transformList(const tensorField& rotTensor, UList<T>& field);
template<class T>
void transformList(const tensor& rotTensor, Map<T>& field);
//- Inplace transform a Map of elements using one tensor per element.
//- Inplace transform a Map of elements.
// Using multiple tensors is ill-defined (Fatal).
template<class T>
void transformList(const tensorField& rotTensor, Map<T>& field);
@ -77,7 +77,7 @@ void transformList(const tensorField& rotTensor, Map<T>& field);
template<class T>
void transformList(const tensor& rotTensor, EdgeMap<T>& field);
//- Inplace transform a Map of elements using one tensor per element.
//- Inplace transform a Map of elements.
// Using multiple tensors is ill-defined (Fatal).
template<class T>
void transformList(const tensorField& rotTensor, EdgeMap<T>& field);

View File

@ -35,8 +35,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef transformGeometricField_H
#define transformGeometricField_H
#ifndef Foam_transformGeometricField_H
#define Foam_transformGeometricField_H
#include "transform.H"
#include "GeometricField.H"

View File

@ -274,6 +274,7 @@ inline const complex& sum(const complex& c)
template<class Cmpt> class Tensor;
//- No-op rotational transform for complex
inline complex transform(const Tensor<scalar>&, const complex c)
{
return c;

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,8 +32,8 @@ Description
\*---------------------------------------------------------------------------*/
#ifndef symmTransform_H
#define symmTransform_H
#ifndef Foam_symmTransform_H
#define Foam_symmTransform_H
#include "transform.H"
@ -43,57 +44,84 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline scalar transform(const symmTensor&, const scalar s)
//- No-op rotational transform for base types
template<class T>
constexpr typename std::enable_if<std::is_arithmetic<T>::value, T>::type
transform(const symmTensor&, const T val)
{
return s;
return val;
}
//- No-op rotational transform for spherical tensor
template<class Cmpt>
inline Vector<Cmpt> transform(const symmTensor& stt, const Vector<Cmpt>& v)
inline SphericalTensor<Cmpt> transform
(
const symmTensor&,
const SphericalTensor<Cmpt>& val
)
{
return stt & v;
return val;
}
//- Use rotational tensor to transform a vector
// Same as (rot & v)
template<class Cmpt>
inline Vector<Cmpt> transform(const symmTensor& tt, const Vector<Cmpt>& v)
{
return tt & v;
}
//- Use rotational tensor to transform a tensor.
// Same as (rot & input & rot.T())
template<class Cmpt>
inline Tensor<Cmpt> transform(const symmTensor& stt, const Tensor<Cmpt>& t)
{
//return stt & t & stt.T();
return Tensor<Cmpt>
(
// xx:
(stt.xx()*t.xx() + stt.xy()*t.yx() + stt.xz()*t.zx())*stt.xx()
+ (stt.xx()*t.xy() + stt.xy()*t.yy() + stt.xz()*t.zy())*stt.xy()
+ (stt.xx()*t.xz() + stt.xy()*t.yz() + stt.xz()*t.zz())*stt.xz(),
// xy:
(stt.xx()*t.xx() + stt.xy()*t.yx() + stt.xz()*t.zx())*stt.xy()
+ (stt.xx()*t.xy() + stt.xy()*t.yy() + stt.xz()*t.zy())*stt.yy()
+ (stt.xx()*t.xz() + stt.xy()*t.yz() + stt.xz()*t.zz())*stt.yz(),
// xz:
(stt.xx()*t.xx() + stt.xy()*t.yx() + stt.xz()*t.zx())*stt.xz()
+ (stt.xx()*t.xy() + stt.xy()*t.yy() + stt.xz()*t.zy())*stt.yz()
+ (stt.xx()*t.xz() + stt.xy()*t.yz() + stt.xz()*t.zz())*stt.zz(),
// yx:
(stt.xy()*t.xx() + stt.yy()*t.yx() + stt.yz()*t.zx())*stt.xx()
+ (stt.xy()*t.xy() + stt.yy()*t.yy() + stt.yz()*t.zy())*stt.xy()
+ (stt.xy()*t.xz() + stt.yy()*t.yz() + stt.yz()*t.zz())*stt.xz(),
// yy:
(stt.xy()*t.xx() + stt.yy()*t.yx() + stt.yz()*t.zx())*stt.xy()
+ (stt.xy()*t.xy() + stt.yy()*t.yy() + stt.yz()*t.zy())*stt.yy()
+ (stt.xy()*t.xz() + stt.yy()*t.yz() + stt.yz()*t.zz())*stt.yz(),
// yz:
(stt.xy()*t.xx() + stt.yy()*t.yx() + stt.yz()*t.zx())*stt.xz()
+ (stt.xy()*t.xy() + stt.yy()*t.yy() + stt.yz()*t.zy())*stt.yz()
+ (stt.xy()*t.xz() + stt.yy()*t.yz() + stt.yz()*t.zz())*stt.zz(),
// zx:
(stt.xz()*t.xx() + stt.yz()*t.yx() + stt.zz()*t.zx())*stt.xx()
+ (stt.xz()*t.xy() + stt.yz()*t.yy() + stt.zz()*t.zy())*stt.xy()
+ (stt.xz()*t.xz() + stt.yz()*t.yz() + stt.zz()*t.zz())*stt.xz(),
// zy:
(stt.xz()*t.xx() + stt.yz()*t.yx() + stt.zz()*t.zx())*stt.xy()
+ (stt.xz()*t.xy() + stt.yz()*t.yy() + stt.zz()*t.zy())*stt.yy()
+ (stt.xz()*t.xz() + stt.yz()*t.yz() + stt.zz()*t.zz())*stt.yz(),
// zz:
(stt.xz()*t.xx() + stt.yz()*t.yx() + stt.zz()*t.zx())*stt.xz()
+ (stt.xz()*t.xy() + stt.yz()*t.yy() + stt.zz()*t.zy())*stt.yz()
+ (stt.xz()*t.xz() + stt.yz()*t.yz() + stt.zz()*t.zz())*stt.zz()
@ -101,17 +129,8 @@ inline Tensor<Cmpt> transform(const symmTensor& stt, const Tensor<Cmpt>& t)
}
template<class Cmpt>
inline SphericalTensor<Cmpt> transform
(
const symmTensor& stt,
const SphericalTensor<Cmpt>& st
)
{
return st;
}
//- Use rotational tensor to transform a symmTensor
// Same as (rot & input & rot.T())
template<class Cmpt>
inline SymmTensor<Cmpt> transform
(
@ -121,26 +140,32 @@ inline SymmTensor<Cmpt> transform
{
return SymmTensor<Cmpt>
(
// xx:
(stt.xx()*st.xx() + stt.xy()*st.xy() + stt.xz()*st.xz())*stt.xx()
+ (stt.xx()*st.xy() + stt.xy()*st.yy() + stt.xz()*st.yz())*stt.xy()
+ (stt.xx()*st.xz() + stt.xy()*st.yz() + stt.xz()*st.zz())*stt.xz(),
// xy:
(stt.xx()*st.xx() + stt.xy()*st.xy() + stt.xz()*st.xz())*stt.xy()
+ (stt.xx()*st.xy() + stt.xy()*st.yy() + stt.xz()*st.yz())*stt.yy()
+ (stt.xx()*st.xz() + stt.xy()*st.yz() + stt.xz()*st.zz())*stt.yz(),
// xz:
(stt.xx()*st.xx() + stt.xy()*st.xy() + stt.xz()*st.xz())*stt.xz()
+ (stt.xx()*st.xy() + stt.xy()*st.yy() + stt.xz()*st.yz())*stt.yz()
+ (stt.xx()*st.xz() + stt.xy()*st.yz() + stt.xz()*st.zz())*stt.zz(),
// yy:
(stt.xy()*st.xx() + stt.yy()*st.xy() + stt.yz()*st.xz())*stt.xy()
+ (stt.xy()*st.xy() + stt.yy()*st.yy() + stt.yz()*st.yz())*stt.yy()
+ (stt.xy()*st.xz() + stt.yy()*st.yz() + stt.yz()*st.zz())*stt.yz(),
// yz:
(stt.xy()*st.xx() + stt.yy()*st.xy() + stt.yz()*st.xz())*stt.xz()
+ (stt.xy()*st.xy() + stt.yy()*st.yy() + stt.yz()*st.yz())*stt.yz()
+ (stt.xy()*st.xz() + stt.yy()*st.yz() + stt.yz()*st.zz())*stt.zz(),
// zz:
(stt.xz()*st.xx() + stt.yz()*st.xy() + stt.zz()*st.xz())*stt.xz()
+ (stt.xz()*st.xy() + stt.yz()*st.yy() + stt.zz()*st.yz())*stt.yz()
+ (stt.xz()*st.xz() + stt.yz()*st.yz() + stt.zz()*st.zz())*stt.zz()
@ -148,6 +173,8 @@ inline SymmTensor<Cmpt> transform
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<>
inline sphericalTensor transformMask<sphericalTensor>(const symmTensor& st)
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -146,6 +146,8 @@ inline tensor Ra(const vector& a, const scalar omega)
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- No-op rotational transform for base types
template<class T>
constexpr typename std::enable_if<std::is_arithmetic<T>::value, T>::type
@ -154,6 +156,19 @@ transform(const tensor&, const T val)
return val;
}
//- No-op rotational transform for spherical tensor
template<class Cmpt>
inline SphericalTensor<Cmpt> transform
(
const tensor&,
const SphericalTensor<Cmpt>& val
)
{
return val;
}
//- No-op inverse rotational transform for base types
template<class T>
constexpr typename std::enable_if<std::is_arithmetic<T>::value, T>::type
@ -163,6 +178,18 @@ invTransform(const tensor&, const T val)
}
//- No-op inverse rotational transform for spherical tensor
template<class Cmpt>
inline SphericalTensor<Cmpt> invTransform
(
const tensor&,
const SphericalTensor<Cmpt>& val
)
{
return val;
}
//- Use rotational tensor to transform a vector.
// Same as (rot & v)
template<class Cmpt>
@ -188,38 +215,47 @@ inline Tensor<Cmpt> transform(const tensor& tt, const Tensor<Cmpt>& t)
{
return Tensor<Cmpt>
(
// xx:
(tt.xx()*t.xx() + tt.xy()*t.yx() + tt.xz()*t.zx())*tt.xx()
+ (tt.xx()*t.xy() + tt.xy()*t.yy() + tt.xz()*t.zy())*tt.xy()
+ (tt.xx()*t.xz() + tt.xy()*t.yz() + tt.xz()*t.zz())*tt.xz(),
// xy:
(tt.xx()*t.xx() + tt.xy()*t.yx() + tt.xz()*t.zx())*tt.yx()
+ (tt.xx()*t.xy() + tt.xy()*t.yy() + tt.xz()*t.zy())*tt.yy()
+ (tt.xx()*t.xz() + tt.xy()*t.yz() + tt.xz()*t.zz())*tt.yz(),
// xz:
(tt.xx()*t.xx() + tt.xy()*t.yx() + tt.xz()*t.zx())*tt.zx()
+ (tt.xx()*t.xy() + tt.xy()*t.yy() + tt.xz()*t.zy())*tt.zy()
+ (tt.xx()*t.xz() + tt.xy()*t.yz() + tt.xz()*t.zz())*tt.zz(),
// yx:
(tt.yx()*t.xx() + tt.yy()*t.yx() + tt.yz()*t.zx())*tt.xx()
+ (tt.yx()*t.xy() + tt.yy()*t.yy() + tt.yz()*t.zy())*tt.xy()
+ (tt.yx()*t.xz() + tt.yy()*t.yz() + tt.yz()*t.zz())*tt.xz(),
// yy:
(tt.yx()*t.xx() + tt.yy()*t.yx() + tt.yz()*t.zx())*tt.yx()
+ (tt.yx()*t.xy() + tt.yy()*t.yy() + tt.yz()*t.zy())*tt.yy()
+ (tt.yx()*t.xz() + tt.yy()*t.yz() + tt.yz()*t.zz())*tt.yz(),
// yz:
(tt.yx()*t.xx() + tt.yy()*t.yx() + tt.yz()*t.zx())*tt.zx()
+ (tt.yx()*t.xy() + tt.yy()*t.yy() + tt.yz()*t.zy())*tt.zy()
+ (tt.yx()*t.xz() + tt.yy()*t.yz() + tt.yz()*t.zz())*tt.zz(),
// zx:
(tt.zx()*t.xx() + tt.zy()*t.yx() + tt.zz()*t.zx())*tt.xx()
+ (tt.zx()*t.xy() + tt.zy()*t.yy() + tt.zz()*t.zy())*tt.xy()
+ (tt.zx()*t.xz() + tt.zy()*t.yz() + tt.zz()*t.zz())*tt.xz(),
// zy:
(tt.zx()*t.xx() + tt.zy()*t.yx() + tt.zz()*t.zx())*tt.yx()
+ (tt.zx()*t.xy() + tt.zy()*t.yy() + tt.zz()*t.zy())*tt.yy()
+ (tt.zx()*t.xz() + tt.zy()*t.yz() + tt.zz()*t.zz())*tt.yz(),
// zz:
(tt.zx()*t.xx() + tt.zy()*t.yx() + tt.zz()*t.zx())*tt.zx()
+ (tt.zx()*t.xy() + tt.zy()*t.yy() + tt.zz()*t.zy())*tt.zy()
+ (tt.zx()*t.xz() + tt.zy()*t.yz() + tt.zz()*t.zz())*tt.zz()
@ -234,38 +270,47 @@ inline Tensor<Cmpt> invTransform(const tensor& tt, const Tensor<Cmpt>& t)
{
return Tensor<Cmpt>
(
// xx:
(tt.xx()*t.xx() + tt.yx()*t.yx() + tt.zx()*t.zx())*tt.xx()
+ (tt.xx()*t.xy() + tt.yx()*t.yy() + tt.zx()*t.zy())*tt.yx()
+ (tt.xx()*t.xz() + tt.yx()*t.yz() + tt.zx()*t.zz())*tt.zx(),
// xy:
(tt.xx()*t.xx() + tt.yx()*t.yx() + tt.zx()*t.zx())*tt.xy()
+ (tt.xx()*t.xy() + tt.yx()*t.yy() + tt.zx()*t.zy())*tt.yy()
+ (tt.xx()*t.xz() + tt.yx()*t.yz() + tt.zx()*t.zz())*tt.zy(),
// xz:
(tt.xx()*t.xx() + tt.yx()*t.yx() + tt.zx()*t.zx())*tt.xz()
+ (tt.xx()*t.xy() + tt.yx()*t.yy() + tt.zx()*t.zy())*tt.yz()
+ (tt.xx()*t.xz() + tt.yx()*t.yz() + tt.zx()*t.zz())*tt.zz(),
// yx:
(tt.xy()*t.xx() + tt.yy()*t.yx() + tt.zy()*t.zx())*tt.xx()
+ (tt.xy()*t.xy() + tt.yy()*t.yy() + tt.zy()*t.zy())*tt.yx()
+ (tt.xy()*t.xz() + tt.yy()*t.yz() + tt.zy()*t.zz())*tt.zx(),
// yy:
(tt.xy()*t.xx() + tt.yy()*t.yx() + tt.zy()*t.zx())*tt.xy()
+ (tt.xy()*t.xy() + tt.yy()*t.yy() + tt.zy()*t.zy())*tt.yy()
+ (tt.xy()*t.xz() + tt.yy()*t.yz() + tt.zy()*t.zz())*tt.zy(),
// yz:
(tt.xy()*t.xx() + tt.yy()*t.yx() + tt.zy()*t.zx())*tt.xz()
+ (tt.xy()*t.xy() + tt.yy()*t.yy() + tt.zy()*t.zy())*tt.yz()
+ (tt.xy()*t.xz() + tt.yy()*t.yz() + tt.zy()*t.zz())*tt.zz(),
// zx:
(tt.xz()*t.xx() + tt.yz()*t.yx() + tt.zz()*t.zx())*tt.xx()
+ (tt.xz()*t.xy() + tt.yz()*t.yy() + tt.zz()*t.zy())*tt.yx()
+ (tt.xz()*t.xz() + tt.yz()*t.yz() + tt.zz()*t.zz())*tt.zx(),
// zy:
(tt.xz()*t.xx() + tt.yz()*t.yx() + tt.zz()*t.zx())*tt.xy()
+ (tt.xz()*t.xy() + tt.yz()*t.yy() + tt.zz()*t.zy())*tt.yy()
+ (tt.xz()*t.xz() + tt.yz()*t.yz() + tt.zz()*t.zz())*tt.zy(),
// zz:
(tt.xz()*t.xx() + tt.yz()*t.yx() + tt.zz()*t.zx())*tt.xz()
+ (tt.xz()*t.xy() + tt.yz()*t.yy() + tt.zz()*t.zy())*tt.yz()
+ (tt.xz()*t.xz() + tt.yz()*t.yz() + tt.zz()*t.zz())*tt.zz()
@ -273,30 +318,6 @@ inline Tensor<Cmpt> invTransform(const tensor& tt, const Tensor<Cmpt>& t)
}
//- Use rotational tensor to transform a spherical tensor (no-op).
template<class Cmpt>
inline SphericalTensor<Cmpt> transform
(
const tensor& tt,
const SphericalTensor<Cmpt>& st
)
{
return st;
}
//- Use rotational tensor to inverse transform a spherical tensor (no-op).
template<class Cmpt>
inline SphericalTensor<Cmpt> invTransform
(
const tensor& tt,
const SphericalTensor<Cmpt>& st
)
{
return st;
}
//- Use rotational tensor to transform a symmetrical tensor.
// Same as (rot & input & rot.T())
template<class Cmpt>
@ -304,26 +325,32 @@ inline SymmTensor<Cmpt> transform(const tensor& tt, const SymmTensor<Cmpt>& st)
{
return SymmTensor<Cmpt>
(
// xx:
(tt.xx()*st.xx() + tt.xy()*st.xy() + tt.xz()*st.xz())*tt.xx()
+ (tt.xx()*st.xy() + tt.xy()*st.yy() + tt.xz()*st.yz())*tt.xy()
+ (tt.xx()*st.xz() + tt.xy()*st.yz() + tt.xz()*st.zz())*tt.xz(),
// xy:
(tt.xx()*st.xx() + tt.xy()*st.xy() + tt.xz()*st.xz())*tt.yx()
+ (tt.xx()*st.xy() + tt.xy()*st.yy() + tt.xz()*st.yz())*tt.yy()
+ (tt.xx()*st.xz() + tt.xy()*st.yz() + tt.xz()*st.zz())*tt.yz(),
// xz:
(tt.xx()*st.xx() + tt.xy()*st.xy() + tt.xz()*st.xz())*tt.zx()
+ (tt.xx()*st.xy() + tt.xy()*st.yy() + tt.xz()*st.yz())*tt.zy()
+ (tt.xx()*st.xz() + tt.xy()*st.yz() + tt.xz()*st.zz())*tt.zz(),
// yy:
(tt.yx()*st.xx() + tt.yy()*st.xy() + tt.yz()*st.xz())*tt.yx()
+ (tt.yx()*st.xy() + tt.yy()*st.yy() + tt.yz()*st.yz())*tt.yy()
+ (tt.yx()*st.xz() + tt.yy()*st.yz() + tt.yz()*st.zz())*tt.yz(),
// yz:
(tt.yx()*st.xx() + tt.yy()*st.xy() + tt.yz()*st.xz())*tt.zx()
+ (tt.yx()*st.xy() + tt.yy()*st.yy() + tt.yz()*st.yz())*tt.zy()
+ (tt.yx()*st.xz() + tt.yy()*st.yz() + tt.yz()*st.zz())*tt.zz(),
// zz:
(tt.zx()*st.xx() + tt.zy()*st.xy() + tt.zz()*st.xz())*tt.zx()
+ (tt.zx()*st.xy() + tt.zy()*st.yy() + tt.zz()*st.yz())*tt.zy()
+ (tt.zx()*st.xz() + tt.zy()*st.yz() + tt.zz()*st.zz())*tt.zz()
@ -339,26 +366,32 @@ invTransform(const tensor& tt, const SymmTensor<Cmpt>& st)
{
return SymmTensor<Cmpt>
(
// xx:
(tt.xx()*st.xx() + tt.yx()*st.xy() + tt.zx()*st.xz())*tt.xx()
+ (tt.xx()*st.xy() + tt.yx()*st.yy() + tt.zx()*st.yz())*tt.yx()
+ (tt.xx()*st.xz() + tt.yx()*st.yz() + tt.zx()*st.zz())*tt.zx(),
// xy:
(tt.xx()*st.xx() + tt.yx()*st.xy() + tt.zx()*st.xz())*tt.xy()
+ (tt.xx()*st.xy() + tt.yx()*st.yy() + tt.zx()*st.yz())*tt.yy()
+ (tt.xx()*st.xz() + tt.yx()*st.yz() + tt.zx()*st.zz())*tt.zy(),
// xz:
(tt.xx()*st.xx() + tt.yx()*st.xy() + tt.zx()*st.xz())*tt.xz()
+ (tt.xx()*st.xy() + tt.yx()*st.yy() + tt.zx()*st.yz())*tt.yz()
+ (tt.xx()*st.xz() + tt.yx()*st.yz() + tt.zx()*st.zz())*tt.zz(),
// yy:
(tt.xy()*st.xx() + tt.yy()*st.xy() + tt.zy()*st.xz())*tt.xy()
+ (tt.xy()*st.xy() + tt.yy()*st.yy() + tt.zy()*st.yz())*tt.yy()
+ (tt.xy()*st.xz() + tt.yy()*st.yz() + tt.zy()*st.zz())*tt.zy(),
// yz:
(tt.xy()*st.xx() + tt.yy()*st.xy() + tt.zy()*st.xz())*tt.xz()
+ (tt.xy()*st.xy() + tt.yy()*st.yy() + tt.zy()*st.yz())*tt.yz()
+ (tt.xy()*st.xz() + tt.yy()*st.yz() + tt.zy()*st.zz())*tt.zz(),
// zz:
(tt.xz()*st.xx() + tt.yz()*st.xy() + tt.zz()*st.xz())*tt.xz()
+ (tt.xz()*st.xy() + tt.yz()*st.yy() + tt.zz()*st.yz())*tt.yz()
+ (tt.xz()*st.xz() + tt.yz()*st.yz() + tt.zz()*st.zz())*tt.zz()
@ -366,6 +399,8 @@ invTransform(const tensor& tt, const SymmTensor<Cmpt>& st)
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type1, class Type2>
inline Type1 transformMask(const Type2& t)
{