void replaceBoundaryType
(
    const fvMesh& mesh,
    const word& fieldName,
    const word& boundaryType,
    const string& boundaryValue
)
{
    IOobject header
    (
        fieldName,
        mesh.time().timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::NO_WRITE
    );

    if (!header.headerOk())
    {
        return;
    }

    Info<< "Updating boundary types for field " << header.name() << endl;

    const word oldTypeName = IOdictionary::typeName;
    const_cast<word&>(IOdictionary::typeName) = word::null;

    IOdictionary dict(header);

    const_cast<word&>(IOdictionary::typeName) = oldTypeName;
    const_cast<word&>(dict.type()) = dict.headerClassName();

    // Make a backup of the old file
    if (mvBak(dict.objectPath(), "old"))
    {
        Info<< "    Backup original file to "
            << (dict.objectPath() + ".old") << endl;
    }

    // Loop through boundary patches and update
    const polyBoundaryMesh& bMesh = mesh.boundaryMesh();
    dictionary& boundaryDict = dict.subDict("boundaryField");
    forAll(bMesh, patchI)
    {
        if (isA<wallPolyPatch>(bMesh[patchI]))
        {
            word patchName = bMesh[patchI].name();
            dictionary& oldPatch = boundaryDict.subDict(patchName);

            dictionary newPatch(dictionary::null);
            newPatch.add("type", boundaryType);
            newPatch.add("value", ("uniform " + boundaryValue).c_str());

            oldPatch = newPatch;
        }
    }

    Info<< "    writing updated " << dict.name() << nl << endl;
    dict.regIOobject::write();
}
Beispiel #2
0
Foam::surfMesh::surfMesh(const IOobject& io, const word& surfName)
:
    surfaceRegistry(io.db(), (surfName.size() ? surfName : io.name())),
    Allocator
    (
        IOobject
        (
            "points",
            time().findInstance(meshDir(), "points"),
            meshSubDir,
            *this,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        ),
        IOobject
        (
            "faces",
            time().findInstance(meshDir(), "faces"),
            meshSubDir,
            *this,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        ),
        IOobject
        (
            "surfZones",
            time().findInstance(meshDir(), "surfZones"),
            meshSubDir,
            *this,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    ),
    MeshReference(this->storedIOFaces(), this->storedIOPoints())
{}
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::fvFieldReconstructor::reconstructFvVolumeField
(
    const IOobject& fieldIoObject
)
{
    // Read the field for all the processors
    PtrList<GeometricField<Type, fvPatchField, volMesh> > procFields
    (
        procMeshes_.size()
    );

    forAll (procMeshes_, procI)
    {
        procFields.set
        (
            procI,
            new GeometricField<Type, fvPatchField, volMesh>
            (
                IOobject
                (
                    fieldIoObject.name(),
                    procMeshes_[procI].time().timeName(),
                    procMeshes_[procI],
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE
                ),
                procMeshes_[procI]
            )
        );
    }
Foam::IOobject Foam::IOMRFZoneList::createIOobject
(
    const fvMesh& mesh
) const
{
    IOobject io
    (
        "MRFProperties",
        mesh.time().constant(),
        mesh,
        IOobject::MUST_READ,
        IOobject::NO_WRITE
    );

    if (io.headerOk())
    {
        Info<< "Creating MRF zone list from " << io.name() << endl;

        io.readOpt() = IOobject::MUST_READ_IF_MODIFIED;
        return io;
    }
    else
    {
        Info<< "No MRF models present" << nl << endl;

        io.readOpt() = IOobject::NO_READ;
        return io;
    }
}
tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
tetPointFieldReconstructor::reconstructTetPointField
(
    const IOobject& fieldIoObject
)
{
    // Read the field for all the processors
    PtrList<GeometricField<Type, tetPolyPatchField, tetPointMesh> > procFields
    (
        procMeshes_.size()
    );

    forAll (procMeshes_, procI)
    {
        procFields.set
        (
            procI,
            new GeometricField<Type, tetPolyPatchField, tetPointMesh>
            (
                IOobject
                (
                    fieldIoObject.name(),
                    procMeshes_[procI]().time().timeName(),
                    procMeshes_[procI](),
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE
                ),
                procMeshes_[procI]
            )
        );
    }
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh> >
Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
(
    const IOobject& fieldIoObject
) const
{
    // Read the field for all the processors
    PtrList<DimensionedField<Type, volMesh> > procFields
    (
        procMeshes_.size()
    );

    forAll(procMeshes_, procI)
    {
        procFields.set
        (
            procI,
            new DimensionedField<Type, volMesh>
            (
                IOobject
                (
                    fieldIoObject.name(),
                    procMeshes_[procI].time().timeName(),
                    procMeshes_[procI],
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE
                ),
                procMeshes_[procI]
            )
        );
    }
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh>>
Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
{
    // Read the field for all the processors
    PtrList<GeometricField<Type, pointPatchField, pointMesh>> procFields
    (
        procMeshes_.size()
    );

    forAll(procMeshes_, proci)
    {
        procFields.set
        (
            proci,
            new GeometricField<Type, pointPatchField, pointMesh>
            (
                IOobject
                (
                    fieldIoObject.name(),
                    procMeshes_[proci]().time().timeName(),
                    procMeshes_[proci](),
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE
                ),
                procMeshes_[proci]
            )
        );
    }
Foam::IOobject Foam::IOporosityModelList::createIOobject
(
    const fvMesh& mesh
) const
{
    IOobject io
    (
        "porosityProperties",
        mesh.time().constant(),
        mesh,
        IOobject::MUST_READ,
        IOobject::NO_WRITE
    );

    if (io.typeHeaderOk<IOdictionary>(true))
    {
        Info<< "Creating porosity model list from " << io.name() << nl << endl;

        io.readOpt() = IOobject::MUST_READ_IF_MODIFIED;
        return io;
    }
    else
    {
        Info<< "No porosity models present" << nl << endl;

        io.readOpt() = IOobject::NO_READ;
        return io;
    }
}
Foam::IOobject Foam::fv::IOoptionList::createIOobject
(
    const fvMesh& mesh
) const
{
    IOobject io
    (
        "fvOptions",
        mesh.time().system(),
        mesh,
        IOobject::MUST_READ,
        IOobject::NO_WRITE
    );

    if (io.headerOk())
    {
        Info<< "Creating fintite volume options from " << io.name() << nl
            << endl;

        io.readOpt() = IOobject::MUST_READ_IF_MODIFIED;
        return io;
    }
    else
    {
        Info<< "No finite volume options present" << nl << endl;

        io.readOpt() = IOobject::NO_READ;
        return io;
    }
}
void Foam::calcTypes::minMaxMag::writeMinMaxMagField
(
    const IOobject& header,
    const fvMesh& mesh,
    bool& processed
)
{
    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;

    if (header.headerClassName() == fieldType::typeName)
    {
        Info<< "    Reading " << header.name() << endl;
        fieldType field(header, mesh);

        Info<< "    Calculating min" << header.name() << ": " << Foam::gMin(Foam::mag(field)()) << endl;
        Info<< "    Calculating max" << header.name() << ": " << Foam::gMax(Foam::mag(field)()) << endl;

        processed = true;
    }
}
Foam::tmp<GeoField> Foam::uniformInterpolate
(
    const IOobject& fieldIO,
    const word& fieldName,
    const wordList& times,
    const scalarField& weights,
    const objectRegistry& fieldsCache
)
{
    // Look up the first field
    const objectRegistry& time0Fields = fieldsCache.lookupObject
    <
        const objectRegistry
    >
    (
        times[0]
    );
    const GeoField& field0 = time0Fields.lookupObject
    <
        const GeoField
    >
    (
        fieldName
    );


    // Interpolate
    tmp<GeoField> tfld(GeoField::New(fieldIO.name(), weights[0]*field0));
    GeoField& fld = tfld.ref();

    for (label i = 1; i < times.size(); ++i)
    {
        const objectRegistry& timeIFields = fieldsCache.lookupObject
        <
            const objectRegistry
        >
        (
            times[i]
        );
        const GeoField& fieldi = timeIFields.lookupObject
        <
            const GeoField
        >
        (
            fieldName
        );

        fld += weights[i]*fieldi;
    }

    return tfld;
}
void Foam::calcTypes::domainIntegrate::calcDomainIntegrate
(
    const IOobject& header,
    const fvMesh& mesh,
    bool& processed
)
{
    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;

    if (header.headerClassName() == fieldType::typeName)
    {
        Info<< "    Reading " << header.name() << endl;
        fieldType field(header, mesh);

        Info<< "    Calculating domain integral for field "
            << header.name() << nl
            << "    " << fvc::domainIntegrate(field)
            << endl;

        processed = true;
    }
}
Beispiel #13
0
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;
    }
}
Beispiel #14
0
void printIntegrate
(
    const fvMesh& mesh,
    const IOobject& fieldHeader,
    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 full fluid volume = "
            << gSum(mesh.V()*field.internalField()) << " "
            << field.dimensions()*dimVolume
            << nl;

        done = true;
    }
}
void Foam::calcTypes::average::writeAverageField
(
    const IOobject& header,
    const fvMesh& mesh,
    bool& processed
)
{
    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;

    if (header.headerClassName() == fieldType::typeName)
    {
        Info<< "    Reading " << header.name() << endl;
        fieldType field(header, mesh);

        dimensioned<Type> avg ("avg", field.dimensions(), pTraits<Type>::zero);
        
        avg = field.weightedAverage(mesh.V());;

        Info<< "    Calculating average(" << header.name() << "): " << avg << endl;

        processed = true;
    }
}
void Foam::calcTypes::maxAbs::writeMaxField
(
    const IOobject& header,
    const fvMesh& mesh,
    bool& processed
)
{
    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;

    if (header.headerClassName() == fieldType::typeName)
    {
        Info<< "    Reading " << header.name() << endl;
        fieldType field(header, mesh);

        dimensioned<Type> maxVal = Foam::gMax(field);
        dimensioned<Type> minVal = Foam::gMin(field);

        Info<< "    Calculating maxAbs" << header.name() << ": " << Foam::max(mag(maxVal), mag(minVal)).value() << endl;
        //Info<< "       MAX: " << Foam::maxAbs(field) << endl;

        processed = true;
    }
}
Beispiel #17
0
void Foam::calcTypes::mag::writeMagField
(
    const IOobject& header,
    const fvMesh& mesh,
    bool& processed
)
{
    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;

    if (header.headerClassName() == fieldType::typeName)
    {
        Info<< "    Reading " << header.name() << endl;
        fieldType field(header, mesh);

        Info<< "    Calculating mag" << header.name() << endl;
        volScalarField magField
        (
            IOobject
            (
                "mag" + header.name(),
                mesh.time().timeName(),
                mesh,
                IOobject::NO_READ
            ),
            Foam::mag(field)
        );

        Info << "mag(" << header.name() << "): max: "
            << gMax(magField.internalField())
            << " min: " << gMin(magField.internalField()) << endl;

        magField.write();

        processed = true;
    }
}
Foam::fileName Foam::fileOperations::autoParallelFileOperation::filePath
(
    const bool checkGlobal,
    const IOobject& io,
    const word& typeName
) const
{
    if (debug)
    {
        Pout<< indent
            << "autoParallelFileOperation::filePath :"
            << " objectPath:" << io.objectPath()
            << " checkGlobal:" << checkGlobal << endl;
    }

    // Try uncollated searching
    fileName objPath = uncollatedFileOperation::filePath
    (
        checkGlobal,
        io,
        typeName
    );

    // If not found and parallel check parent
    if (objPath.empty() && io.time().processorCase()) // && checkGlobal)
    {
        fileName parentObjectPath =
            io.rootPath()/io.time().globalCaseName()
           /io.instance()/io.db().dbDir()/io.local()/io.name();

        if (isFile(parentObjectPath))
        {
            objPath = parentObjectPath;
        }
    }

    if (debug)
    {
        Pout<< indent
            << "autoParallelFileOperation::filePath :"
            << " Returning from file searching:" << endl
            << "    objectPath:" << io.objectPath() << endl
            << "    filePath  :" << objPath << endl << endl;
    }
    return objPath;
}
Beispiel #19
0
Foam::surfMesh::surfMesh
(
    const IOobject& io,
    const Xfer<pointField>& pointLst,
    const Xfer<faceList>& faceLst,
    const word& surfName
)
:
    surfaceRegistry(io.db(), (surfName.size() ? surfName : io.name())),
    Allocator
    (
        IOobject
        (
            "points",
            instance(),
            meshSubDir,
            *this,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        pointLst,
        IOobject
        (
            "faces",
            instance(),
            meshSubDir,
            *this,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        faceLst,
        IOobject
        (
            "surfZones",
            instance(),
            meshSubDir,
            *this,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        Xfer<surfZoneList>()
    ),
    MeshReference(this->storedIOFaces(), this->storedIOPoints())
{}
void Foam::addToFieldList
(
    PtrList<GeometricField<Type, fvPatchField, volMesh> >& fieldList,
    const IOobject& obj,
    const label fieldI,
    const fvMesh& mesh
)
{
    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;

    if (obj.headerClassName() == fieldType::typeName)
    {
        fieldList.set
        (
            fieldI,
            new fieldType(obj, mesh)
        );
        Info<< "    " << fieldType::typeName << tab << obj.name() << endl;
    }
}
Beispiel #21
0
void printIntegrate
(
    const fvMesh& mesh,
    const IOobject& fieldHeader,
    bool& done
)
{
    if (!done && fieldHeader.headerClassName() == FieldType::typeName)
    {
        Info<< "    Reading " << fieldHeader.headerClassName() << " "
            << fieldHeader.name() << " ";

        FieldType field(fieldHeader, mesh);

        Info<< field.dimensions() <<  endl;


        Info<< "        min : " << gMin(field) << nl
            << "        max : " << gMax(field) << nl;

        done = true;
    }
}
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;
    }
}
void Foam::calcTypes::randomise::writeRandomField
(
    const IOobject& header,
    const scalar pertMag,
    Random& rand,
    const fvMesh& mesh,
    bool& processed
)
{
    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;

    if (header.headerClassName() == fieldType::typeName)
    {
        Info<< "    Reading " << header.name() << endl;
        fieldType field(header, mesh);

        forAll(field, cellI)
        {
            Type rndPert;
            rand.randomise(rndPert);
            rndPert = 2.0*rndPert - pTraits<Type>::one;
            rndPert /= mag(rndPert);
            field[cellI] += pertMag*rndPert;
        }
Foam::solidDisplacementFvMotionSolver::solidDisplacementFvMotionSolver
(
    const polyMesh& mesh,
    Istream& is
)
:
    displacementFvMotionSolver(mesh, is),
    pointDisplacement_
    (
        IOobject
        (
            "pointDisplacement",
            fvMesh_.time().timeName(),
            fvMesh_,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        pointMesh::New(fvMesh_),
        dimensionedVector
        (
            "pointDisplacement",
            dimLength,
            vector::zero
        )
    ),
    cellDisplacement_
    (
        IOobject
        (
            "cellDisplacement",
            mesh.time().timeName(),
            mesh,
            IOobject::READ_IF_PRESENT,
            IOobject::AUTO_WRITE
        ),
        fvMesh_,
        dimensionedVector
        (
            "cellDisplacement",
            dimLength,
            vector::zero
        ) //,
//         cellMotionBoundaryTypes<vector>(pointDisplacement_.boundaryField())
    ),
    pointLocation_(NULL),
//     diffusivityPtr_
//     (
//         motionDiffusivity::New(*this, lookup("diffusivity"))
//     ),
    frozenPointsZone_
    (
        found("frozenPointsZone")
      ? fvMesh_.pointZones().findZoneID(lookup("frozenPointsZone"))
      : -1
    )
{
    IOobject io
    (
        "pointLocation",
        fvMesh_.time().timeName(),
        fvMesh_,
        IOobject::MUST_READ,
        IOobject::AUTO_WRITE
    );

    if (debug)
    {
        Info<< "solidDisplacementFvMotionSolver:" << nl
//             << "    diffusivity       : " << diffusivityPtr_().type() << nl
            << "    frozenPoints zone : " << frozenPointsZone_ << endl;
    }


    if (io.headerOk())
    {
        pointLocation_.reset
        (
            new pointVectorField
            (
                io,
                pointMesh::New(fvMesh_)
            )
        );

        if (debug)
        {
            Info<< "solidDisplacementFvMotionSolver :"
                << " Read pointVectorField "
                << io.name() << " to be used for boundary conditions on points."
                << nl
                << "Boundary conditions:"
                << pointLocation_().boundaryField().types() << endl;
        }
    }
}
void Foam::calcTypes::scalarMult::writeAddSubtractField
(
    const IOobject& baseHeader,
    const IOobject& addHeader,
    const fvMesh& mesh,
    bool& processed
)
{
    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;

    if
    (
        baseHeader.headerClassName() == fieldType::typeName
     && baseHeader.headerClassName() == addHeader.headerClassName()
    )
    {
        if (resultName_ == "")
        {
            if (calcMode_ == ADD)
            {
                resultName_ = baseHeader.name() + "_add_" + addHeader.name();
            }
            else
            {
                resultName_ = baseHeader.name() + "_subtract_"
                    + addHeader.name();
            }
        }

        Info<< "    Reading " << baseHeader.name() << endl;
        fieldType baseField(baseHeader, mesh);

        Info<< "    Reading " << addHeader.name() << endl;
        fieldType addField(addHeader, mesh);

        if (baseField.dimensions() == addField.dimensions())
        {
            Info<< "    Calculating " << resultName_ << endl;

            fieldType newField
            (
                IOobject
                (
                    resultName_,
                    mesh.time().timeName(),
                    mesh,
                    IOobject::NO_READ
                ),
                calcMode_ == ADD ? baseField + addField : baseField - addField
            );
            newField.write();
        }
        else
        {
            Info<< "    Cannot calculate " << resultName_ << nl
                << "    - inconsistent dimensions: "
                << baseField.dimensions() << " - " << addField.dimensions()
                << endl;
        }

        processed = true;
    }
}
Foam::autoPtr<Foam::dynamicFvMesh> Foam::dynamicFvMesh::New(const IOobject& io)
{
    wordList libNames(1);
    libNames[0]=word("mesquiteMotionSolver");

    forAll(libNames,i) {
        const word libName("lib"+libNames[i]+".so");

        bool ok=dlLibraryTable::open(libName);
        if(!ok) {
            WarningIn("dynamicFvMesh::New(const IOobject& io)")
                << "Loading of dynamic mesh library " << libName
                    << " unsuccesful. Some dynamic mesh  methods may not be "
                    << " available"
                    << endl;
        }
    }

    // Enclose the creation of the dynamicMesh to ensure it is
    // deleted before the dynamicFvMesh is created otherwise the dictionary
    // is entered in the database twice
    IOdictionary dynamicMeshDict
    (
        IOobject
        (
            "dynamicMeshDict",
            io.time().constant(),
            (io.name() == dynamicFvMesh::defaultRegion ? "" : io.name() ),
            io.db(),
            IOobject::MUST_READ,
            IOobject::NO_WRITE,
            false
        )
    );

    word dynamicFvMeshTypeName(dynamicMeshDict.lookup("dynamicFvMesh"));

    Info<< "Selecting dynamicFvMesh " << dynamicFvMeshTypeName << endl;

    dlLibraryTable::open
    (
        dynamicMeshDict,
        "dynamicFvMeshLibs",
        IOobjectConstructorTablePtr_
    );

    if (!IOobjectConstructorTablePtr_)
    {
        FatalErrorIn
        (
            "dynamicFvMesh::New(const IOobject&)"
        )   << "dynamicFvMesh table is empty"
            << exit(FatalError);
    }

    IOobjectConstructorTable::iterator cstrIter =
        IOobjectConstructorTablePtr_->find(dynamicFvMeshTypeName);

    if (cstrIter == IOobjectConstructorTablePtr_->end())
    {
        FatalErrorIn
        (
            "dynamicFvMesh::New(const IOobject&)"
        )   << "Unknown dynamicFvMesh type " << dynamicFvMeshTypeName
            << endl << endl
            << "Valid dynamicFvMesh types are :" << endl
            << IOobjectConstructorTablePtr_->toc()
            << exit(FatalError);
    }

    return autoPtr<dynamicFvMesh>(cstrIter()(io));
}
Foam::displacementLaplacianFvMotionSolver::displacementLaplacianFvMotionSolver
(
    const polyMesh& mesh,
    const IOdictionary& dict
)
:
    displacementMotionSolver(mesh, dict, typeName),
    fvMotionSolver(mesh),
    cellDisplacement_
    (
        IOobject
        (
            "cellDisplacement",
            mesh.time().timeName(),
            mesh,
            IOobject::READ_IF_PRESENT,
            IOobject::AUTO_WRITE
        ),
        fvMesh_,
        dimensionedVector
        (
            "cellDisplacement",
            pointDisplacement_.dimensions(),
            Zero
        ),
        cellMotionBoundaryTypes<vector>(pointDisplacement_.boundaryField())
    ),
    pointLocation_(nullptr),
    diffusivityPtr_
    (
        motionDiffusivity::New(fvMesh_, coeffDict().lookup("diffusivity"))
    ),
    frozenPointsZone_
    (
        coeffDict().found("frozenPointsZone")
      ? fvMesh_.pointZones().findZoneID(coeffDict().lookup("frozenPointsZone"))
      : -1
    )
{
    IOobject io
    (
        "pointLocation",
        fvMesh_.time().timeName(),
        fvMesh_,
        IOobject::MUST_READ,
        IOobject::AUTO_WRITE
    );

    if (debug)
    {
        Info<< "displacementLaplacianFvMotionSolver:" << nl
            << "    diffusivity       : " << diffusivityPtr_().type() << nl
            << "    frozenPoints zone : " << frozenPointsZone_ << endl;
    }


    if (io.typeHeaderOk<pointVectorField>(true))
    {
        pointLocation_.reset
        (
            new pointVectorField
            (
                io,
                pointMesh::New(fvMesh_)
            )
        );

        if (debug)
        {
            Info<< "displacementLaplacianFvMotionSolver :"
                << " Read pointVectorField "
                << io.name()
                << " to be used for boundary conditions on points."
                << nl
                << "Boundary conditions:"
                << pointLocation_().boundaryField().types() << endl;
        }
    }
}
bool Foam::passiveParticleStreamReconstructor::reconstruct
(
    const IOobject& io,
    const bool,
    Ostream& os
) const
{
    // io.db()                   = Cloud<passiveParticle>
    // io.db().parent()          = polyMesh
    // io.db().parent().parent() = Time

    // Retrieve from polyMesh
    const uFieldReconstructor& reconstructor =
        uFieldReconstructor::New(io.db().parent());

    const PtrList<unallocatedFvMesh>& procMeshes = reconstructor.procMeshes();

    Info<< "Reconstructing " << io.objectPath() << endl;

    // Read field on proc meshes
    PtrList<cloud> procClouds(procMeshes.size());
    PtrList<unallocatedIOPosition> procFields(procMeshes.size());
    forAll(procFields, proci)
    {
        const unallocatedFvMesh& procMesh = procMeshes[proci];

        Pout<< incrIndent;

        // Construct empty cloud
        procClouds.set
        (
            proci,
            new cloud
            (
                procMesh.thisDb(),
                "kinematicCloud"
            )
        );

        procFields.set
        (
            proci,
            new unallocatedIOPosition
            (
                IOobject
                (
                    io.name(),
                    io.instance(),
                    io.local(),
                    procClouds[proci],
                    IOobject::MUST_READ,    //IOobject::READ_IF_PRESENT,
                    IOobject::NO_WRITE
                )
            )
        );

        Pout<< decrIndent;
    }

    unallocatedIOPosition particles
    (
        IOobject
        (
            io.name(),
            io.instance(),
            io.local(),
            io.db(),
            IOobject::NO_READ,
            IOobject::NO_WRITE,
            false
        )
    );

    const faceList* facesPtr = nullptr;
    if (isA<polyMesh>(io.db().parent()))
    {
        facesPtr = &dynamic_cast<const polyMesh&>(io.db().parent()).faces();
    }

    forAll(procFields, proci)
    {
        const unallocatedIOPosition& procCloud = procFields[proci];
        const labelList& cellMap = reconstructor.cellProcAddressing()[proci];
        const labelList& faceMap = reconstructor.faceProcAddressing()[proci];

        forAllConstIter(typename IDLList<basicParticle>, procCloud, iter)
        {
            const basicParticle& p = iter();

            const label mappedCell = cellMap[p.cell()];

            const label mapi = faceMap[p.tetFace()];

            label mappedTetFace = -1;
            label tetPti = p.tetPt();
            if (mapi == 0)
            {
                FatalErrorInFunction << "problem" << exit(FatalError);
            }
            else if (mapi > 0)
            {
                mappedTetFace = mapi - 1;
            }
            else
            {
                mappedTetFace = -mapi - 1;

                if (facesPtr)
                {
                    // Flipping face

                    const face& f = (*facesPtr)[mappedTetFace];
                    tetPti = f.size() - 1 - tetPti;
                }
            }

            particles.append
            (
                new basicParticle
                (
                    p,
                    mappedCell,
                    mappedTetFace,
                    tetPti
                )
            );
        }
    }
    particles.writeData(os);

    return os.good();
}
int main(int argc, char *argv[])
{
    argList::noParallel();
    timeSelector::addOptions();

#   include "setRootCase.H"
#   include "createTime.H"

    // Get times list
    instantList timeDirs = timeSelector::select0(runTime, args);

#   include "createMesh.H"
#   include "readTransportProperties.H"

    const word& gFormat = runTime.graphFormat();

    // Setup channel indexing for averaging over channel down to a line

    IOdictionary channelDict
    (
        IOobject
        (
            "postChannelExtDict",
            mesh.time().constant(),
            mesh,
            IOobject::MUST_READ_IF_MODIFIED,
            IOobject::NO_WRITE
        )
    );
    channelIndex channelIndexing(mesh, channelDict);

    List<Triple<word> > fields(channelDict.lookup("fieldsAndIdentifiers"));

    bool backwardsCompatibility(channelDict.lookupOrDefault("backwardsCompatibility", true));

    // For each time step read all fields
    forAll(timeDirs, timeI)
    {
        runTime.setTime(timeDirs[timeI], timeI);
        Info << "Processing fields for time " << runTime.timeName() << endl;
        Info << endl;

        fileName path(runTime.rootPath()/runTime.caseName()/"graphs"/runTime.timeName());
        mkDir(path);

        forAll(fields, I)
        {
           const word& fieldName = fields[I].first();
           const word& identifierName = fields[I].second();
           const word& moment = fields[I].third();

           IOobject fieldHeader
           (
               fieldName,
               runTime.timeName(),
               mesh,
               IOobject::MUST_READ
           );

           if (!fieldHeader.headerOk())
           {
               Info << endl;
               Info<< "No " << fieldName <<" field" << endl;
               Info << endl;
               continue;
           }

           Info << endl;
           Info << fieldName << endl;

           if(fieldHeader.headerClassName() == volScalarField::typeName)
           {
               Info << endl;
               Info << "    Reading field" << endl;
              
               volScalarField field(fieldHeader, mesh);

               Info << "    Collapsing field"  << endl;
               Info << endl;
               processField(field, channelIndexing, identifierName, path, gFormat, moment);
           }

           if(fieldHeader.headerClassName() == volVectorField::typeName)
           {
               Info << endl;
               Info << "    Reading field" << endl;
               
               volVectorField field(fieldHeader, mesh);
               
               Info << "    Collapsing field"  << endl;
               Info << endl;
               
               
               if((fieldHeader.name() == "U" || fieldHeader.name() == "UMean") && backwardsCompatibility)
               {
                   processField(field.component(vector::X)(), channelIndexing, identifierName, path, gFormat, "mean");
               }
               else
               {
                   processField(field.component(vector::X)(), channelIndexing, identifierName+"_x", path, gFormat, moment);
                   processField(field.component(vector::Y)(), channelIndexing, identifierName+"_y", path, gFormat, moment);
                   processField(field.component(vector::Z)(), channelIndexing, identifierName+"_z", path, gFormat, moment);
                    
               }
           }

           if(fieldHeader.headerClassName() == volSymmTensorField::typeName)
           {
               Info << endl;
               Info << "    Reading field" << endl;

               volSymmTensorField field(fieldHeader, mesh);

               Info << "    Collapsing field"  << endl;
               Info << endl;
               
               if((fieldHeader.name() == "UPrime2Mean") && backwardsCompatibility)
               {
                   processField(field.component(symmTensor::XX)(), channelIndexing, "u", path, gFormat, "rms");
                   processField(field.component(symmTensor::YY)(), channelIndexing, "v", path, gFormat, "rms");
                   processField(field.component(symmTensor::ZZ)(), channelIndexing, "w", path, gFormat, "rms");
                   processField(field.component(symmTensor::XY)(), channelIndexing, "uv", path, gFormat, "mean", true);
               }
               else
               {
                   processField(field.component(symmTensor::XX)(), channelIndexing, identifierName+"_xx", path, gFormat, moment);
                   processField(field.component(symmTensor::XY)(), channelIndexing, identifierName+"_xy", path, gFormat, moment, true);
                   processField(field.component(symmTensor::XZ)(), channelIndexing, identifierName+"_xz", path, gFormat, moment, true);
                   processField(field.component(symmTensor::YY)(), channelIndexing, identifierName+"_yy", path, gFormat, moment);
                   processField(field.component(symmTensor::YZ)(), channelIndexing, identifierName+"_yz", path, gFormat, moment, true);
                   processField(field.component(symmTensor::ZZ)(), channelIndexing, identifierName+"_zz", path, gFormat, moment);
               }
           }

           if(fieldHeader.headerClassName() == volTensorField::typeName)
           {
               Info << endl;
               Info << "    Reading field" << endl;

               volTensorField field(fieldHeader, mesh);

               Info << "    Collapsing field"  << endl;
               Info << endl;

               processField(field.component(tensor::XX)(), channelIndexing, identifierName+"_xx", path, gFormat, moment);
               processField(field.component(tensor::XY)(), channelIndexing, identifierName+"_xy", path, gFormat, moment, true);
               processField(field.component(tensor::XZ)(), channelIndexing, identifierName+"_xz", path, gFormat, moment, true);
               processField(field.component(tensor::YX)(), channelIndexing, identifierName+"_yx", path, gFormat, moment, true);
               processField(field.component(tensor::YY)(), channelIndexing, identifierName+"_yy", path, gFormat, moment);
               processField(field.component(tensor::YZ)(), channelIndexing, identifierName+"_yz", path, gFormat, moment, true);
               processField(field.component(tensor::XZ)(), channelIndexing, identifierName+"_xz", path, gFormat, moment, true);
               processField(field.component(tensor::YZ)(), channelIndexing, identifierName+"_yz", path, gFormat, moment, true);
               processField(field.component(tensor::ZZ)(), channelIndexing, identifierName+"_zz", path, gFormat, moment);
           }


        }

    }
int main(int argc, char *argv[])
{
    argList::addNote
    (
        "redistribute a triSurface"
    );

    argList::validArgs.append("triSurfaceMesh");
    argList::validArgs.append("distributionType");
    argList::addBoolOption
    (
        "keepNonMapped",
        "preserve surface outside of mesh bounds"
    );

    #include "setRootCase.H"
    #include "createTime.H"
    runTime.functionObjects().off();

    const fileName surfFileName = args[1];
    const word distType = args[2];

    Info<< "Reading surface from " << surfFileName << nl << nl
        << "Using distribution method "
        << distributedTriSurfaceMesh::distributionTypeNames_[distType]
        << " " << distType << nl << endl;

    const bool keepNonMapped = args.options().found("keepNonMapped");

    if (keepNonMapped)
    {
        Info<< "Preserving surface outside of mesh bounds." << nl << endl;
    }
    else
    {
        Info<< "Removing surface outside of mesh bounds." << nl << endl;
    }


    if (!Pstream::parRun())
    {
        FatalErrorIn(args.executable())
            << "Please run this program on the decomposed case."
            << " It will read surface " << surfFileName
            << " and decompose it such that it overlaps the mesh bounding box."
            << exit(FatalError);
    }


    #include "createPolyMesh.H"

    Random rndGen(653213);

    // Determine mesh bounding boxes:
    List<List<treeBoundBox> > meshBb(Pstream::nProcs());
    {
        meshBb[Pstream::myProcNo()] = List<treeBoundBox>
        (
            1,
            treeBoundBox
            (
                boundBox(mesh.points(), false)
            ).extend(rndGen, 1E-3)
        );
        Pstream::gatherList(meshBb);
        Pstream::scatterList(meshBb);
    }

    IOobject io
    (
        surfFileName,         // name
        //runTime.findInstance("triSurface", surfFileName),   // instance
        runTime.constant(),   // instance
        "triSurface",         // local
        runTime,              // registry
        IOobject::MUST_READ,
        IOobject::NO_WRITE
    );

    const fileName actualPath(io.filePath());
    fileName localPath(actualPath);
    localPath.replace(runTime.rootPath() + '/', "");

    if (actualPath == io.objectPath())
    {
        Info<< "Loading local (decomposed) surface " << localPath << nl <<endl;
    }
    else
    {
        Info<< "Loading undecomposed surface " << localPath << nl << endl;
    }


    // Create dummy dictionary for bounding boxes if does not exist.
    if (!isFile(actualPath / "Dict"))
    {
        dictionary dict;
        dict.add("bounds", meshBb[Pstream::myProcNo()]);
        dict.add("distributionType", distType);
        dict.add("mergeDistance", SMALL);

        IOdictionary ioDict
        (
            IOobject
            (
                io.name() + "Dict",
                io.instance(),
                io.local(),
                io.db(),
                IOobject::NO_READ,
                IOobject::NO_WRITE,
                false
            ),
            dict
        );

        Info<< "Writing dummy bounds dictionary to " << ioDict.name()
            << nl << endl;

        ioDict.regIOobject::writeObject
        (
            IOstream::ASCII,
            IOstream::currentVersion,
            ioDict.time().writeCompression()
        );
    }


    // Load surface
    distributedTriSurfaceMesh surfMesh(io);
    Info<< "Loaded surface" << nl << endl;


    // Generate a test field
    {
        const triSurface& s = static_cast<const triSurface&>(surfMesh);

        autoPtr<triSurfaceVectorField> fcPtr
        (
            new triSurfaceVectorField
            (
                IOobject
                (
                    surfMesh.searchableSurface::name(),     // name
                    surfMesh.searchableSurface::instance(), // instance
                    surfMesh.searchableSurface::local(),    // local
                    surfMesh,
                    IOobject::NO_READ,
                    IOobject::AUTO_WRITE
                ),
                surfMesh,
                dimLength
            )
        );
        triSurfaceVectorField& fc = fcPtr();

        forAll(fc, triI)
        {
            fc[triI] = s[triI].centre(s.points());
        }

        // Steal pointer and store object on surfMesh
        fcPtr.ptr()->store();
    }