Пример #1
0
tmp<GeometricField<Type, fvPatchField, volMesh> > fvMeshSubset::meshToMesh
(
    const GeometricField<Type, fvPatchField, volMesh>& vf,
    const fvMesh& sMesh,
    const labelList& patchMap,
    const labelList& cellMap,
    const labelList& faceMap
)
{
    // Create and map the internal-field values
    Field<Type> internalField(vf.internalField(), cellMap);

    // Create and map the patch field values
    PtrList<fvPatchField<Type> > patchFields(patchMap.size());

    forAll (patchFields, patchI)
    {
        // Set the first one by hand as it corresponds to the
        // exposed internal faces.  Additional interpolation can be put here
        // as necessary.  HJ, date deleted
        if (patchMap[patchI] == -1)
        {
            patchFields.set
            (
                patchI,
                new emptyFvPatchField<Type>
                (
                    sMesh.boundary()[patchI],
                    DimensionedField<Type, volMesh>::null()
                )
            );
        }
        else
        {
            // Construct addressing
            const fvPatch& subPatch = sMesh.boundary()[patchI];
            const fvPatch& basePatch = vf.mesh().boundary()[patchMap[patchI]];
            label baseStart = basePatch.patch().start();
            label baseSize = basePatch.size();

            labelList directAddressing(subPatch.size());

            forAll(directAddressing, i)
            {
                label baseFaceI = faceMap[subPatch.patch().start()+i];

                if (baseFaceI >= baseStart && baseFaceI < baseStart + baseSize)
                {
                    directAddressing[i] = baseFaceI-baseStart;
                }
                else
                {
                    // Mapped from internal face. Do what? Map from element
                    // 0 for now.
                    directAddressing[i] = 0;
                }
            }

            patchFields.set
            (
                patchI,
                fvPatchField<Type>::New
                (
                    vf.boundaryField()[patchMap[patchI]],
                    sMesh.boundary()[patchI],
                    DimensionedField<Type, volMesh>::null(),
                    patchFieldSubset
                    (
                        vf.boundaryField()[patchMap[patchI]].size(),
                        directAddressing
                    )
                )
            );

            // What to do with exposed internal faces if put into this patch?
        }
    }
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
Foam::pointFieldDecomposer::decomposeField
(
    const GeometricField<Type, pointPatchField, pointMesh>& field
) const
{
    // Create and map the internal field values
    Field<Type> internalField(field.internalField(), pointAddressing_);

    // Create a list of pointers for the patchFields
    PtrList<pointPatchField<Type> > patchFields(boundaryAddressing_.size());

    // Create and map the patch field values
    forAll(boundaryAddressing_, patchi)
    {
        if (patchFieldDecomposerPtrs_[patchi])
        {
            patchFields.set
            (
                patchi,
                pointPatchField<Type>::New
                (
                    field.boundaryField()[boundaryAddressing_[patchi]],
                    procMesh_.boundary()[patchi],
                    DimensionedField<Type, pointMesh>::null(),
                    *patchFieldDecomposerPtrs_[patchi]
                )
            );
        }
        else
        {
            patchFields.set
            (
                patchi,
                new processorPointPatchField<Type>
                (
                    procMesh_.boundary()[patchi],
                    DimensionedField<Type, pointMesh>::null()
                )
            );
        }
    }

    // Create the field for the processor
    return tmp<GeometricField<Type, pointPatchField, pointMesh> >
    (
        new GeometricField<Type, pointPatchField, pointMesh>
        (
            IOobject
            (
                field.name(),
                procMesh_().time().timeName(),
                procMesh_(),
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            procMesh_,
            field.dimensions(),
            internalField,
            patchFields
        )
    );
}
tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
tetPointFieldDecomposer::decomposeField
(
    const GeometricField<Type, tetPolyPatchField, tetPointMesh>& field
) const
{
    // Create and map the internal field values
    Field<Type> internalField(field.internalField(), directAddressing());

    // Create and map the patch field values
    PtrList<tetPolyPatchField<Type> > patchFields
    (
        boundaryAddressing_.size() + 1
    );

    forAll (boundaryAddressing_, patchI)
    {
        if (boundaryAddressing_[patchI] >= 0)
        {
            patchFields.set
            (
                patchI,
                tetPolyPatchField<Type>::New
                (
                    field.boundaryField()
                        [boundaryAddressing_[patchI]],
                    processorMesh_.boundary()[patchI],
                    DimensionedField<Type, tetPointMesh>::null(),
                    *patchFieldDecompPtrs_[patchI]
                )
            );
        }
        else
        {
            patchFields.set
            (
                patchI,
                new ProcessorPointPatchField
                <
                    tetPolyPatchField,
                    tetPointMesh,
                    tetPolyPatch,
                    processorTetPolyPatch,
                    tetFemMatrix,
                    Type
                >
                (
                    processorMesh_.boundary()[patchI],
                    DimensionedField<Type, tetPointMesh>::null()
                )
            );
        }
    }

    // Add the global patch by hand.  This needs to be present on
    // all processors
    patchFields.set
    (
        patchFields.size() - 1,
        new GlobalPointPatchField
        <
            tetPolyPatchField,
            tetPointMesh,
            tetPolyPatch,
            globalTetPolyPatch,
            tetFemMatrix,
            Type
        >
        (
            processorMesh_.boundary().globalPatch(),
            DimensionedField<Type, tetPointMesh>::null()
        )
    );

    // Create the field for the processor
    return tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
    (
        new GeometricField<Type, tetPolyPatchField, tetPointMesh>
        (
            IOobject
            (
                field.name(),
                processorMesh_().time().timeName(),
                processorMesh_(),
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            processorMesh_,
            field.dimensions(),
            internalField,
            patchFields
        )
    );
}
tmp
<
    GeometricField
    <
        typename outerProduct<vector, Type>::type,
        tetPolyPatchField,
        tetPointMesh
    >
> 
tetFec::grad
(
    const GeometricField<Type, tetPolyPatchField, tetPointMesh>& psi
)
{
    typedef typename outerProduct<vector, Type>::type GradType;

    const tetPolyMesh& tetMesh = psi.mesh();

    tmp<GeometricField<GradType, tetPolyPatchField, tetPointMesh> > tFemGrad
    (
        new GeometricField<GradType, tetPolyPatchField, tetPointMesh>
        (
            IOobject
            (
                "grad("+psi.name()+')',
                psi.instance(),
                psi.db(),
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            tetMesh,
            dimensioned<GradType>
            (
                "zero",
                psi.dimensions()/dimLength,
                pTraits<GradType>::zero
            )
        )
    );

    GeometricField<GradType, tetPolyPatchField, tetPointMesh>& femGrad = 
        tFemGrad();

    pointField points = tetMesh.points();
    cellShapeList tetCellShapes = tetMesh.tetCells();

    scalarField weights (points.size(), 0.0);

    forAll (tetCellShapes, tetI)
    {
        cellShape& curShape = tetCellShapes[tetI];

        tetPointRef curTetrahedron
        (
            points[curShape[0]],
            points[curShape[1]],
            points[curShape[2]],
            points[curShape[3]]
        );

        GradType tetGrad = 
          - (1.0/3.0)*
            (
                curTetrahedron.Sa()*psi.internalField()[curShape[0]]
              + curTetrahedron.Sb()*psi.internalField()[curShape[1]]
              + curTetrahedron.Sc()*psi.internalField()[curShape[2]]
              + curTetrahedron.Sd()*psi.internalField()[curShape[3]]
            )/curTetrahedron.mag();

        forAll (curShape, pointI)
        {
            scalar weight = 
                curTetrahedron.mag()/
                mag
                (
                    points[curShape[pointI]]
                  - curShape.centre(points)
                );

            femGrad.internalField()[curShape[pointI]] += weight*tetGrad;

            weights[curShape[pointI]] += weight;
        }
tmp<GeometricField<Type, fvPatchField, volMesh> > fvMeshSubset::interpolate
(
    const GeometricField<Type, fvPatchField, volMesh>& vf,
    const fvMesh& sMesh,
    const labelList& patchMap,
    const labelList& cellMap,
    const labelList& faceMap
)
{
    // 1. Create the complete field with dummy patch fields
    PtrList<fvPatchField<Type> > patchFields(patchMap.size());

    forAll(patchFields, patchI)
    {
        // Set the first one by hand as it corresponds to the
        // exposed internal faces. Additional interpolation can be put here
        // as necessary.
        if (patchMap[patchI] == -1)
        {
            patchFields.set
            (
                patchI,
                new emptyFvPatchField<Type>
                (
                    sMesh.boundary()[patchI],
                    DimensionedField<Type, volMesh>::null()
                )
            );
        }
        else
        {
            patchFields.set
            (
                patchI,
                fvPatchField<Type>::New
                (
                    calculatedFvPatchField<Type>::typeName,
                    sMesh.boundary()[patchI],
                    DimensionedField<Type, volMesh>::null()
                )
            );
        }
    }

    tmp<GeometricField<Type, fvPatchField, volMesh> > tresF
    (
        new GeometricField<Type, fvPatchField, volMesh>
        (
            IOobject
            (
                "subset"+vf.name(),
                sMesh.time().timeName(),
                sMesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            sMesh,
            vf.dimensions(),
            Field<Type>(vf.internalField(), cellMap),
            patchFields
        )
    );
    GeometricField<Type, fvPatchField, volMesh>& resF = tresF();


    // 2. Change the fvPatchFields to the correct type using a mapper
    //  constructor (with reference to the now correct internal field)

    typename GeometricField<Type, fvPatchField, volMesh>::
        GeometricBoundaryField& bf = resF.boundaryField();

    forAll(bf, patchI)
    {
        if (patchMap[patchI] != -1)
        {
            // Construct addressing
            const fvPatch& subPatch = sMesh.boundary()[patchI];
            const fvPatch& basePatch = vf.mesh().boundary()[patchMap[patchI]];
            const label baseStart = basePatch.start();
            const label baseSize = basePatch.size();

            labelList directAddressing(subPatch.size());

            forAll(directAddressing, i)
            {
                label baseFaceI = faceMap[subPatch.start()+i];

                if (baseFaceI >= baseStart && baseFaceI < baseStart+baseSize)
                {
                    directAddressing[i] = baseFaceI-baseStart;
                }
                else
                {
                    // Mapped from internal face. Do what? Leave up to
                    // fvPatchField
                    directAddressing[i] = -1;
                }
            }

            bf.set
            (
                patchI,
                fvPatchField<Type>::New
                (
                    vf.boundaryField()[patchMap[patchI]],
                    subPatch,
                    resF.dimensionedInternalField(),
                    directFvPatchFieldMapper(directAddressing)
                )
            );
        }
    }