void Foam::wedgePolyPatch::initTransforms() { if (size() > 0) { const pointField& points = this->points(); patchNormal_ = operator[](0).normal(points); patchNormal_ /= mag(patchNormal_); centreNormal_ = vector ( sign(patchNormal_.x())*(max(mag(patchNormal_.x()), 0.5) - 0.5), sign(patchNormal_.y())*(max(mag(patchNormal_.y()), 0.5) - 0.5), sign(patchNormal_.z())*(max(mag(patchNormal_.z()), 0.5) - 0.5) ); centreNormal_ /= mag(centreNormal_); if ( mag(centreNormal_.x() + centreNormal_.y() + centreNormal_.z()) < (1 - SMALL) ) { FatalErrorIn ( "wedgePolyPatch::initTransforms()" ) << "wedge " << name() << " centre plane does not align with a coordinate plane by " << 1 - mag(centreNormal_.x()+centreNormal_.y()+centreNormal_.z()) << exit(FatalError); } axis_ = centreNormal_ ^ patchNormal_; scalar magAxis = mag(axis_); if (magAxis < SMALL) { FatalErrorIn ( "wedgePolyPatch::initTransforms()" ) << "wedge " << name() << " plane aligns with a coordinate plane." << nl << " The wedge plane should make a small angle (~2.5deg)" " with the coordinate plane" << nl << " and the the pair of wedge planes should be symmetric" << " about the coordinate plane." << nl << " Normal of face " << 0 << " is " << patchNormal_ << " , implied coordinate plane direction is " << centreNormal_ << exit(FatalError); } axis_ /= magAxis; faceT_ = rotationTensor(centreNormal_, patchNormal_); cellT_ = faceT_ & faceT_; } }
Foam::rotateSearchableSurface::rotateSearchableSurface ( const IOobject& io, const dictionary& dict ) : transformationSearchableSurface(io,dict) { vector from(dict.lookup("rotateFrom")); vector to(dict.lookup("rotateTo")); if(mag(from)<SMALL || mag(to)<SMALL) { FatalErrorIn("rotateSearchableSurface::rotateSearchableSurface") << "Vector " << from << " or " << to << " close to zero" << endl << abort(FatalError); } from/=mag(from); to/=mag(to); rotation_ = rotationTensor(from,to); backRotation_ = rotationTensor(to,from); }
void Foam::triad::align(const vector& v) { if (set()) { vector mostAligned ( mag(v & operator[](0)), mag(v & operator[](1)), mag(v & operator[](2)) ); scalar mav; if ( mostAligned.x() > mostAligned.y() && mostAligned.x() > mostAligned.z() ) { mav = mostAligned.x(); mostAligned = operator[](0); } else if (mostAligned.y() > mostAligned.z()) { mav = mostAligned.y(); mostAligned = operator[](1); } else { mav = mostAligned.z(); mostAligned = operator[](2); } if (mav < 0.99) { tensor R(rotationTensor(mostAligned, v)); operator[](0) = transform(R, operator[](0)); operator[](1) = transform(R, operator[](1)); operator[](2) = transform(R, operator[](2)); } } }
bool Foam::dynamicBodyFvMesh::update() { scalar curTime = time().value(); scalar oldTime = curTime - time().deltaT().value(); if ( motionPtr_->type() == laplaceTetMotionSolver::typeName ) { tetMotionSolver& mSolver = dynamic_cast<tetMotionSolver&> ( motionPtr_() ); vector trans = translationAmplitude_ *( sin(2*mathematicalConstant::pi*translationFrequency_*curTime) - sin(2*mathematicalConstant::pi*translationFrequency_*oldTime) ) *translationDirection_; scalar rotAngle = rotationAmplitude_ *( sin(2*mathematicalConstant::pi*rotationFrequency_*curTime) - sin(2*mathematicalConstant::pi*rotationFrequency_*oldTime) ); vector curRotationOrigin = initialRotationOrigin_ + translationDirection_ *translationAmplitude_ *sin(2*mathematicalConstant::pi*translationFrequency_*oldTime); const pointField& oldPoints = mSolver.tetMesh().boundary()[bodyPatchID_].localPoints(); vector r0(1, 1, 1); r0 -= rotationAxis_*(rotationAxis_ & r0); r0 /= mag(r0); // http://mathworld.wolfram.com/RotationFormula.html vector r1 = r0*cos(rotAngle) + rotationAxis_*(rotationAxis_ & r0)*(1 - cos(rotAngle)) + (r0 ^ rotationAxis_)*sin(rotAngle); tensor T = rotationTensor(r0, r1); vectorField rot = transform(T, oldPoints - curRotationOrigin) + curRotationOrigin - oldPoints; tetPointVectorField& motionU = mSolver.motionU(); if ( motionU.boundaryField()[bodyPatchID_].type() == fixedValueTetPolyPatchVectorField::typeName ) { fixedValueTetPolyPatchVectorField& motionUBodyPatch = refCast<fixedValueTetPolyPatchVectorField> ( motionU.boundaryField()[bodyPatchID_] ); motionUBodyPatch == (trans + rot)/time().deltaT().value(); } else { FatalErrorIn("dynamicBodyFvMesh::update()") << "Bounary condition on " << motionU.name() << " for " << bodyPatchName_ << " patch is " << motionU.boundaryField()[bodyPatchID_].type() << ", instead " << fixedValueTetPolyPatchVectorField::typeName << exit(FatalError); } } else { FatalErrorIn("dynamicBodyFvMesh::update()") << "Selected mesh motion solver is " << motionPtr_->type() << ", instead " << tetMotionSolver::typeName << exit(FatalError); } fvMesh::movePoints(motionPtr_->newPoints()); // Mesh motion only - return false return false; }
void Foam::coupledPolyPatch::calcTransformTensors ( const vectorField& Cf, const vectorField& Cr, const vectorField& nf, const vectorField& nr, const scalarField& smallDist, const scalar absTol ) const { if (debug) { Pout<< "coupledPolyPatch::calcTransformTensors : " << name() << endl << " (half)size:" << Cf.size() << nl << " absTol:" << absTol << nl << " sum(mag(nf & nr)):" << sum(mag(nf & nr)) << endl; } // Tolerance calculation. // - normal calculation: assume absTol is the absolute error in a // single normal/transformation calculation. Consists both of numerical // precision (on the order of SMALL and of writing precision // (from e.g. decomposition) // Then the overall error of summing the normals is sqrt(size())*absTol // - separation calculation: pass in from the outside an allowable error. if (size() == 0) { // Dummy geometry. separation_.setSize(0); forwardT_ = I; reverseT_ = I; } else { scalar error = absTol*Foam::sqrt(1.0*Cf.size()); if (debug) { Pout<< " error:" << error << endl; } if (sum(mag(nf & nr)) < Cf.size() - error) { // Rotation, no separation separation_.setSize(0); forwardT_.setSize(Cf.size()); reverseT_.setSize(Cf.size()); forAll (forwardT_, facei) { forwardT_[facei] = rotationTensor(-nr[facei], nf[facei]); reverseT_[facei] = rotationTensor(nf[facei], -nr[facei]); } if (debug) { Pout<< " sum(mag(forwardT_ - forwardT_[0])):" << sum(mag(forwardT_ - forwardT_[0])) << endl; } if (sum(mag(forwardT_ - forwardT_[0])) < error) { forwardT_.setSize(1); reverseT_.setSize(1); if (debug) { Pout<< " difference in rotation less than" << " local tolerance " << error << ". Assuming uniform rotation." << endl; } } }
void Foam::wedgePolyPatch::calcGeometry(PstreamBuffers&) { if (axis_ != vector::rootMax) { return; } if (returnReduce(size(), sumOp<label>())) { const vectorField& nf(faceNormals()); n_ = gAverage(nf); if (debug) { Info<< "Patch " << name() << " calculated average normal " << n_ << endl; } // Check the wedge is planar forAll(nf, faceI) { if (magSqr(n_ - nf[faceI]) > SMALL) { // only issue warning instead of error so that the case can // still be read for post-processing WarningIn ( "wedgePolyPatch::calcGeometry(PstreamBuffers&)" ) << "Wedge patch '" << name() << "' is not planar." << nl << "At local face at " << primitivePatch::faceCentres()[faceI] << " the normal " << nf[faceI] << " differs from the average normal " << n_ << " by " << magSqr(n_ - nf[faceI]) << nl << "Either correct the patch or split it into planar parts" << endl; } } centreNormal_ = vector ( sign(n_.x())*(max(mag(n_.x()), 0.5) - 0.5), sign(n_.y())*(max(mag(n_.y()), 0.5) - 0.5), sign(n_.z())*(max(mag(n_.z()), 0.5) - 0.5) ); centreNormal_ /= mag(centreNormal_); cosAngle_ = centreNormal_ & n_; const scalar cnCmptSum = centreNormal_.x() + centreNormal_.y() + centreNormal_.z(); if (mag(cnCmptSum) < (1 - SMALL)) { FatalErrorIn("wedgePolyPatch::calcGeometry(PstreamBuffers&)") << "wedge " << name() << " centre plane does not align with a coordinate plane by " << 1 - mag(cnCmptSum) << exit(FatalError); } axis_ = centreNormal_ ^ n_; scalar magAxis = mag(axis_); if (magAxis < SMALL) { FatalErrorIn("wedgePolyPatch::calcGeometry(PstreamBuffers&)") << "wedge " << name() << " plane aligns with a coordinate plane." << nl << " The wedge plane should make a small angle (~2.5deg)" " with the coordinate plane" << nl << " and the the pair of wedge planes should be symmetric" << " about the coordinate plane." << nl << " Normal of wedge plane is " << n_ << " , implied coordinate plane direction is " << centreNormal_ << exit(FatalError); } axis_ /= magAxis; faceT_ = rotationTensor(centreNormal_, n_); cellT_ = faceT_ & faceT_; } }