Пример #1
0
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);
}
Пример #3
0
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;
}
Пример #5
0
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;
                }
            }
        }
Пример #6
0
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_;
    }
}