Foam::tmp<Foam::Field<Type>>
Foam::functionObjects::fieldValues::surfaceRegion::getFieldValues
(
    const word& fieldName,
    const bool mustGet,
    const bool applyOrientation
) const
{
    typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
    typedef GeometricField<Type, fvPatchField, volMesh> vf;

    if (regionType_ != stSampledSurface && obr_.foundObject<sf>(fieldName))
    {
        return filterField(obr_.lookupObject<sf>(fieldName), applyOrientation);
    }
    else if (obr_.foundObject<vf>(fieldName))
    {
        const vf& fld = obr_.lookupObject<vf>(fieldName);

        if (surfacePtr_.valid())
        {
            if (surfacePtr_().interpolate())
            {
                const interpolationCellPoint<Type> interp(fld);
                tmp<Field<Type>> tintFld(surfacePtr_().interpolate(interp));
                const Field<Type>& intFld = tintFld();

                // Average
                const faceList& faces = surfacePtr_().faces();
                tmp<Field<Type>> tavg
                (
                    new Field<Type>(faces.size(), Zero)
                );
                Field<Type>& avg = tavg.ref();

                forAll(faces, facei)
                {
                    const face& f = faces[facei];
                    forAll(f, fp)
                    {
                        avg[facei] += intFld[f[fp]];
                    }
                    avg[facei] /= f.size();
                }

                return tavg;
            }
            else
            {
                return surfacePtr_().sample(fld);
            }
        }
        else
        {
            return filterField(fld, applyOrientation);
Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::setFieldValues
(
    const word& fieldName
) const
{
    typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
    typedef GeometricField<Type, fvPatchField, volMesh> vf;

    if (source_ != stSampledSurface && obr_.foundObject<sf>(fieldName))
    {
        return filterField(obr_.lookupObject<sf>(fieldName), true);
    }
    else if (obr_.foundObject<vf>(fieldName))
    {
        if (surfacePtr_.valid())
        {
            return surfacePtr_().sample(obr_.lookupObject<vf>(fieldName));
        }
        else
        {
            return filterField(obr_.lookupObject<vf>(fieldName), true);
        }
    }

    return tmp<Field<Type> >(new Field<Type>(0));
}
bool Foam::fieldValues::faceSource::writeValues(const word& fieldName)
{
    const bool ok = validField<Type>(fieldName);

    if (ok)
    {
        // Get (correctly oriented) field
        Field<Type> values = combineFields(setFieldValues<Type>(fieldName)());

        // Get unoriented magSf
        scalarField magSf;

        if (surfacePtr_.valid())
        {
            magSf = combineFields(surfacePtr_().magSf());
        }
        else
        {
            magSf = combineFields(filterField(mesh().magSf(), false)());
        }

        // Get (correctly oriented) weighting field
        scalarField weightField =
            combineFields(setFieldValues<scalar>(weightFieldName_)());

        if (Pstream::master())
        {
            Type result = processValues(values, magSf, weightField);

            if (valueOutput_)
            {
                IOList<Type>
                (
                    IOobject
                    (
                        fieldName + "_" + sourceTypeNames_[source_] + "-"
                            + sourceName_,
                        obr_.time().timeName(),
                        obr_,
                        IOobject::NO_READ,
                        IOobject::NO_WRITE
                    ),
                    values
                ).write();
            }

            outputFilePtr_()<< tab << result;

            if (log_)
            {
                Info<< "    " << operationTypeNames_[operation_]
                    << "(" << sourceName_ << ") for " << fieldName
                    <<  " = " << result << endl;
            }
        }
    }

    return ok;
}