transformer: Added bool to optimise transformations without translation

Also corrected bugs in the inverse transform function and added tmp<Field>
transform functions for efficiency.
This commit is contained in:
Henry Weller
2019-12-30 17:55:52 +00:00
parent 164ab8407b
commit f8ac6e8d1e
11 changed files with 296 additions and 158 deletions

View File

@ -53,7 +53,7 @@ Foam::label Foam::globalIndexAndTransform::matchTransform
{
const transformer& refTransform = refTransforms[i];
scalar maxVectorMag = sqrt
const scalar maxVectorMag = sqrt
(
max(magSqr(testTransform.t()), magSqr(refTransform.t()))
);
@ -74,7 +74,7 @@ Foam::label Foam::globalIndexAndTransform::matchTransform
scalar tensorDiff = 0;
if (refTransform.hasR() || testTransform.hasR())
if (refTransform.rotates() || testTransform.rotates())
{
tensorDiff =
mag(refTransform.R() - testTransform.R())
@ -103,7 +103,7 @@ Foam::label Foam::globalIndexAndTransform::matchTransform
tensorDiff = 0;
if (refTransform.hasR() || testTransform.hasR())
if (refTransform.rotates() || testTransform.rotates())
{
tensorDiff =
mag(refTransform.R() - testTransform.R().T())
@ -234,7 +234,7 @@ void Foam::globalIndexAndTransform::determineTransforms()
{
const transformer& transform = procTransVecs[pSVI];
if (mag(transform.t()) > small || transform.hasR())
if (transform.translates() || transform.rotates())
{
if
(
@ -448,7 +448,7 @@ Foam::globalIndexAndTransform::globalIndexAndTransform(const polyMesh& mesh)
{
Info<< '\t' << i << '\t';
const transformer& trafo = transforms_[i];
if (trafo.hasR())
if (trafo.rotates())
{
Info<< trafo.t() << '\t' << trafo.R();
}
@ -481,7 +481,7 @@ Foam::globalIndexAndTransform::globalIndexAndTransform(const polyMesh& mesh)
{
Info<< '\t' << i << '\t';
const transformer& trafo = transformPermutations_[i];
if (trafo.hasR())
if (trafo.rotates())
{
Info<< trafo.t() << '\t' << trafo.R();
}

View File

@ -188,7 +188,7 @@ Foam::label Foam::globalIndexAndTransform::addToTransformIndex
bool antiCyclic = false;
const transformer& vt = transforms_[matchTransI];
if (mag(vt.t()) < small && vt.hasR())
if (!vt.translates() && vt.rotates())
{
const tensor& R = vt.R();
scalar sumDiag = tr(R);

View File

@ -35,15 +35,16 @@ const char* const Foam::transformer::typeName =
const Foam::transformer Foam::transformer::zero
(
Zero,
false,
Zero,
false
);
const Foam::transformer Foam::transformer::I
(
Zero,
sphericalTensor::I,
false,
tensor::I,
false
);
@ -76,6 +77,18 @@ Foam::tmp<Foam::Field<bool>> Foam::transformer::transform
{
return fld;
}
template<>
Foam::tmp<Foam::Field<bool>> Foam::transformer::transform
(
const tmp<Field<bool>>& tfld
) const
{
return tfld;
}
template<>
Foam::tmp<Foam::Field<Foam::label>> Foam::transformer::transform
(
@ -84,6 +97,18 @@ Foam::tmp<Foam::Field<Foam::label>> Foam::transformer::transform
{
return fld;
}
template<>
Foam::tmp<Foam::Field<Foam::label>> Foam::transformer::transform
(
const tmp<Field<label>>& tfld
) const
{
return tfld;
}
template<>
Foam::tmp<Foam::Field<Foam::scalar>> Foam::transformer::transform
(
@ -94,6 +119,16 @@ Foam::tmp<Foam::Field<Foam::scalar>> Foam::transformer::transform
}
template<>
Foam::tmp<Foam::Field<Foam::scalar>> Foam::transformer::transform
(
const tmp<Field<scalar>>& tfld
) const
{
return tfld;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, transformer& tr)
@ -101,7 +136,7 @@ Foam::Istream& Foam::operator>>(Istream& is, transformer& tr)
// Read beginning of transformer
is.readBegin("transformer");
is >> tr.t_ >> tr.R_ >> tr.hasR_;
is >> tr.t_ >> tr.R_ >> tr.rotates_;
// Read end of transformer
is.readEnd("transformer");
@ -116,7 +151,7 @@ Foam::Istream& Foam::operator>>(Istream& is, transformer& tr)
Foam::Ostream& Foam::operator<<(Ostream& os, const transformer& tr)
{
os << token::BEGIN_LIST
<< tr.t() << token::SPACE << tr.R() << token::SPACE << tr.hasR()
<< tr.t() << token::SPACE << tr.R() << token::SPACE << tr.rotates()
<< token::END_LIST;
return os;

View File

@ -67,13 +67,14 @@ class transformer
//- Translation vector
vector t_;
//- True if the translation vector is non-zero
bool translates_;
//- Rotation tensor
tensor R_;
//- Recording if the transform has non-identity transform to
// allow its calculation to be skipped, which is the majority
// of the expected cases
bool hasR_;
//- True if the rotation tensor is non-I
bool rotates_;
public:
@ -92,15 +93,6 @@ public:
//- Construct null
inline transformer();
//- Construct given a translation vector, rotation tensor and
// hasR bool
inline transformer
(
const vector& t,
const tensor& R,
bool hasR = true
);
//- Construct a pure translation transformer given a
// translation vector
inline explicit transformer(const vector& t);
@ -109,6 +101,18 @@ public:
// rotation tensor
inline explicit transformer(const tensor& R);
//- Construct given a translation vector and rotation tensor
inline transformer(const vector& t, const tensor& R);
//- Construct given a translation vector and rotation tensor
inline transformer
(
const vector& t,
const bool translates,
const tensor& R,
const bool rotates
);
//- Construct from Istream
transformer(Istream&);
@ -117,17 +121,28 @@ public:
// Access
//- Return the translation vector
inline const vector& t() const;
//- Return true is the translation vector is non-zero
inline bool translates() const;
//- Return the rotation tensor
inline const tensor& R() const;
inline bool hasR() const;
//- Return true if the rotation tensor is non-I
inline bool rotates() const;
//- Return true if the transformer either translates or rotates
inline bool transforms() const;
// Edit
//- Return non-const access to the translation vector
inline vector& t();
//- Return non-const access to the rotation tensor
inline tensor& R();
@ -137,13 +152,19 @@ public:
inline vector transformPosition(const vector& v) const;
//- Transform the given pointField
inline pointField transformPosition(const pointField& pts) const;
inline tmp<pointField> transformPosition
(
const pointField& pts
) const;
//- Inverse transform the given position
inline vector invTransformPosition(const vector& v) const;
//- Inverse transform the given pointField
inline pointField invTransformPosition(const pointField& pts) const;
inline tmp<pointField> invTransformPosition
(
const pointField& pts
) const;
//- Transform the given type
template<class Type>
@ -153,6 +174,10 @@ public:
template<class Type>
tmp<Field<Type>> transform(const Field<Type>&) const;
//- Transform the given field
template<class Type>
tmp<Field<Type>> transform(const tmp<Field<Type>>&) const;
//- Inverse transform the given type
template<class Type>
Type invTransform(const Type&) const;
@ -161,6 +186,10 @@ public:
template<class Type>
tmp<Field<Type>> invTransform(const Field<Type>&) const;
//- Inverse transform the given field
template<class Type>
tmp<Field<Type>> invTransform(const tmp<Field<Type>>&) const;
// Member Operators
@ -187,68 +216,49 @@ public:
//- Return the inverse of the given transformer
inline transformer inv(const transformer& tr);
//- Return a string representation of a transformer
word name(const transformer&);
//- Data associated with transformer type are contiguous
template<>
inline bool contiguous<transformer>() {return true;}
//- Template specialisations
// Template specialisations
template<>
tmp<Field<bool>> transformer::transform(const Field<bool>&) const;
template<>
tmp<Field<bool>> transformer::transform(const tmp<Field<bool>>&) const;
template<>
tmp<Field<label>> transformer::transform(const Field<label>&) const;
template<>
tmp<Field<label>> transformer::transform(const tmp<Field<label>>&) const;
template<>
tmp<Field<scalar>> transformer::transform(const Field<scalar>&)
const;
template<>
tmp<Field<scalar>> transformer::transform(const tmp<Field<scalar>>&)
const;
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
inline bool operator==
(
const transformer& tr1,
const transformer& tr2
);
inline bool operator==(const transformer& tr1, const transformer& tr2);
inline bool operator!=(const transformer& tr1, const transformer& tr2);
inline bool operator!=
(
const transformer& tr1,
const transformer& tr2
inline transformer operator+(const transformer& tr, const vector& t);
);
inline transformer operator+(const vector& t, const transformer& tr);
inline transformer operator-(const transformer& tr, const vector& t);
inline transformer operator+
(
const transformer& tr,
const vector& t
);
inline transformer operator+
(
const vector& t,
const transformer& tr
);
inline transformer operator-
(
const transformer& tr,
const vector& t
);
inline transformer operator&
(
const transformer& tr1,
const transformer& tr2
);
inline transformer operator&(const transformer& tr1, const transformer& tr2);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -28,37 +28,51 @@ License
inline Foam::transformer::transformer()
:
t_(Zero),
R_(sphericalTensor::I),
hasR_(false)
{}
inline Foam::transformer::transformer
(
const vector& t,
const tensor& R,
bool hasR
)
:
t_(t),
R_(R),
hasR_(hasR)
translates_(false),
R_(tensor::I),
rotates_(false)
{}
inline Foam::transformer::transformer(const vector& t)
:
t_(t),
R_(sphericalTensor::I),
hasR_(false)
translates_(true),
R_(tensor::I),
rotates_(false)
{}
inline Foam::transformer::transformer(const tensor& R)
:
t_(Zero),
translates_(false),
R_(R),
hasR_(true)
rotates_(true)
{}
inline Foam::transformer::transformer(const vector& t, const tensor& R)
:
t_(t),
translates_(true),
R_(R),
rotates_(true)
{}
inline Foam::transformer::transformer
(
const vector& t,
const bool translates,
const tensor& R,
const bool rotates
)
:
t_(t),
translates_(translates),
R_(R),
rotates_(rotates)
{}
@ -70,30 +84,43 @@ inline const Foam::vector& Foam::transformer::t() const
}
inline bool Foam::transformer::translates() const
{
return translates_;
}
inline const Foam::tensor& Foam::transformer::R() const
{
return R_;
}
inline bool Foam::transformer::hasR() const
inline bool Foam::transformer::rotates() const
{
return hasR_;
return rotates_;
}
inline bool Foam::transformer::transforms() const
{
return translates_ || rotates_;
}
inline Foam::vector& Foam::transformer::t()
{
// Assume that non-const access to t changes it from zero
translates_ = true;
return t_;
}
inline Foam::tensor& Foam::transformer::R()
{
// Assume that non-const access to R changes it from I, so set
// hasR to true
hasR_ = true;
// Assume that non-const access to R changes it from I
rotates_ = true;
return R_;
}
@ -104,33 +131,46 @@ inline Foam::vector Foam::transformer::transformPosition
const vector& v
) const
{
if (hasR_)
if (translates_ && !rotates_)
{
return t() + (R() & v);
return v + t();
}
else if (!translates_ && rotates_)
{
return R() & v;
}
else if (translates_ && rotates_)
{
return (R() & v) + t();
}
else
{
return t() + v;
return v;
}
}
inline Foam::pointField Foam::transformer::transformPosition
inline Foam::tmp<Foam::pointField> Foam::transformer::transformPosition
(
const pointField& pts
) const
{
tmp<pointField> tfld;
if (hasR_)
if (translates_ && !rotates_)
{
tfld = t() + (R() & pts);
return pts + t();
}
else if (!translates_ && rotates_)
{
return R() & pts;
}
else if (translates_ && rotates_)
{
return (R() & pts) + t();
}
else
{
tfld = t() + pts;
return pts;
}
return tfld();
}
@ -139,33 +179,46 @@ inline Foam::vector Foam::transformer::invTransformPosition
const vector& v
) const
{
if (hasR_)
if (translates_ && !rotates_)
{
return v - t();
}
else if (!translates_ && rotates_)
{
return R().T() & v;
}
else if (translates_ && rotates_)
{
return (R().T() & (v - t()));
}
else
{
return v - t();
return v;
}
}
inline Foam::pointField Foam::transformer::invTransformPosition
inline Foam::tmp<Foam::pointField> Foam::transformer::invTransformPosition
(
const pointField& pts
) const
{
tmp<pointField> tfld;
if (hasR_)
if (translates_ && !rotates_)
{
tfld = (R().T() & (pts - t()));
return pts - t();
}
else if (!translates_ && rotates_)
{
return R().T() & pts;
}
else if (translates_ && rotates_)
{
return (R().T() & (pts - t()));
}
else
{
tfld = pts - t();
return pts;
}
return tfld();
}
@ -177,44 +230,50 @@ inline void Foam::transformer::operator&=
)
{
t_ += tr.t_;
// If either of the two objects has translates_ as true, then inherit
// it, otherwise, these should both be zero vectors.
translates_ = tr.translates_ || translates_;
R_ = tr.R_ & R_;
// If either of the two objects has hasR_ as true, then inherit
// If either of the two objects has rotates_ as true, then inherit
// it, otherwise, these should both be I tensors.
hasR_ = tr.hasR_ || hasR_;
rotates_ = tr.rotates_ || rotates_;
}
inline void Foam::transformer::operator=(const vector& t)
{
translates_ = true;
t_ = t;
}
inline void Foam::transformer::operator+=(const vector& t)
{
translates_ = true;
t_ += t;
}
inline void Foam::transformer::operator-=(const vector& t)
{
translates_ = true;
t_ -= t;
}
inline void Foam::transformer::operator=(const tensor& R)
{
hasR_ = true;
rotates_ = true;
R_ = R;
}
inline void Foam::transformer::operator&=(const tensor& R)
{
hasR_ = true;
rotates_ = true;
R_ = R & R_;
}
@ -223,59 +282,54 @@ inline void Foam::transformer::operator&=(const tensor& R)
inline Foam::transformer Foam::inv(const transformer& tr)
{
return transformer(-tr.t(), tr.R().T(), tr.hasR());
if (tr.translates() && !tr.rotates())
{
return transformer(-tr.t());
}
else if (!tr.translates() && tr.rotates())
{
return transformer(tr.R().T());
}
else if (tr.translates() && tr.rotates())
{
return transformer(tr.R().T() & (-tr.t()), tr.R().T());
}
else
{
return transformer();
}
}
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
inline bool Foam::operator==
(
const transformer& tr1,
const transformer& tr2
)
inline bool Foam::operator==(const transformer& tr1, const transformer& tr2)
{
return (tr1.t() == tr2.t() && tr1.R() == tr2.R());
}
inline bool Foam::operator!=
(
const transformer& tr1,
const transformer& tr2
)
inline bool Foam::operator!=(const transformer& tr1, const transformer& tr2)
{
return !operator==(tr1, tr2);
}
inline Foam::transformer Foam::operator+
(
const transformer& tr,
const vector& t
)
inline Foam::transformer Foam::operator+(const transformer& tr, const vector& t)
{
return transformer(tr.t() + t, tr.R(), tr.hasR());
return transformer(tr.t() + t, true, tr.R(), tr.rotates());
}
inline Foam::transformer Foam::operator+
(
const vector& t,
const transformer& tr
)
inline Foam::transformer Foam::operator+(const vector& t, const transformer& tr)
{
return transformer(t + tr.t(), tr.R(), tr.hasR());
return transformer(t + tr.t(), true, tr.R(), tr.rotates());
}
inline Foam::transformer Foam::operator-
(
const transformer& tr,
const vector& t
)
inline Foam::transformer Foam::operator-(const transformer& tr, const vector& t)
{
return transformer(tr.t() - t, tr.R(), tr.hasR());
return transformer(tr.t() - t, true, tr.R(), tr.rotates());
}
@ -288,8 +342,9 @@ inline Foam::transformer Foam::operator&
return transformer
(
tr1.t() + tr2.t(),
tr1.translates() || tr2.translates(),
tr1.R() & tr2.R(),
(tr1.hasR() || tr2.hasR())
tr1.rotates() || tr2.rotates()
);
}

View File

@ -28,7 +28,7 @@ License
template<class Type>
Type Foam::transformer::transform(const Type& x) const
{
if (hasR_)
if (rotates_)
{
return Foam::transform(R(), x);
}
@ -45,7 +45,7 @@ Foam::tmp<Foam::Field<Type>> Foam::transformer::transform
const Field<Type>& fld
) const
{
if (hasR_)
if (rotates_)
{
return Foam::transform(R(), fld);
}
@ -56,10 +56,27 @@ Foam::tmp<Foam::Field<Type>> Foam::transformer::transform
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::transformer::transform
(
const tmp<Field<Type>>& tfld
) const
{
if (rotates_)
{
return Foam::transform(R(), tfld);
}
else
{
return tfld;
}
}
template<class Type>
Type Foam::transformer::invTransform(const Type& x) const
{
if (hasR_)
if (rotates_)
{
return Foam::transform(R().T(), x);
}
@ -76,7 +93,7 @@ Foam::tmp<Foam::Field<Type>> Foam::transformer::invTransform
const Field<Type>& fld
) const
{
if (hasR_)
if (rotates_)
{
return Foam::transform(R().T(), fld);
}
@ -87,4 +104,21 @@ Foam::tmp<Foam::Field<Type>> Foam::transformer::invTransform
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::transformer::invTransform
(
const tmp<Field<Type>>& tfld
) const
{
if (rotates_)
{
return Foam::transform(R().T(), tfld);
}
else
{
return tfld;
}
}
// ************************************************************************* //

View File

@ -193,7 +193,7 @@ void Foam::InteractionLists<ParticleType>::buildInteractionLists()
treeBoundBox tempTransformedBb
(
transform.invTransformPosition(cellBbsToExchange[bbI].points())
transform.invTransformPosition(cellBbsToExchange[bbI].points())()
);
treeBoundBox extendedBb
@ -410,7 +410,10 @@ void Foam::InteractionLists<ParticleType>::buildInteractionLists()
treeBoundBox tempTransformedBb
(
transform.invTransformPosition(wallFaceBbsToExchange[bbI].points())
transform.invTransformPosition
(
wallFaceBbsToExchange[bbI].points()
)()
);
treeBoundBox extendedBb
@ -708,7 +711,7 @@ void Foam::InteractionLists<ParticleType>::findExtendedProcBbsInRange
transform.transformPosition
(
allExtendedProcBbs[proci].points()
)
)()
);
if (procBb.overlaps(extendedReferredProcBb))
@ -755,7 +758,7 @@ void Foam::InteractionLists<ParticleType>::findExtendedProcBbsInRange
transform.transformPosition
(
allExtendedProcBbs[proci].points()
)
)()
);
if (procBb.overlaps(extendedReferredProcBb))
@ -798,7 +801,7 @@ void Foam::InteractionLists<ParticleType>::findExtendedProcBbsInRange
transform.transformPosition
(
allExtendedProcBbs[proci].points()
)
)()
);
if (procBb.overlaps(extendedReferredProcBb))
@ -1026,7 +1029,7 @@ void Foam::InteractionLists<ParticleType>::prepareWallDataToRefer()
// supported
referredWallData_[rWVI] = U.boundaryField()[patchi][patchFacei];
if (transform.hasR())
if (transform.rotates())
{
referredWallData_[rWVI] =
transform.R().T() & referredWallData_[rWVI];

View File

@ -1114,7 +1114,7 @@ void Foam::particle::prepareForInteractionListReferral
// Transform the properties
transformProperties(- transform.t());
if (transform.hasR())
if (transform.rotates())
{
transformProperties(transform.R().T());
}

View File

@ -363,7 +363,7 @@ void Foam::particle::hitCyclicAMIPatch
receiveCpp.owner()
? receiveCpp.AMITransforms()[receiveAMIi]
: inv(cpp.AMITransforms()[receiveAMIi]);
if (AMITransform.hasR())
if (AMITransform.rotates())
{
transformProperties(AMITransform.R());
displacementT = transform(AMITransform.R(), displacementT);

View File

@ -108,6 +108,7 @@ void Foam::cyclicRepeatAMIPolyPatch::resetAMI() const
transformPatch.separated()
? transformPatch.separation()
: vector::zero,
transformPatch.separated(),
!transformPatch.parallel()
? transformPatch.forwardT()
: tensor::zero,

View File

@ -479,7 +479,7 @@ void Foam::FaceCellWave<Type, TrackingData>::transform
{
// Transform. Implementation referred to Type
if (trans.hasR())
if (trans.rotates())
{
for (label facei = 0; facei < nFaces; facei++)
{