Пример #1
0
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::linearUpwind<Type>::correction
(
    const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
    const fvMesh& mesh = this->mesh();

    tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr
    (
        new GeometricField<Type, fvsPatchField, surfaceMesh>
        (
            IOobject
            (
                "linearUpwind::correction(" + vf.name() + ')',
                mesh.time().timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE,
                false
            ),
            mesh,
            dimensioned<Type>(vf.name(), vf.dimensions(), pTraits<Type>::zero)
        )
    );

    GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr();

    const surfaceScalarField& faceFlux = this->faceFlux_;

    const labelList& owner = mesh.owner();
    const labelList& neighbour = mesh.neighbour();

    const volVectorField& C = mesh.C();
    const surfaceVectorField& Cf = mesh.Cf();

    tmp
    <
        GeometricField
        <
            typename outerProduct<vector, Type>::type,
            fvPatchField,
            volMesh
        >
    > tgradVf = gradScheme_().grad(vf, gradSchemeName_);

    const GeometricField
    <
        typename outerProduct<vector, Type>::type,
        fvPatchField,
        volMesh
    >& gradVf = tgradVf();

    forAll(faceFlux, facei)
    {
        label celli = (faceFlux[facei] > 0) ? owner[facei] : neighbour[facei];
        sfCorr[facei] = (Cf[facei] - C[celli]) & gradVf[celli];
    }
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::extendedUpwindCellToFaceStencil::weightedSum
(
    const surfaceScalarField& phi,
    const GeometricField<Type, fvPatchField, volMesh>& fld,
    const List<List<scalar> >& ownWeights,
    const List<List<scalar> >& neiWeights
) const
{
    const fvMesh& mesh = fld.mesh();

    // Collect internal and boundary values
    List<List<Type> > ownFld;
    collectData(ownMap(), ownStencil(), fld, ownFld);
    List<List<Type> > neiFld;
    collectData(neiMap(), neiStencil(), fld, neiFld);

    tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr
    (
        new GeometricField<Type, fvsPatchField, surfaceMesh>
        (
            IOobject
            (
                fld.name(),
                mesh.time().timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE,
                false
            ),
            mesh,
            dimensioned<Type>
            (
                fld.name(),
                fld.dimensions(),
                pTraits<Type>::zero
            )
        )
    );
    GeometricField<Type, fvsPatchField, surfaceMesh>& sf = tsfCorr();

    // Internal faces
    for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
    {
        if (phi[faceI] > 0)
        {
            // Flux out of owner. Use upwind (= owner side) stencil.
            const List<Type>& stField = ownFld[faceI];
            const List<scalar>& stWeight = ownWeights[faceI];

            forAll(stField, i)
            {
                sf[faceI] += stField[i]*stWeight[i];
            }
        }
        else
        {
Пример #3
0
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::CLUST<Type>::correction
(
    const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
    const fvMesh& mesh = this->mesh();

    tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr
    (
        new GeometricField<Type, fvsPatchField, surfaceMesh>
        (
            IOobject
            (
                "CLUST::correction(" + vf.name() + ')',
                mesh.time().timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE,
                false
            ),
            mesh,
            dimensioned<Type>(vf.name(), vf.dimensions(), pTraits<Type>::zero)
        )
    );

    GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr();

    const surfaceVectorField& Uf = this->Uf_;

    //const GeometricField<Type,fvsPatchField,surfaceMesh> gradf=fvc::snGrad(vf);

    const GeometricField
    <
        typename outerProduct<vector, Type>::type,
        fvPatchField,
        volMesh
    > Grad = fvc::grad(vf);
    
    forAll(sfCorr, facei)
    {
        const scalar un = (Uf[facei] & mesh.Sf()[facei])/mesh.magSf()[facei];
        const scalar ub = mag(un)/max(SMALL, mag(Uf[facei]));
        label celli = un > 0 ? mesh.owner()[facei] : mesh.neighbour()[facei];
        label cellj = celli == mesh.owner()[facei] ? mesh.neighbour()[facei]
                                                    : mesh.owner()[facei];
        sfCorr[facei] = 0.5*b_*ub*
        (
            ((mesh.C()[cellj] - mesh.C()[celli]) & Grad[celli])
          + vf[celli] - vf[cellj]
        );
    }

    return tsfCorr;
}
Пример #4
0
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::APVM<Type>::correction
(
    const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
    const fvMesh& mesh = this->mesh();

    tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr
    (
        new GeometricField<Type, fvsPatchField, surfaceMesh>
        (
            IOobject
            (
                "APVM::correction(" + vf.name() + ')',
                mesh.time().timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE,
                false
            ),
            mesh,
            dimensioned<Type>(vf.name(), vf.dimensions(), pTraits<Type>::zero)
        )
    );

    GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr.ref();

    const dimensionedScalar& dt = mesh.time().deltaT();

    const surfaceVectorField& Uf = this->Uf_;

    const GeometricField<Type, fvsPatchField, surfaceMesh> gradf = fvc::snGrad(vf);

    const GeometricField
    <
        typename outerProduct<vector, Type>::type,
        fvsPatchField,
        surfaceMesh
    > GradF = fvc::interpolate(fvc::reconstruct(gradf*mesh.magSf()));

    sfCorr = -0.5*dt*(Uf & GradF);

    return tsfCorr;
}
Пример #5
0
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::linearUpwindV<Type>::correction
(
    const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
   const fvMesh& mesh = this->mesh();

   tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr
   (
       new GeometricField<Type, fvsPatchField, surfaceMesh>
       (
           IOobject
           (
               vf.name(),
               mesh.time().timeName(),
               mesh
           ),
           mesh,
           dimensioned<Type>
           (
               vf.name(),
               vf.dimensions(),
               pTraits<Type>::zero
           )
       )
   );

   GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr();

   const surfaceScalarField& faceFlux = this->faceFlux_;
   const surfaceScalarField& w = mesh.weights();

   const labelList& own = mesh.owner();
   const labelList& nei = mesh.neighbour();

   const vectorField& C = mesh.C();
   const vectorField& Cf = mesh.Cf();

   GeometricField
       <typename outerProduct<vector, Type>::type, fvPatchField, volMesh>
       gradVf = gradScheme_().grad(vf);

   forAll(faceFlux, facei)
   {
       vector maxCorr;

       if (faceFlux[facei] > 0.0)
       {
           maxCorr =
               (1.0 - w[facei])
               *(vf[nei[facei]] - vf[own[facei]]);

           sfCorr[facei] =
               (Cf[facei] - C[own[facei]]) & gradVf[own[facei]];
       }
       else
       {
           maxCorr =
               w[facei]*(vf[own[facei]] - vf[nei[facei]]);

           sfCorr[facei] =
               (Cf[facei] - C[nei[facei]]) & gradVf[nei[facei]];
       }

       scalar sfCorrs = magSqr(sfCorr[facei]);
       scalar maxCorrs = sfCorr[facei] & maxCorr;

       if (sfCorrs > 0)
       {
           if (maxCorrs < 0)
           {
               sfCorr[facei] = vector::zero;
           }
           else if (sfCorrs > maxCorrs)
           {
               sfCorr[facei] *= maxCorrs/(sfCorrs + VSMALL);
           }
       }
       else if (sfCorrs < 0)
       {
           if (maxCorrs > 0)
           {
               sfCorr[facei] = vector::zero;
           }
           else if (sfCorrs < maxCorrs)
           {
               sfCorr[facei] *= maxCorrs/(sfCorrs - VSMALL);
           }
       }
   }
Пример #6
0
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::pointLinear<Type>::
correction
(
    const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
    const fvMesh& mesh = this->mesh();

    GeometricField<Type, pointPatchField, pointMesh> pvf
    (
        volPointInterpolation::New(mesh).interpolate(vf)
    );

    tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr =
        linearInterpolate(vf);

    Field<Type>& sfCorr = tsfCorr().internalField();

    const pointField& points = mesh.points();
    const pointField& C = mesh.C().internalField();
    const faceList& faces = mesh.faces();
    const scalarField& w = mesh.weights().internalField();
    const labelList& owner = mesh.owner();
    const labelList& neighbour = mesh.neighbour();

    forAll(sfCorr, facei)
    {
        point pi =
            w[owner[facei]]*C[owner[facei]]
          + (1.0 - w[owner[facei]])*C[neighbour[facei]];

        scalar at = triangle<point, const point&>
        (
            pi,
            points[faces[facei][0]],
            points[faces[facei][faces[facei].size()-1]]
        ).mag();

        scalar sumAt = at;
        Type sumPsip = at*(1.0/3.0)*
        (
            sfCorr[facei]
          + pvf[faces[facei][0]]
          + pvf[faces[facei][faces[facei].size()-1]]
        );

        for (label pointi=1; pointi<faces[facei].size(); pointi++)
        {
            at = triangle<point, const point&>
            (
                pi,
                points[faces[facei][pointi]],
                points[faces[facei][pointi-1]]
            ).mag();

            sumAt += at;
            sumPsip += at*(1.0/3.0)*
            (
                sfCorr[facei]
              + pvf[faces[facei][pointi]]
              + pvf[faces[facei][pointi-1]]
            );

        }

        sfCorr[facei] = sumPsip/sumAt - sfCorr[facei];
    }
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>>
Foam::fv::faceCorrectedSnGrad<Type>::fullGradCorrection
(
    const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
    const fvMesh& mesh = this->mesh();

    GeometricField<Type, pointPatchField, pointMesh> pvf
    (
        volPointInterpolation::New(mesh).interpolate(vf)
    );

    // construct GeometricField<Type, fvsPatchField, surfaceMesh>
    tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tsfCorr
    (
        new GeometricField<Type, fvsPatchField, surfaceMesh>
        (
            IOobject
            (
                "snGradCorr("+vf.name()+')',
                vf.instance(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            mesh,
            vf.dimensions()*mesh.nonOrthDeltaCoeffs().dimensions()
        )
    );

    Field<Type>& sfCorr = tsfCorr.ref().internalField();

    const pointField& points = mesh.points();
    const faceList& faces = mesh.faces();
    const vectorField& Sf = mesh.Sf().internalField();
    const vectorField& C = mesh.C().internalField();
    const scalarField& magSf = mesh.magSf().internalField();
    const labelList& owner = mesh.owner();
    const labelList& neighbour = mesh.neighbour();

    forAll(sfCorr, facei)
    {
        typename outerProduct<vector, Type>::type fgrad
        (
            outerProduct<vector, Type>::type::zero
        );

        const face& fi = faces[facei];

        vector nf(Sf[facei]/magSf[facei]);

        for (label pi=0; pi<fi.size(); pi++)
        {
            // Next point index
            label pj = (pi+1)%fi.size();

            // Edge normal in plane of face
            vector edgen(nf^(points[fi[pj]] - points[fi[pi]]));

            // Edge centre field value
            Type pvfe(0.5*(pvf[fi[pj]] + pvf[fi[pi]]));

            // Integrate face gradient
            fgrad += edgen*pvfe;
        }

        // Finalize face-gradient by dividing by face area
        fgrad /= magSf[facei];

        // Calculate correction vector
        vector dCorr(C[neighbour[facei]] - C[owner[facei]]);
        dCorr /= (nf & dCorr);

        // if (mag(dCorr) > 2) dCorr *= 2/mag(dCorr);

        sfCorr[facei] = dCorr&fgrad;
    }
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::linearUpwindV<Type>::correction
(
    const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
    const fvMesh& mesh = this->mesh();

    tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr
    (
        new GeometricField<Type, fvsPatchField, surfaceMesh>
        (
            IOobject
            (
                "linearUpwindCorrection(" + vf.name() + ')',
                mesh.time().timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE,
                false
            ),
            mesh,
            dimensioned<Type>(vf.name(), vf.dimensions(), pTraits<Type>::zero)
        )
    );

    GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr();

    const surfaceScalarField& faceFlux = this->faceFlux_;
    const surfaceScalarField& w = mesh.weights();

    const labelList& own = mesh.owner();
    const labelList& nei = mesh.neighbour();

    const volVectorField& C = mesh.C();
    const surfaceVectorField& Cf = mesh.Cf();

    GeometricField
        <typename outerProduct<vector, Type>::type, fvPatchField, volMesh>
        gradVf = gradScheme_().grad(vf);

    // Note: in order for the patchNeighbourField to be correct on coupled
    // boundaries, correctBoundaryConditions needs to be called.
    // The call shall be moved into the library fvc operators
    gradVf.correctBoundaryConditions();

    forAll(faceFlux, facei)
    {
        vector maxCorr;

        if (faceFlux[facei] > 0)
        {
            maxCorr =
                (1 - w[facei])*(vf[nei[facei]] - vf[own[facei]]);

            sfCorr[facei] =
                (Cf[facei] - C[own[facei]]) & gradVf[own[facei]];
        }
        else
        {
            maxCorr =
                w[facei]*(vf[own[facei]] - vf[nei[facei]]);

            sfCorr[facei] =
                (Cf[facei] - C[nei[facei]]) & gradVf[nei[facei]];
        }

        scalar sfCorrs = magSqr(sfCorr[facei]);
        scalar maxCorrs = sfCorr[facei] & maxCorr;

        if (sfCorrs > 0)
        {
            if (maxCorrs < 0)
            {
                sfCorr[facei] = vector::zero;
            }
            else if (sfCorrs > maxCorrs)
            {
                sfCorr[facei] *= maxCorrs/(sfCorrs + VSMALL);
            }
        }
        else if (sfCorrs < 0)
        {
            if (maxCorrs > 0)
            {
                sfCorr[facei] = vector::zero;
            }
            else if (sfCorrs < maxCorrs)
            {
                sfCorr[facei] *= maxCorrs/(sfCorrs - VSMALL);
            }
        }
    }