From f269371dbc324cbaf714b4fff70519469f3c1e2a Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Fri, 16 Nov 2018 15:12:19 +0100 Subject: [PATCH] ENH: support cylindrical coordinates in fieldCoordinateSystemTransform (#1076) --- .../fieldCoordinateSystemTransform.C | 97 ++++++++++++++++++- .../fieldCoordinateSystemTransform.H | 38 ++++++-- .../fieldCoordinateSystemTransformTemplates.C | 97 ++++++++++++++++--- .../simpleFoam/pipeCyclic/system/controlDict | 5 + .../pipeCyclic/system/coordinateTransform | 24 +++++ 5 files changed, 234 insertions(+), 27 deletions(-) create mode 100644 tutorials/incompressible/simpleFoam/pipeCyclic/system/coordinateTransform diff --git a/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C b/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C index e1d06c1729f..7259d24ca84 100644 --- a/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C +++ b/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C @@ -64,7 +64,8 @@ fieldCoordinateSystemTransform read(dict); Info<< type() << " " << name << ":" << nl - << " Applying uniform transformation from global Cartesian to local " + << " Applying " << (csysPtr_->uniform() ? "" : "non-") + << "uniform transformation from global Cartesian to local " << *csysPtr_ << nl << endl; } @@ -81,6 +82,96 @@ Foam::functionObjects::fieldCoordinateSystemTransform::transformFieldName } +const Foam::surfaceTensorField& +Foam::functionObjects::fieldCoordinateSystemTransform::srotTensor() const +{ + typedef surfaceTensorField FieldType; + typedef surfaceTensorField::Boundary BoundaryType; + + if (!rotTensorSurface_.valid()) + { + tensorField rotations(csysPtr_->R(mesh_.faceCentres())); + + rotTensorSurface_.reset + ( + new FieldType + ( + IOobject + ( + "surfRotation", + mesh_.objectRegistry::instance(), + mesh_.objectRegistry::db(), + IOobject::NO_READ, + IOobject::NO_WRITE, + false // no register + ), + mesh_, + dimless, + std::move(rotations) + // calculatedType + ) + ); + + auto& rot = *rotTensorSurface_; + + // Boundaries + BoundaryType& bf = const_cast<BoundaryType&>(rot.boundaryField()); + + forAll(bf, patchi) + { + bf[patchi] = csysPtr_->R(bf[patchi].patch().patch().faceCentres()); + } + } + + return *rotTensorSurface_; +} + + +const Foam::volTensorField& +Foam::functionObjects::fieldCoordinateSystemTransform::vrotTensor() const +{ + typedef volTensorField FieldType; + typedef volTensorField::Boundary BoundaryType; + + if (!rotTensorVolume_.valid()) + { + tensorField rotations(csysPtr_->R(mesh_.cellCentres())); + + rotTensorVolume_.reset + ( + new FieldType + ( + IOobject + ( + "volRotation", + mesh_.objectRegistry::instance(), + mesh_.objectRegistry::db(), + IOobject::NO_READ, + IOobject::NO_WRITE, + false // no register + ), + mesh_, + dimless, + std::move(rotations) + // calculatedType + ) + ); + + auto& rot = *rotTensorVolume_; + + // Boundaries + BoundaryType& bf = const_cast<BoundaryType&>(rot.boundaryField()); + + forAll(bf, patchi) + { + bf[patchi] = csysPtr_->R(bf[patchi].patch().patch().faceCentres()); + } + } + + return *rotTensorVolume_; +} + + bool Foam::functionObjects::fieldCoordinateSystemTransform::read ( const dictionary& dict @@ -109,6 +200,10 @@ bool Foam::functionObjects::fieldCoordinateSystemTransform::execute() transform<tensor>(fieldName); } + // Finished with these + rotTensorSurface_.clear(); + rotTensorVolume_.clear(); + return true; } diff --git a/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H b/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H index 6247df0dca0..2f2e317e6d2 100644 --- a/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H +++ b/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H @@ -29,7 +29,7 @@ Group Description Transforms a user-specified selection of fields from global Cartesian - coordinates to a local Cartesian coordinate system. + coordinates to a local coordinate system. The fields are run-time modifiable. Usage @@ -37,15 +37,10 @@ Usage \verbatim fieldCoordinateSystemTransform1 { - type fieldCoordinateSystemTransform; - libs ("libfieldFunctionObjects.so"); + type fieldCoordinateSystemTransform; + libs ("libfieldFunctionObjects.so"); ... - fields - ( - U - UMean - UPrime2Mean - ); + fields ( U UMean UPrime2Mean ); coordinateSystem { @@ -102,7 +97,7 @@ class fieldCoordinateSystemTransform { protected: - // Protected data + // Protected Data //- Fields to transform volFieldSelection fieldSet_; @@ -110,16 +105,39 @@ protected: //- Coordinate system to transform to autoPtr<coordinateSystem> csysPtr_; + //- Demand-driven non-uniform rotation field (surface fields) + // Eg, for cylindrical coordinates + mutable autoPtr<surfaceTensorField> rotTensorSurface_; + + //- Demand-driven non-uniform rotation field (volume fields) + // Eg, for cylindrical coordinates + mutable autoPtr<volTensorField> rotTensorVolume_; + // Protected Member Functions //- Return the name of the transformed field word transformFieldName(const word& fieldName) const; + //- Demand-driven non-uniform rotation field for surface fields + const surfaceTensorField& srotTensor() const; + + //- Demand-driven non-uniform rotation field for volume fields + const volTensorField& vrotTensor() const; + + //- Transform the given field template<class FieldType> void transformField(const FieldType& field); + //- Transform the given field + template<class FieldType, class RotationFieldType> + void transformField + ( + const RotationFieldType& rot, + const FieldType& field + ); + //- Transform the given field if has the specified element type template<class Type> void transform(const word& fieldName); diff --git a/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C b/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C index a0ea180a432..4fd833b0e36 100644 --- a/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C +++ b/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C @@ -46,6 +46,23 @@ void Foam::functionObjects::fieldCoordinateSystemTransform::transformField } +template<class FieldType, class RotationFieldType> +void Foam::functionObjects::fieldCoordinateSystemTransform::transformField +( + const RotationFieldType& rot, + const FieldType& field +) +{ + word transFieldName(transformFieldName(field.name())); + + store + ( + transFieldName, + Foam::invTransform(rot, field) + ); +} + + template<class Type> void Foam::functionObjects::fieldCoordinateSystemTransform::transform ( @@ -55,16 +72,31 @@ void Foam::functionObjects::fieldCoordinateSystemTransform::transform typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType; + // Scalar quantities (bool, label, scalar) and sphericalTensor quantities + // are transform invariant. Use (pTraits<Type>::nComponents == 1) to avoid + // avoid generating a tensor field for a non-uniform transformation. + if (foundObject<VolFieldType>(fieldName)) { DebugInfo << type() << ": Field " << fieldName << " already in database" << endl; - transformField<VolFieldType> - ( - lookupObject<VolFieldType>(fieldName) - ); + if (csysPtr_->uniform() || pTraits<Type>::nComponents == 1) + { + transformField<VolFieldType> + ( + lookupObject<VolFieldType>(fieldName) + ); + } + else + { + transformField<VolFieldType> + ( + vrotTensor(), + lookupObject<VolFieldType>(fieldName) + ); + } } else if (foundObject<SurfaceFieldType>(fieldName)) { @@ -72,10 +104,21 @@ void Foam::functionObjects::fieldCoordinateSystemTransform::transform << type() << ": Field " << fieldName << " already in database" << endl; - transformField<SurfaceFieldType> - ( - lookupObject<SurfaceFieldType>(fieldName) - ); + if (csysPtr_->uniform() || pTraits<Type>::nComponents == 1) + { + transformField<SurfaceFieldType> + ( + lookupObject<SurfaceFieldType>(fieldName) + ); + } + else + { + transformField<SurfaceFieldType> + ( + srotTensor(), + lookupObject<SurfaceFieldType>(fieldName) + ); + } } else { @@ -94,10 +137,21 @@ void Foam::functionObjects::fieldCoordinateSystemTransform::transform << type() << ": Field " << fieldName << " read from file" << endl; - transformField<VolFieldType> - ( - lookupObject<VolFieldType>(fieldName) - ); + if (csysPtr_->uniform() || pTraits<Type>::nComponents == 1) + { + transformField<VolFieldType> + ( + lookupObject<VolFieldType>(fieldName) + ); + } + else + { + transformField<VolFieldType> + ( + vrotTensor(), + lookupObject<VolFieldType>(fieldName) + ); + } } else if (fieldHeader.typeHeaderOk<SurfaceFieldType>(true, true, false)) { @@ -105,10 +159,21 @@ void Foam::functionObjects::fieldCoordinateSystemTransform::transform << type() << ": Field " << fieldName << " read from file" << endl; - transformField<SurfaceFieldType> - ( - lookupObject<SurfaceFieldType>(fieldName) - ); + if (csysPtr_->uniform() || pTraits<Type>::nComponents == 1) + { + transformField<SurfaceFieldType> + ( + lookupObject<SurfaceFieldType>(fieldName) + ); + } + else + { + transformField<SurfaceFieldType> + ( + srotTensor(), + lookupObject<SurfaceFieldType>(fieldName) + ); + } } } } diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/system/controlDict b/tutorials/incompressible/simpleFoam/pipeCyclic/system/controlDict index 19c1063ae38..fae83278cb6 100644 --- a/tutorials/incompressible/simpleFoam/pipeCyclic/system/controlDict +++ b/tutorials/incompressible/simpleFoam/pipeCyclic/system/controlDict @@ -45,5 +45,10 @@ timePrecision 6; runTimeModifiable true; +functions +{ + #include "coordinateTransform" +} + // ************************************************************************* // diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/system/coordinateTransform b/tutorials/incompressible/simpleFoam/pipeCyclic/system/coordinateTransform new file mode 100644 index 00000000000..4b340809e3d --- /dev/null +++ b/tutorials/incompressible/simpleFoam/pipeCyclic/system/coordinateTransform @@ -0,0 +1,24 @@ +/// -*- C++ -*- +coordinateTransform +{ + type fieldCoordinateSystemTransform; + libs ("libfieldFunctionObjects.so"); + log true; + fields ( U ); + + writeControl writeTime; + + coordinateSystem + { + type cylindrical; + origin (0 0 0); + rotation + { + type cylindrical; + axis (1 0 0); //< local Z + } + } +} + + +// ************************************************************************* // -- GitLab