void Foam::fvMeshTools::addPatchFields
(
    fvMesh& mesh,
    const dictionary& patchFieldDict,
    const word& defaultPatchFieldType,
    const typename GeoField::value_type& defaultPatchValue
)
{
    HashTable<GeoField*> flds
    (
        mesh.objectRegistry::lookupClass<GeoField>()
    );

    forAllIter(typename HashTable<GeoField*>, flds, iter)
    {
        GeoField& fld = *iter();

        typename GeoField::GeometricBoundaryField& bfld =
            fld.boundaryField();

        label sz = bfld.size();
        bfld.setSize(sz+1);

        if (patchFieldDict.found(fld.name()))
        {
            bfld.set
            (
                sz,
                GeoField::PatchFieldType::New
                (
                    mesh.boundary()[sz],
                    fld.dimensionedInternalField(),
                    patchFieldDict.subDict(fld.name())
                )
            );
        }
        else
        {
            bfld.set
            (
                sz,
                GeoField::PatchFieldType::New
                (
                    defaultPatchFieldType,
                    mesh.boundary()[sz],
                    fld.dimensionedInternalField()
                )
            );
            bfld[sz] == defaultPatchValue;
        }
    }
}
Exemple #2
0
void calcYPlus
(
    const TurbulenceModel& turbulenceModel,
    const fvMesh& mesh,
    const volVectorField& U,
    volScalarField& yPlus
)
{
    volScalarField::GeometricBoundaryField d = nearWallDist(mesh).y();

    const volScalarField::GeometricBoundaryField nutBf =
        turbulenceModel->nut()().boundaryField();

    const volScalarField::GeometricBoundaryField nuEffBf =
        turbulenceModel->nuEff()().boundaryField();

    const volScalarField::GeometricBoundaryField nuBf =
        turbulenceModel->nu()().boundaryField();

    const fvPatchList& patches = mesh.boundary();

    forAll(patches, patchi)
    {
        const fvPatch& patch = patches[patchi];

        if (isA<nutWallFunctionFvPatchScalarField>(nutBf[patchi]))
        {
            const nutWallFunctionFvPatchScalarField& nutPf =
                dynamic_cast<const nutWallFunctionFvPatchScalarField&>
                (
                    nutBf[patchi]
                );

            yPlus.boundaryField()[patchi] = nutPf.yPlus();
            const scalarField& Yp = yPlus.boundaryField()[patchi];

            Info<< "Patch " << patchi
                << " named " << nutPf.patch().name()
                << ", wall-function " << nutPf.type()
                << ", y+ : min: " << gMin(Yp) << " max: " << gMax(Yp)
                << " average: " << gAverage(Yp) << nl << endl;
        }
        else if (isA<wallFvPatch>(patch))
        {
            yPlus.boundaryField()[patchi] =
                d[patchi]
               *sqrt
                (
                    nuEffBf[patchi]
                   *mag(U.boundaryField()[patchi].snGrad())
                )/nuBf[patchi];
            const scalarField& Yp = yPlus.boundaryField()[patchi];

            Info<< "Patch " << patchi
                << " named " << patch.name()
                << " y+ : min: " << gMin(Yp) << " max: " << gMax(Yp)
                << " average: " << gAverage(Yp) << nl << endl;
        }
    }
}
void Foam::fvMeshTools::setPatchFields
(
    fvMesh& mesh,
    const label patchI,
    const dictionary& patchFieldDict
)
{
    HashTable<GeoField*> flds
    (
        mesh.objectRegistry::lookupClass<GeoField>()
    );

    forAllIter(typename HashTable<GeoField*>, flds, iter)
    {
        GeoField& fld = *iter();

        typename GeoField::GeometricBoundaryField& bfld =
            fld.boundaryField();

        if (patchFieldDict.found(fld.name()))
        {
            bfld.set
            (
                patchI,
                GeoField::PatchFieldType::New
                (
                    mesh.boundary()[patchI],
                    fld.dimensionedInternalField(),
                    patchFieldDict.subDict(fld.name())
                )
            );
        }
    }
}
void printSum
(
    const fvMesh& mesh,
    const IOobject& fieldHeader,
    const label patchI,
    bool& done
)
{
    if (!done && fieldHeader.headerClassName() == FieldType::typeName)
    {
        Info<< "    Reading " << FieldType::typeName << " "
            << fieldHeader.name() << endl;

        FieldType field(fieldHeader, mesh);
        typename FieldType::value_type sumField = gSum
        (
            field.boundaryField()[patchI]
        );

        Info<< "    Integral of " << fieldHeader.name() << " over patch "
            << mesh.boundary()[patchI].name() << '[' << patchI << ']' << " = "
            << sumField << nl;

        done = true;
    }
}
// Inplace add mesh1 to mesh0
Foam::autoPtr<Foam::mapAddedPolyMesh> Foam::fvMeshAdder::add
(
    fvMesh& mesh0,
    const fvMesh& mesh1,
    const faceCoupleInfo& coupleInfo,
    const bool validBoundary
)
{
    mesh0.clearOut();

    // Resulting merged mesh (polyMesh only!)
    autoPtr<mapAddedPolyMesh> mapPtr
    (
        polyMeshAdder::add
        (
            mesh0,
            mesh1,
            coupleInfo,
            validBoundary
        )
    );

    // Adjust the fvMesh part.
    const polyBoundaryMesh& patches = mesh0.boundaryMesh();

    fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh0.boundary());
    fvPatches.setSize(patches.size());
    forAll(patches, patchI)
    {
        fvPatches.set(patchI, fvPatch::New(patches[patchI], fvPatches));
    }
void printIntegrate
(
    const fvMesh& mesh,
    const IOobject& fieldHeader,
    const label patchI,
    bool& done
)
{
    if (!done && fieldHeader.headerClassName() == FieldType::typeName)
    {
        Info<< "    Reading " << fieldHeader.headerClassName() << " "
            << fieldHeader.name() << endl;

        FieldType field(fieldHeader, mesh);

        Info<< "    Integral of " << fieldHeader.name()
            << " over vector area of patch "
            << mesh.boundary()[patchI].name() << '[' << patchI << ']' << " = "
            << gSum
               (
                   mesh.Sf().boundaryField()[patchI]
                  *field.boundaryField()[patchI]
               )
            << nl;

        Info<< "    Integral of " << fieldHeader.name()
            << " over area magnitude of patch "
            << mesh.boundary()[patchI].name() << '[' << patchI << ']' << " = "
            << gSum
               (
                   mesh.magSf().boundaryField()[patchI]
                  *field.boundaryField()[patchI]
               )
            << nl;

        done = true;
    }
}
Exemple #7
0
void Foam::functionObjects::yPlus::calcYPlus
(
    const turbulenceModel& turbModel,
    const fvMesh& mesh,
    volScalarField& yPlus
)
{
    volScalarField::Boundary d = nearWallDist(mesh).y();

    const volScalarField::Boundary nutBf =
        turbModel.nut()().boundaryField();

    const volScalarField::Boundary nuEffBf =
        turbModel.nuEff()().boundaryField();

    const volScalarField::Boundary nuBf =
        turbModel.nu()().boundaryField();

    const fvPatchList& patches = mesh.boundary();

    volScalarField::Boundary& yPlusBf = yPlus.boundaryFieldRef();

    forAll(patches, patchi)
    {
        const fvPatch& patch = patches[patchi];

        if (isA<nutWallFunctionFvPatchScalarField>(nutBf[patchi]))
        {
            const nutWallFunctionFvPatchScalarField& nutPf =
                dynamic_cast<const nutWallFunctionFvPatchScalarField&>
                (
                    nutBf[patchi]
                );

            yPlusBf[patchi] = nutPf.yPlus();
        }
        else if (isA<wallFvPatch>(patch))
        {
            yPlusBf[patchi] =
                d[patchi]
               *sqrt
                (
                    nuEffBf[patchi]
                   *mag(turbModel.U().boundaryField()[patchi].snGrad())
                )/nuBf[patchi];
        }
    }
}
void printAverage
(
    const fvMesh& mesh,
    const IOobject& fieldHeader,
    const scalar area,
    const label patchI,
    bool& done
)
{
    if (!done && fieldHeader.headerClassName() == FieldType::typeName)
    {
        Info<< "    Reading " << fieldHeader.headerClassName() << " "
            << fieldHeader.name() << endl;

        FieldType field(fieldHeader, mesh);

        typename FieldType::value_type sumField =
            pTraits<typename FieldType::value_type>::zero;

        if (area > 0)
        {
            sumField = gSum
            (
                mesh.magSf().boundaryField()[patchI]
              * field.boundaryField()[patchI]
            ) / area;
        }

        Info<< "    Average of " << fieldHeader.headerClassName()
            << " over patch "
            << mesh.boundary()[patchI].name()
            << '[' << patchI << ']' << " = "
            << sumField << endl;

        done = true;
    }
}
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
)
{
    // 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.  
        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(directAddressing)
                )
            );

            // What to do with exposed internal faces if put into this patch?
        }
    }
tmp<GeometricField<Type, fvPatchField, volMesh> >
autoCreateWallFunctionField
(
    const word& fieldName,
    const fvMesh& mesh,
    const objectRegistry& obj
)
{
    IOobject nutHeader
    (
        "nut",
        mesh.time().timeName(),
        obj,
        IOobject::MUST_READ
    );

    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;

    if (nutHeader.headerOk())
    {
        return tmp<fieldType>
        (
            new fieldType
            (
                IOobject
                (
                    fieldName,
                    mesh.time().timeName(),
                    obj,
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE,
                    false
                ),
                mesh
            )
        );
    }
    else
    {
        Info<< "--> Upgrading " << fieldName
            << " to employ run-time selectable wall functions" << endl;

        // Read existing field
        IOobject ioObj
        (
            fieldName,
            mesh.time().timeName(),
            obj,
            IOobject::MUST_READ,
            IOobject::NO_WRITE,
            false
        );

        tmp<fieldType> fieldOrig
        (
            new fieldType
            (
                ioObj,
                mesh
            )
        );

        // rename file
        Info<< "    Backup original " << fieldName << " to "
            << fieldName << ".old" << endl;
        mvBak(ioObj.objectPath(), "old");


        PtrList<fvPatchField<Type> > newPatchFields(mesh.boundary().size());

        forAll(newPatchFields, patchI)
        {
            if (mesh.boundary()[patchI].isWall())
            {
                newPatchFields.set
                (
                    patchI,
                    new PatchType
                    (
                        mesh.boundary()[patchI],
                        fieldOrig().dimensionedInternalField()
                    )
                );
                newPatchFields[patchI] == fieldOrig().boundaryField()[patchI];
            }
            else
            {
                newPatchFields.set
                (
                    patchI,
                    fieldOrig().boundaryField()[patchI].clone()
                );
            }
        }

        tmp<fieldType> fieldNew
        (
            new fieldType
            (
                IOobject
                (
                    fieldName,
                    mesh.time().timeName(),
                    obj,
                    IOobject::NO_READ,
                    IOobject::NO_WRITE,
                    false
                ),
                mesh,
                fieldOrig().dimensions(),
                fieldOrig().internalField(),
                newPatchFields
            )
        );

        Info<< "    Writing updated " << fieldName << endl;
        fieldNew().write();

        return fieldNew;
    }
}
void Foam::yPlus::calcYPlus
(
    const TurbulenceModel& turbulenceModel,
    const fvMesh& mesh,
    volScalarField& yPlus
)
{
    volScalarField::GeometricBoundaryField d = nearWallDist(mesh).y();

    const volScalarField::GeometricBoundaryField nutBf =
        turbulenceModel.nut()().boundaryField();

    const volScalarField::GeometricBoundaryField nuEffBf =
        turbulenceModel.nuEff()().boundaryField();

    const volScalarField::GeometricBoundaryField nuBf =
        turbulenceModel.nu()().boundaryField();

    const fvPatchList& patches = mesh.boundary();

    forAll(patches, patchi)
    {
        const fvPatch& patch = patches[patchi];

        if (isA<nutWallFunctionFvPatchScalarField>(nutBf[patchi]))
        {
            const nutWallFunctionFvPatchScalarField& nutPf =
                dynamic_cast<const nutWallFunctionFvPatchScalarField&>
                (
                    nutBf[patchi]
                );

            yPlus.boundaryField()[patchi] = nutPf.yPlus();
            const scalarField& yPlusp = yPlus.boundaryField()[patchi];

            const scalar minYplus = gMin(yPlusp);
            const scalar maxYplus = gMax(yPlusp);
            const scalar avgYplus = gAverage(yPlusp);

            if (Pstream::master())
            {
                if (log_) Info
                    << "    patch " << patch.name()
                    << " y+ : min = " << minYplus << ", max = " << maxYplus
                    << ", average = " << avgYplus << nl;

                file() << obr_.time().value()
                    << token::TAB << patch.name()
                    << token::TAB << minYplus
                    << token::TAB << maxYplus
                    << token::TAB << avgYplus
                    << endl;
            }
        }
        else if (isA<wallFvPatch>(patch))
        {
            yPlus.boundaryField()[patchi] =
                d[patchi]
               *sqrt
                (
                    nuEffBf[patchi]
                   *mag(turbulenceModel.U().boundaryField()[patchi].snGrad())
                )/nuBf[patchi];
            const scalarField& yPlusp = yPlus.boundaryField()[patchi];

            const scalar minYplus = gMin(yPlusp);
            const scalar maxYplus = gMax(yPlusp);
            const scalar avgYplus = gAverage(yPlusp);

            if (Pstream::master())
            {
                if (log_) Info
                    << "    patch " << patch.name()
                    << " y+ : min = " << minYplus << ", max = " << maxYplus
                    << ", average = " << avgYplus << nl;

                file() << obr_.time().value()
                    << token::TAB << patch.name()
                    << token::TAB << minYplus
                    << token::TAB << maxYplus
                    << token::TAB << avgYplus
                    << endl;
            }
        }
    }
}
Exemple #12
0
void Foam::yPlusLES::calcIncompressibleYPlus
(
    const fvMesh& mesh,
    const volVectorField& U,
    volScalarField& yPlus
)
{
    const incompressible::LESModel& model =
        mesh.lookupObject<incompressible::LESModel>("LESProperties");

    volScalarField::GeometricBoundaryField d = nearWallDist(mesh).y();
    volScalarField nuEff(model.nuEff());

    const fvPatchList& patches = mesh.boundary();

    const volScalarField nuLam(model.nu());

    bool foundPatch = false;
    forAll(patches, patchI)
    {
        const fvPatch& currPatch = patches[patchI];

        if (isA<wallFvPatch>(currPatch))
        {
            foundPatch = true;
            yPlus.boundaryField()[patchI] =
                d[patchI]
               *sqrt
                (
                    nuEff.boundaryField()[patchI]
                   *mag(U.boundaryField()[patchI].snGrad())
                )
               /nuLam.boundaryField()[patchI];

            const scalarField& Yp = yPlus.boundaryField()[patchI];

            scalar minYp = gMin(Yp);
            scalar maxYp = gMax(Yp);
            scalar avgYp = gAverage(Yp);

            if (log_)
            {
                Info<< "    patch " << currPatch.name()
                    << " y+ : min = " << minYp << ", max = " << maxYp
                    << ", average = " << avgYp << nl;
            }

            if (Pstream::master())
            {
                file() << obr_.time().value() << token::TAB
                    << currPatch.name() << token::TAB
                    << minYp << token::TAB << maxYp << token::TAB
                    << avgYp << endl;
            }
        }
    }

    if (log_ && !foundPatch)
    {
        Info<< "    no " << wallFvPatch::typeName << " patches" << endl;
    }
}
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)
                )
            );
        }
    }