diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C index 9f451bd772..01dee2c5e4 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C +++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -36,6 +36,7 @@ License #include "diagTensor.H" #include "transformField.H" #include "SubField.H" +#include "unitConversion.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -272,10 +273,14 @@ void Foam::cyclicPolyPatch::calcTransforms if (debug) { + scalar theta = radToDeg(acos(n0 & n1)); + Pout<< "cyclicPolyPatch::calcTransforms :" << " patch:" << name() << " Specified rotation :" - << " n0:" << n0 << " n1:" << n1 << endl; + << " n0:" << n0 << " n1:" << n1 + << " swept angle: " << theta << " [deg]" + << endl; } // Extended tensor from two local coordinate systems calculated @@ -432,10 +437,14 @@ void Foam::cyclicPolyPatch::getCentresAndAnchors if (debug) { + scalar theta = radToDeg(acos(n0 & n1)); + Pout<< "cyclicPolyPatch::getCentresAndAnchors :" << " patch:" << name() << " Specified rotation :" - << " n0:" << n0 << " n1:" << n1 << endl; + << " n0:" << n0 << " n1:" << n1 + << " swept angle: " << theta << " [deg]" + << endl; } // Extended tensor from two local coordinate systems calculated diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C index 52373c438d..98ce25d260 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -45,7 +45,7 @@ namespace Foam // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // -Foam::vector Foam::cyclicAMIPolyPatch::findFaceMaxRadius +Foam::vector Foam::cyclicAMIPolyPatch::findFaceNormalMaxRadius ( const pointField& faceCentres ) const @@ -138,45 +138,115 @@ void Foam::cyclicAMIPolyPatch::calcTransforms { case ROTATIONAL: { - point n0 = vector::zero; - if (half0Ctrs.size()) + tensor revT = tensor::zero; + + if (rotationAngleDefined_) { - n0 = findFaceMaxRadius(half0Ctrs); + tensor T(rotationAxis_*rotationAxis_); + + tensor S + ( + 0, -rotationAxis_.z(), rotationAxis_.y(), + rotationAxis_.z(), 0, -rotationAxis_.x(), + -rotationAxis_.y(), rotationAxis_.x(), 0 + ); + + tensor RPos + ( + T + + cos(rotationAngle_)*(tensor::I + T) + + sin(rotationAngle_)*S + ); + tensor RNeg + ( + T + + cos(-rotationAngle_)*(tensor::I + T) + + sin(-rotationAngle_)*S + ); + + // check - assume correct angle when difference in face areas + // is the smallest + vector transformedAreaPos = sum(half0Areas & RPos); + vector transformedAreaNeg = sum(half0Areas & RNeg); + vector area1 = sum(half1Areas); + reduce(transformedAreaPos, sumOp()); + reduce(transformedAreaNeg, sumOp()); + reduce(area1, sumOp()); + + scalar errorPos = mag(transformedAreaPos - area1); + scalar errorNeg = mag(transformedAreaNeg - area1); + + if (errorPos < errorNeg) + { + revT = RPos; + } + else + { + revT = RNeg; + rotationAngle_ *= -1; + } + + if (debug) + { + scalar theta = radToDeg(rotationAngle_); + + Pout<< "cyclicAMIPolyPatch::calcTransforms: patch:" + << name() + << " Specified rotation:" + << " swept angle: " << theta << " [deg]" + << " reverse transform: " << revT + << endl; + } } - point n1 = vector::zero; - if (half1Ctrs.size()) + else { - n1 = -findFaceMaxRadius(half1Ctrs); + point n0 = vector::zero; + point n1 = vector::zero; + if (half0Ctrs.size()) + { + n0 = findFaceNormalMaxRadius(half0Ctrs); + } + if (half1Ctrs.size()) + { + n1 = -findFaceNormalMaxRadius(half1Ctrs); + } + + reduce(n0, maxMagSqrOp()); + reduce(n1, maxMagSqrOp()); + + n0 /= mag(n0) + VSMALL; + n1 /= mag(n1) + VSMALL; + + // Extended tensor from two local coordinate systems calculated + // using normal and rotation axis + const tensor E0 + ( + rotationAxis_, + (n0 ^ rotationAxis_), + n0 + ); + const tensor E1 + ( + rotationAxis_, + (-n1 ^ rotationAxis_), + -n1 + ); + revT = E1.T() & E0; + + if (debug) + { + scalar theta = radToDeg(acos(n0 & n1)); + + Pout<< "cyclicAMIPolyPatch::calcTransforms: patch:" + << name() + << " Specified rotation:" + << " n0:" << n0 << " n1:" << n1 + << " swept angle: " << theta << " [deg]" + << " reverse transform: " << revT + << endl; + } } - reduce(n0, maxMagSqrOp()); - reduce(n1, maxMagSqrOp()); - - n0 /= mag(n0) + VSMALL; - n1 /= mag(n1) + VSMALL; - - if (debug) - { - Pout<< "cyclicAMIPolyPatch::calcTransforms : patch:" << name() - << " Specified rotation :" - << " n0:" << n0 << " n1:" << n1 << endl; - } - - // Extended tensor from two local coordinate systems calculated - // using normal and rotation axis - const tensor E0 - ( - rotationAxis_, - (n0 ^ rotationAxis_), - n0 - ); - const tensor E1 - ( - rotationAxis_, - (-n1 ^ rotationAxis_), - -n1 - ); - const tensor revT(E1.T() & E0); const_cast(forwardT()) = tensorField(1, revT.T()); const_cast(reverseT()) = tensorField(1, revT); const_cast(separation()).setSize(0); @@ -395,6 +465,8 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch nbrPatchID_(-1), rotationAxis_(vector::zero), rotationCentre_(point::zero), + rotationAngleDefined_(false), + rotationAngle_(0.0), separationVector_(vector::zero), AMIPtr_(NULL), AMIReverse_(false), @@ -421,6 +493,8 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch nbrPatchID_(-1), rotationAxis_(vector::zero), rotationCentre_(point::zero), + rotationAngleDefined_(false), + rotationAngle_(0.0), separationVector_(vector::zero), AMIPtr_(NULL), AMIReverse_(dict.lookupOrDefault("flipNormals", false)), @@ -466,6 +540,17 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch { dict.lookup("rotationAxis") >> rotationAxis_; dict.lookup("rotationCentre") >> rotationCentre_; + if (dict.readIfPresent("rotationAngle", rotationAngle_)) + { + rotationAngleDefined_ = true; + rotationAngle_ = degToRad(rotationAngle_); + + if (debug) + { + Info<< "rotationAngle: " << rotationAngle_ << " [rad]" + << endl; + } + } scalar magRot = mag(rotationAxis_); if (magRot < SMALL) @@ -516,6 +601,8 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch nbrPatchID_(-1), rotationAxis_(pp.rotationAxis_), rotationCentre_(pp.rotationCentre_), + rotationAngleDefined_(pp.rotationAngleDefined_), + rotationAngle_(pp.rotationAngle_), separationVector_(pp.separationVector_), AMIPtr_(NULL), AMIReverse_(pp.AMIReverse_), @@ -543,6 +630,8 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch nbrPatchID_(-1), rotationAxis_(pp.rotationAxis_), rotationCentre_(pp.rotationCentre_), + rotationAngleDefined_(pp.rotationAngleDefined_), + rotationAngle_(pp.rotationAngle_), separationVector_(pp.separationVector_), AMIPtr_(NULL), AMIReverse_(pp.AMIReverse_), @@ -584,6 +673,8 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch nbrPatchID_(-1), rotationAxis_(pp.rotationAxis_), rotationCentre_(pp.rotationCentre_), + rotationAngleDefined_(pp.rotationAngleDefined_), + rotationAngle_(pp.rotationAngle_), separationVector_(pp.separationVector_), AMIPtr_(NULL), AMIReverse_(pp.AMIReverse_), @@ -874,6 +965,14 @@ void Foam::cyclicAMIPolyPatch::write(Ostream& os) const << token::END_STATEMENT << nl; os.writeKeyword("rotationCentre") << rotationCentre_ << token::END_STATEMENT << nl; + + if (rotationAngleDefined_) + { + os.writeKeyword("rotationAngle") << radToDeg(rotationAngle_) + << token::END_STATEMENT << nl; + + } + break; } case TRANSLATIONAL: diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H index e3bb1d35d9..fbdffb3dee 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -75,9 +75,15 @@ private: //- Axis of rotation for rotational cyclics vector rotationAxis_; - //- point on axis of rotation for rotational cyclics + //- Point on axis of rotation for rotational cyclics point rotationCentre_; + //- Flag to show whether the rotation angle is defined + bool rotationAngleDefined_; + + //- Rotation angle + scalar rotationAngle_; + // For translation @@ -101,7 +107,7 @@ private: // Private Member Functions //- Return normal of face at max distance from rotation axis - vector findFaceMaxRadius(const pointField& faceCentres) const; + vector findFaceNormalMaxRadius(const pointField& faceCentres) const; void calcTransforms ( diff --git a/src/postProcessing/functionObjects/forces/forces/forces.C b/src/postProcessing/functionObjects/forces/forces/forces.C index e38c5a4622..831f552667 100644 --- a/src/postProcessing/functionObjects/forces/forces/forces.C +++ b/src/postProcessing/functionObjects/forces/forces/forces.C @@ -940,6 +940,8 @@ void Foam::forces::calcForcesMoment() Pstream::listCombineGather(force_, plusEqOp()); Pstream::listCombineGather(moment_, plusEqOp()); + Pstream::listCombineScatter(force_); + Pstream::listCombineScatter(moment_); }