コード例 #1
0
void Foam::steadyStateControl::maxTypeResidual
(
    const word& fieldName,
    ITstream& data,
    scalar& firstRes,
    scalar& lastRes
) const
{
    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
    if (mesh_.foundObject<fieldType>(fieldName))
    {
        //fieldType& pointVelocity = const_cast<fieldType&>(
        //  mesh_.objectRegistry::lookupObject<fieldType>( fieldName )
        //);
	fieldType& field = const_cast<fieldType&>(
		mesh_.lookupObject<fieldType>( fieldName )
	);

        const List<SolverPerformance<Type> > sp(data);

        int sz = field.size();
        reduce(sz, sumOp<int>());
        Type nF = gSumCmptProd( field, field ) / static_cast<double>(sz);

	//Type finiR = sp.first().initialResidual();
	//Type liniR = sp.last().initialResidual();
	//
	scalar norm = mag(nF);

	for (direction cmpt=0; cmpt < nF.size(); cmpt++){
	  nF[cmpt] = sqrt( nF[cmpt] );
	  //finiR[cmpt] *= tmpNF;
	  //liniR[cmpt] *= tmpNF;
	}
        nF = nF/norm;

	//finiR /= norm;
	//liniR /= norm;
	//firstRes = cmptMax(finiR);
	//lastRes = cmptMax(liniR);
	//
        firstRes = cmptMax( cmptMultiply(sp.first().initialResidual(), nF) );
        lastRes  = cmptMax( cmptMultiply(sp.last().initialResidual(),  nF) );

        //firstRes = cmptMax(sp.first().initialResidual());
        //lastRes = cmptMax(sp.last().initialResidual());
    }
}
コード例 #2
0
Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
(
    const lduMesh& mesh,
    const scalarField& cellVolumes,
    const vectorField& faceAreas,
    const dictionary& controlDict
)
:
    pairGAMGAgglomeration(mesh, controlDict)
{
    // agglomerate(mesh, sqrt(mag(faceAreas)));
    agglomerate
    (
        mesh,
        mag
        (
            cmptMultiply
            (
                faceAreas
               /sqrt(mag(faceAreas)),
                vector(1, 1.01, 1.02)
                // vector::one
            )
        )
    );
}
コード例 #3
0
vector horizontalVelocityField::streamfunctionAt
(
        const point& p,
        const Time& t
) const
{
    const vector unitNormal(0, -1, 0);
    const dimensionedScalar z("z", dimLength, p.z());

    dimensionedScalar psi("psi", cmptMultiply(dimVelocity, dimLength), scalar(0));
    if (z.value() <= z1.value())
    {
        // psi is zero
    }
    else if (z.value() <= z2.value())
    {
        psi = -0.5*u0*(z - z1 - (z2-z1)/M_PI*Foam::sin(M_PI*(z-z1)/(z2-z1)));
    }
    else 
    {
        psi = -0.5*u0*(2*z - z2 - z1);
    }

    return unitNormal * psi.value();
}
コード例 #4
0
bool Foam::SolverPerformance<Type>::checkConvergence
(
    const Type& Tolerance,
    const Type& RelTolerance
)
{
    if (debug >= 2)
    {
        Info<< solverName_
            << ":  Iteration " << nIterations_
            << " residual = " << finalResidual_
            << endl;
    }

    if
    (
        finalResidual_ < Tolerance
     || (
            RelTolerance
          > small_*pTraits<Type>::one
         && finalResidual_ < cmptMultiply(RelTolerance, initialResidual_)
        )
    )
    {
        converged_ = true;
    }
    else
    {
        converged_ = false;
    }

    return converged_;
}
コード例 #5
0
Foam::tmp<Foam::Field<Type>>
Foam::transformFvPatchField<Type>::gradientBoundaryCoeffs() const
{
    return
        snGrad()
      - cmptMultiply(gradientInternalCoeffs(), this->patchInternalField());
}
コード例 #6
0
Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
(
    const lduMesh& mesh,
    const dictionary& controlDict
)
:
    pairGAMGAgglomeration(mesh, controlDict)
{
    const fvMesh& fvmesh = refCast<const fvMesh>(mesh);

    //agglomerate(mesh, sqrt(fvmesh.magSf().internalField()));
    agglomerate
    (
        mesh,
        mag
        (
            cmptMultiply
            (
                fvmesh.Sf().internalField()
               /sqrt(fvmesh.magSf().internalField()),
                vector(1, 1.01, 1.02)
                //vector::one
            )
        )
    );
}
コード例 #7
0
void Foam::directionalDiffusivity::correct()
{
    const fvMesh& mesh = mSolver().mesh();

    surfaceVectorField n = mesh.Sf()/mesh.magSf();
    faceDiffusivity_ == (n & cmptMultiply(diffusivityVector_, n));
}
コード例 #8
0
void Foam::displacementMotionSolver::updateMesh(const mapPolyMesh& mpm)
{
    // pointMesh already updates pointFields

    motionSolver::updateMesh(mpm);

    // Map points0_. Bit special since we somehow have to come up with
    // a sensible points0 position for introduced points.
    // Find out scaling between points0 and current points

    // Get the new points either from the map or the mesh
    const pointgpuField& points =
    (
        mpm.hasMotionPoints()
      ? mpm.preMotionPoints()
      : mesh().points()
    );

    // Note: boundBox does reduce
    const vector span0 = boundBox(points0_).span();
    const vector span = boundBox(points).span();

    vector scaleFactors(cmptDivide(span0, span));

    pointField newPoints0(mpm.pointMap().size());

    forAll(newPoints0, pointI)
    {
        label oldPointI = mpm.pointMap()[pointI];

        if (oldPointI >= 0)
        {
            label masterPointI = mpm.reversePointMap()[oldPointI];

            if (masterPointI == pointI)
            {
                newPoints0[pointI] = points0_[oldPointI];
            }
            else
            {
                // New point - assume motion is scaling
                newPoints0[pointI] = points0_[oldPointI] + cmptMultiply
                (
                    scaleFactors,
                    points[pointI] - points[masterPointI]
                );
            }
        }
        else
        {
            FatalErrorIn
            (
                "displacementMotionSolver::updateMesh"
                "(const mapPolyMesh&)"
            )   << "Cannot determine co-ordinates of introduced vertices."
                << " New vertex " << pointI << " at co-ordinate "
                << points[pointI] << exit(FatalError);
        }
    }
コード例 #9
0
ファイル: POD.C プロジェクト: Danniel-UCAS/LEMOS-2.4.x
Type projection
(
    const GeometricField<Type, fvPatchField, volMesh>& a,
    const GeometricField<Type, fvPatchField, volMesh>& b
)
{
    return sum(cmptMultiply(a.internalField(), b.internalField()));
}
コード例 #10
0
tmp<Field<Type> > transformFaPatchField<Type>::valueBoundaryCoeffs
(
    const tmp<scalarField>&
) const
{
    return
        *this
      - cmptMultiply
        (
            valueInternalCoeffs(this->patch().weights()),
            this->patchInternalField()
        );
}
コード例 #11
0
void implicitExtrapolationFvPatchField<Type>::updateCoeffs(){


    Field<Type>& boundaryField = *this;                         // will be set from old time-step
    const Field<Type>& internalField = this->internalField();
    const fvMesh& m = this->patch().boundaryMesh().mesh();
    const scalarField& d1 = this->patch().deltaCoeffs();
    const scalarField& d2 = secondDeltas;
    const scalarField d1_dividedBy_d2 = (1/d1)/d2;
    const Field<Type> oneField = Field<Type>(this->size(), pTraits<Type>::one);
    const labelList& faceCells = this->patch().faceCells();

    internalCoeffsDiag = (1 + d1_dividedBy_d2 ) * oneField;

    forAll(boundaryField, i){

        if(secondNormalCellIsOwner[i]){
            internalCoeffsLower[i] = - d1_dividedBy_d2[i] * oneField[i];
            internalCoeffsUpper[i] = 0 * oneField[i];
            const label boundaryCell = faceCells[i];
            const label secondCell = m.owner()[secondFaces()[i]];
            boundaryField[i] = cmptMultiply(internalCoeffsDiag[i],internalField[boundaryCell])
                             + cmptMultiply(internalCoeffsLower[i],internalField[secondCell]);
        }
        else{
            internalCoeffsLower[i] = 0 * oneField[i];
            internalCoeffsUpper[i] = - d1_dividedBy_d2[i] * oneField[i];
            const label boundaryCell = faceCells[i];
            const label secondCell = m.neighbour()[secondFaces()[i]];
            boundaryField[i] = cmptMultiply(internalCoeffsDiag[i],internalField[boundaryCell])
                             + cmptMultiply(internalCoeffsUpper[i],internalField[secondCell]);
        }

    }

    fvPatchField<Type>::updateCoeffs();

}
void Foam::processorBlockGAMGInterfaceField<Type>::updateInterfaceMatrix
(
    const Field<Type>& psiInternal,
    Field<Type>& result,
    const BlockLduMatrix<Type>&,
    const CoeffField<Type>& coeffs,
    const Pstream::commsTypes commsType,
    const bool switchToLhs
) const
{
    Field<Type> pnf
    (
        coeffs.size()
    );

    if (coeffs.activeType() == blockCoeffBase::SCALAR)
    {
        pnf = coeffs.asScalar()*
            procInterface_.compressedReceive<Type>(commsType, this->size())();
    }
    else if (coeffs.activeType() == blockCoeffBase::LINEAR)
    {
        pnf = cmptMultiply
        (
            coeffs.asLinear(),
            procInterface_.compressedReceive<Type>(commsType, this->size())()
        );
    }
    else if (coeffs.activeType() == blockCoeffBase::SQUARE)
    {
        pnf = coeffs.asSquare() &
            procInterface_.compressedReceive<Type>(commsType, this->size())();
    }

    const unallocLabelList& faceCells = procInterface_.faceCells();

    if (switchToLhs)
    {
        forAll(faceCells, elemI)
        {
            result[faceCells[elemI]] += pnf[elemI];
        }
    }
    else
    {
コード例 #13
0
void Foam::motionDirectionalDiffusivity::correct()
{
    const fvMesh& mesh = mSolver().mesh();

    static bool first = true;

    if (!first)
    {
        const volVectorField& cellMotionU = 
            mesh.lookupObject<volVectorField>("cellMotionU");

        volVectorField D
        (
            IOobject
            (
                "D",
                mesh.time().timeName(),
                mesh
            ),
            diffusivityVector_.y()*vector::one
          + (diffusivityVector_.x() - diffusivityVector_.y())*cellMotionU
           /(mag(cellMotionU) + dimensionedScalar("small", dimVelocity, SMALL)),
            zeroGradientFvPatchVectorField::typeName
        );
        D.correctBoundaryConditions();

        surfaceVectorField n = mesh.Sf()/mesh.magSf();
        faceDiffusivity_ == (n & cmptMultiply(fvc::interpolate(D), n));
    }
    else
    {
        first = false;
        const_cast<fvMotionSolver&>(mSolver()).solve();
        correct();
    }
}
コード例 #14
0
ファイル: PCICG.C プロジェクト: Kiiree/CONSELFcae-dev
typename Foam::SolverPerformance<Type>
Foam::PCICG<Type, DType, LUType>::solve(Field<Type>& psi) const
{
    word preconditionerName(this->controlDict_.lookup("preconditioner"));

    // --- Setup class containing solver performance data
    SolverPerformance<Type> solverPerf
    (
        preconditionerName + typeName,
        this->fieldName_
    );

    label nCells = psi.size();

    Type* __restrict__ psiPtr = psi.begin();

    Field<Type> pA(nCells);
    Type* __restrict__ pAPtr = pA.begin();

    Field<Type> wA(nCells);
    Type* __restrict__ wAPtr = wA.begin();

    Type wArA = solverPerf.great_*pTraits<Type>::one;
    Type wArAold = wArA;

    // --- Calculate A.psi
    this->matrix_.Amul(wA, psi);

    // --- Calculate initial residual field
    Field<Type> rA(this->matrix_.source() - wA);
    Type* __restrict__ rAPtr = rA.begin();

    // --- Calculate normalisation factor
    Type normFactor = this->normFactor(psi, wA, pA);

    if (LduMatrix<Type, DType, LUType>::debug >= 2)
    {
        Info<< "   Normalisation factor = " << normFactor << endl;
    }

    // --- Calculate normalised residual norm
    solverPerf.initialResidual() = cmptDivide(gSumCmptMag(rA), normFactor);
    solverPerf.finalResidual() = solverPerf.initialResidual();

    // --- Check convergence, solve if not converged
    if
    (
        this->minIter_ > 0
     || !solverPerf.checkConvergence(this->tolerance_, this->relTol_)
    )
    {
        // --- Select and construct the preconditioner
        autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner>
        preconPtr = LduMatrix<Type, DType, LUType>::preconditioner::New
        (
            *this,
            this->controlDict_
        );

        // --- Solver iteration
        do
        {
            // --- Store previous wArA
            wArAold = wArA;

            // --- Precondition residual
            preconPtr->precondition(wA, rA);

            // --- Update search directions:
            wArA = gSumCmptProd(wA, rA);

            if (solverPerf.nIterations() == 0)
            {
                for (label cell=0; cell<nCells; cell++)
                {
                    pAPtr[cell] = wAPtr[cell];
                }
            }
            else
            {
                Type beta = cmptDivide
                (
                    wArA,
                    stabilise(wArAold, solverPerf.vsmall_)
                );

                for (label cell=0; cell<nCells; cell++)
                {
                    pAPtr[cell] = wAPtr[cell] + cmptMultiply(beta, pAPtr[cell]);
                }
            }


            // --- Update preconditioned residual
            this->matrix_.Amul(wA, pA);

            Type wApA = gSumCmptProd(wA, pA);


            // --- Test for singularity
            if
            (
                solverPerf.checkSingularity
                (
                    cmptDivide(cmptMag(wApA), normFactor)
                )
            )
            {
                break;
            }


            // --- Update solution and residual:

            Type alpha = cmptDivide
            (
                wArA,
                stabilise(wApA, solverPerf.vsmall_)
            );

            for (label cell=0; cell<nCells; cell++)
            {
                psiPtr[cell] += cmptMultiply(alpha, pAPtr[cell]);
                rAPtr[cell] -= cmptMultiply(alpha, wAPtr[cell]);
            }

            solverPerf.finalResidual() =
                cmptDivide(gSumCmptMag(rA), normFactor);

        } while
        (
            (
                solverPerf.nIterations()++ < this->maxIter_
            && !solverPerf.checkConvergence(this->tolerance_, this->relTol_)
            )
         || solverPerf.nIterations() < this->minIter_
        );
    }

    return solverPerf;
}
コード例 #15
0
void Foam::directionalDiffusivity::correct()
{
    const surfaceVectorField n(mesh().Sf()/mesh().magSf());
    faceDiffusivity_ == (n & cmptMultiply(diffusivityVector_, n));
}
void Foam::displacementSBRStressFvMotionSolver::updateMesh
(
    const mapPolyMesh& mpm
)
{
    fvMotionSolver::updateMesh(mpm);

    // Map points0_
    // Map points0_. Bit special since we somehow have to come up with
    // a sensible points0 position for introduced points.
    // Find out scaling between points0 and current points

    // Get the new points either from the map or the mesh
    const pointField& points =
    (
        mpm.hasMotionPoints()
      ? mpm.preMotionPoints()
      : fvMesh_.points()
    );

    // Note: boundBox does reduce
    const boundBox bb0(points0_, true);
    const vector span0(bb0.max()-bb0.min());
    const boundBox bb(points, true);
    const vector span(bb.max()-bb.min());

    vector scaleFactors(cmptDivide(span0, span));

    pointField newPoints0(mpm.pointMap().size());

    forAll(newPoints0, pointI)
    {
        label oldPointI = mpm.pointMap()[pointI];

        if (oldPointI >= 0)
        {
            label masterPointI = mpm.reversePointMap()[oldPointI];

            if (masterPointI == pointI)
            {
                newPoints0[pointI] = points0_[oldPointI];
            }
            else
            {
                // New point. Assume motion is scaling.
                newPoints0[pointI] =
                    points0_[oldPointI]
                  + cmptMultiply
                    (
                        scaleFactors,
                        points[pointI]-points[masterPointI]
                    );
            }
        }
        else
        {
            FatalErrorIn
            (
                "displacementSBRStressFvMotionSolver::updateMesh"
                "(const mapPolyMesh& mpm)"
            )   << "Cannot work out coordinates of introduced vertices."
                << " New vertex " << pointI << " at coordinate "
                << points[pointI] << exit(FatalError);
        }
    }
コード例 #17
0
void Foam::searchableSurfaceCollection::findNearest
(
    const pointField& samples,
    scalarField& minDistSqr,
    List<pointIndexHit>& nearestInfo,
    labelList& nearestSurf
) const
{
    // Initialise
    nearestInfo.setSize(samples.size());
    nearestInfo = pointIndexHit();
    nearestSurf.setSize(samples.size());
    nearestSurf = -1;

    List<pointIndexHit> hitInfo(samples.size());

    const scalarField localMinDistSqr(samples.size(), GREAT);

    forAll(subGeom_, surfI)
    {
        subGeom_[surfI].findNearest
        (
            cmptDivide  // Transform then divide
            (
                transform_[surfI].localPosition(samples),
                scale_[surfI]
            ),
            localMinDistSqr,
            hitInfo
        );

        forAll(hitInfo, pointI)
        {
            if (hitInfo[pointI].hit())
            {
                // Rework back into global coordinate sys. Multiply then
                // transform
                point globalPt = transform_[surfI].globalPosition
                (
                    cmptMultiply
                    (
                        hitInfo[pointI].rawPoint(),
                        scale_[surfI]
                    )
                );

                scalar distSqr = magSqr(globalPt - samples[pointI]);

                if (distSqr < minDistSqr[pointI])
                {
                    minDistSqr[pointI] = distSqr;
                    nearestInfo[pointI].setPoint(globalPt);
                    nearestInfo[pointI].setHit();
                    nearestInfo[pointI].setIndex
                    (
                        hitInfo[pointI].index()
                      + indexOffset_[surfI]
                    );
                    nearestSurf[pointI] = surfI;
                }
            }
        }
    }
コード例 #18
0
ファイル: vectorSnapshots.C プロジェクト: Brzous/WindFOAM
int main(int argc, char *argv[])
{

#   include "setRootCase.H"

#   include "createTime.H"

    // Get times list
    instantList Times = runTime.times();

    const label startTime = 1;
    const label endTime = Times.size();
    const label nSnapshots = Times.size() - 1;

    Info << "Number of snapshots: " << nSnapshots << endl;

    // Create a list of snapshots
    PtrList<volVectorField> fields(nSnapshots);

    runTime.setTime(Times[startTime], startTime);

#   include "createMesh.H"

    IOdictionary PODsolverDict
    (
        IOobject
        (
            "PODsolverDict",
            runTime.system(),
            mesh,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    );

    scalar accuracy =
        readScalar
        (
            PODsolverDict.subDict("scalarTransportCoeffs").lookup("accuracy")
        );

    Info << "Seeking accuracy: " << accuracy << endl;

    word fieldName
    (
        PODsolverDict.subDict("scalarTransportCoeffs").lookup("velocity")
    );

    label snapI = 0;

    labelList timeIndices(nSnapshots);

    for (label i = startTime; i < endTime; i++)
    {
        runTime.setTime(Times[i], i);

        Info<< "Time = " << runTime.timeName() << endl;

        mesh.readUpdate();

        Info<< "    Reading " << fieldName << endl;
        fields.set
        (
            snapI,
            new volVectorField
            (
                IOobject
                (
                    fieldName,
                    runTime.timeName(),
                    mesh,
                    IOobject::MUST_READ
                ),
                mesh
            )
        );

        // Rename the field
        fields[snapI].rename(fieldName + name(i));
        timeIndices[snapI] = i;
        snapI++;

        Info<< endl;
    }

    timeIndices.setSize(snapI);

    vectorPODOrthoNormalBase eb(fields, accuracy);

    const RectangularMatrix<vector>& coeffs = eb.interpolationCoeffs();

    // Check all snapshots
    forAll (fields, fieldI)
    {
        runTime.setTime(Times[timeIndices[fieldI]], timeIndices[fieldI]);

        volVectorField reconstruct
        (
            IOobject
            (
                fieldName + "PODreconstruct",
                runTime.timeName(),
                mesh,
                IOobject::NO_READ
            ),
            mesh,
            dimensionedVector
            (
                "zero",
                fields[fieldI].dimensions(),
                vector::zero
            )
        );

        for (label baseI = 0; baseI < eb.baseSize(); baseI++)
        {
            reconstruct +=
                cmptMultiply
                (
                    eb.orthoField(baseI),
                    coeffs[fieldI][baseI]
                );
        }

        scalar sumFieldError =
            sumMag
            (
                reconstruct.internalField()
              - fields[fieldI].internalField()
            );

        scalar measure = sumMag(fields[fieldI].internalField()) + SMALL;

        Info<< "Field error: absolute = " << sumFieldError << " relative = "
            << sumFieldError/measure << " measure = " << measure
            << endl;

        reconstruct.write();
    }