Foam::KinematicCloud<CloudType>::KinematicCloud
(
    const fvMesh& mesh,
    const word& name,
    const KinematicCloud<CloudType>& c
)
:
    CloudType(mesh, name, IDLList<parcelType>()),
    kinematicCloud(),
    cloudCopyPtr_(NULL),
    mesh_(mesh),
    particleProperties_
    (
        IOobject
        (
            name + "Properties",
            mesh.time().constant(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE,
            false
        )
    ),
    solution_(mesh),
    constProps_(),
    subModelProperties_(dictionary::null),
    rndGen_(0, 0),
    cellOccupancyPtr_(NULL),
    rho_(c.rho_),
    U_(c.U_),
    mu_(c.mu_),
    g_(c.g_),
    pAmbient_(c.pAmbient_),
    forces_(*this, mesh),
    functions_(*this),
    dispersionModel_(NULL),
    injectionModel_(NULL),
    patchInteractionModel_(NULL),
    surfaceFilmModel_(NULL),
    UIntegrator_(NULL),
    UTrans_(NULL),
    UCoeff_(NULL)
{}
Foam::hsCombustionThermo::hsCombustionThermo(const fvMesh& mesh)
:
    basicPsiThermo(mesh),

    hs_
    (
        IOobject
        (
            "hs",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        dimEnergy/dimMass,
        this->hBoundaryTypes()
    )
{}
Exemple #3
0
Foam::hCombustionThermo::hCombustionThermo(const fvMesh& mesh)
:
    basicPsiThermo(mesh),

    h_
    (
        IOobject
        (
            "h",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        dimensionSet(0, 2, -2, 0, 0),
        this->hBoundaryTypes()
    )
{}
Exemple #4
0
Foam::wallDist::wallDist(const fvMesh& mesh, const bool correctWalls)
:
    volScalarField
    (
        IOobject
        (
            "y",
            mesh.time().timeName(),
            mesh
        ),
        mesh,
        dimensionedScalar("y", dimLength, GREAT)
    ),
    cellDistFuncs(mesh),
    correctWalls_(correctWalls),
    nUnset_(0)
{
    wallDist::correct();
}
Foam::constSolidThermo::constSolidThermo
(
    const fvMesh& mesh,
    const dictionary& dict
)
:
    basicSolidThermo(mesh, dict),
    dict_(dict.subDict(typeName + "Coeffs")),
    constK_(dimensionedScalar(dict_.lookup("K"))),
    K_
    (
        IOobject
        (
            "K",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        constK_
    ),
    constRho_(dimensionedScalar(dict_.lookup("rho"))),
    constCp_(dimensionedScalar(dict_.lookup("Cp"))),
    constHf_(dimensionedScalar(dict_.lookup("Hf"))),
    constEmissivity_(dimensionedScalar(dict_.lookup("emissivity"))),
    constKappa_(dimensionedScalar(dict_.lookup("kappa"))),
    constSigmaS_(dimensionedScalar(dict_.lookup("sigmaS")))
{
    read();

    K_ = constK_;

    rho_ = constRho_;

    emissivity_ = constEmissivity_;

    kappa_ = constKappa_;

    sigmaS_ = constSigmaS_;
}
autoPtr<thermalBaffleModel> thermalBaffleModel::New(const fvMesh& mesh)
{
    word modelType;
    {
        IOdictionary thermalBafflePropertiesDict
        (
            IOobject
            (
                "thermalBaffleProperties",
                mesh.time().constant(),
                mesh,
                IOobject::MUST_READ_IF_MODIFIED,
                IOobject::NO_WRITE,
                false
            )
        );

        word modelType =
            thermalBafflePropertiesDict.lookupOrDefault<word>
            (
                "thermalBaffleModel",
                "thermalBaffle"
            );
    }

    meshConstructorTable::iterator cstrIter =
        meshConstructorTablePtr_->find(modelType);

    if (cstrIter == meshConstructorTablePtr_->end())
    {

        FatalErrorIn("thermalBaffleModel::New(const fvMesh&)")
            << "Unknown thermalBaffleModel type " << modelType
            << nl << nl
            <<  "Valid thermalBaffleModel types are:" << nl
            << meshConstructorTablePtr_->sortedToc()
            << exit(FatalError);
    }

    return autoPtr<thermalBaffleModel>(cstrIter()(modelType, mesh));
}
Exemple #7
0
DMDModel<Type>::DMDModel
(
    const fvMesh& mesh,
    const word& DMDModelName
)
:
    IOdictionary
    (
        IOobject
        (
            "DMDProperties",
            mesh.time().constant(),
            mesh,
            IOobject::MUST_READ_IF_MODIFIED,
            IOobject::NO_WRITE,
            false
        )
    ),
    mesh_(mesh),
    coeffDict_(subOrEmptyDict(DMDModelName + "Coeffs"))
{}
Foam::wavesPorosityModel::wavesPorosityModel
(
	const fvMesh& mesh
)
:
    porosity_
    (
        IOobject
        (
            "porosity",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        dimensionedScalar("NULL", dimless, 1.0),
        "zeroGradient"
    )
{
}
Exemple #9
0
Foam::solidThermo::solidThermo
(
    const fvMesh& mesh,
    const word& phaseName
)
:
    basicThermo(mesh, phaseName),
    rho_
    (
        IOobject
        (
            phasePropertyName("thermo:rho"),
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        dimDensity
    )
{}
Exemple #10
0
bool loadFieldFunction(
    fvMesh &mesh,
    const word &fName,
    SLPtrList<FieldType> &fieldList
) {
    const Time &runTime=mesh.time();

    IOobject f
        (
            fName,
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        );
    f.headerOk();
    word className=f.headerClassName();

    if(className==FieldType::typeName) {
        Info << "Reading field " << fName << " of type "
            << FieldType::typeName << endl;
        fieldList.append(
            new FieldType
            (
                IOobject
                (
                    fName,
                    runTime.timeName(),
                    mesh,
                    IOobject::MUST_READ,
                    IOobject::AUTO_WRITE
                ),
                mesh
            )
        );
        return true;
    } else {
        return false;
    }
}
Foam::autoPtr<Foam::hCombustionThermo> Foam::hCombustionThermo::New
(
    const fvMesh& mesh
)
{
    // get model name, but do not register the dictionary
    // otherwise it is registered in the database twice
    const word modelType
    (
        IOdictionary
        (
            IOobject
            (
                "thermophysicalProperties",
                mesh.time().constant(),
                mesh,
                IOobject::MUST_READ_IF_MODIFIED,
                IOobject::NO_WRITE,
                false
            )
        ).lookup("thermoType")
    );

    Info<< "Selecting thermodynamics package " << modelType << endl;

    fvMeshConstructorTable::iterator cstrIter =
        fvMeshConstructorTablePtr_->find(modelType);

    if (cstrIter == fvMeshConstructorTablePtr_->end())
    {
        FatalErrorIn("hCombustionThermo::New(const fvMesh&)")
            << "Unknown hCombustionThermo type "
            << modelType << nl << nl
            << "Valid hCombustionThermo types are:" << nl
            << fvMeshConstructorTablePtr_->sortedToc() << nl
            << exit(FatalError);
    }

    return autoPtr<hCombustionThermo>(cstrIter()(mesh));
}
Foam::tmp<Foam::volScalarField> Foam::sampledIsoSurface::average
(
    const fvMesh& mesh,
    const pointScalarField& pfld
) const
{
    tmp<volScalarField> tcellAvg
    (
        new volScalarField
        (
            IOobject
            (
                "cellAvg",
                mesh.time().timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE,
                false
            ),
            mesh,
            dimensionedScalar("zero", dimless, scalar(0.0))
        )
    );
    volScalarField& cellAvg = tcellAvg();

    labelField nPointCells(mesh.nCells(), 0);
    {
        for (label pointI = 0; pointI < mesh.nPoints(); pointI++)
        {
            const labelList& pCells = mesh.pointCells(pointI);

            forAll(pCells, i)
            {
                label cellI = pCells[i];

                cellAvg[cellI] += pfld[pointI];
                nPointCells[cellI]++;
            }
        }
    }
Foam::autoPtr<Foam::multiphaseSystem> Foam::multiphaseSystem::New
(
    const fvMesh& mesh
)
{
    const word multiphaseSystemType
    (
        IOdictionary
        (
            IOobject
            (
                propertiesName,
                mesh.time().constant(),
                mesh,
                IOobject::MUST_READ_IF_MODIFIED,
                IOobject::NO_WRITE,
                false
            )
        ).lookup("type")
    );

    Info<< "Selecting multiphaseSystem "
        << multiphaseSystemType << endl;

    dictionaryConstructorTable::iterator cstrIter =
        dictionaryConstructorTablePtr_->find(multiphaseSystemType);

    if (cstrIter == dictionaryConstructorTablePtr_->end())
    {
        FatalErrorInFunction
            << "Unknown multiphaseSystemType type "
            << multiphaseSystemType << endl << endl
            << "Valid multiphaseSystem types are : " << endl
            << dictionaryConstructorTablePtr_->sortedToc()
            << exit(FatalError);
    }

    return cstrIter()(mesh);
}
Foam::hReactionThermo::hReactionThermo
(
    const fvMesh& mesh,
    const objectRegistry& obj
)
:
    basicRhoThermo(mesh, obj),

    h_
    (
        IOobject
        (
            "h",
            mesh.time().timeName(),
            obj,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        dimensionSet(0, 2, -2, 0, 0),
        this->hBoundaryTypes()
    )
{}
Exemple #15
0
Foam::patchDist::patchDist
(
    const fvMesh& mesh,
    const labelHashSet& patchIDs,
    const bool correctWalls
)
:
    volScalarField
    (
        IOobject
        (
            "y",
            mesh.time().timeName(),
            mesh
        ),
        mesh,
        dimensionedScalar("y", dimLength, GREAT)
    ),
    patchIDs_(patchIDs),
    correctWalls_(correctWalls),
    nUnset_(0)
{
    patchDist::correct();
}
Exemple #16
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::autoPtr<Foam::flameletTable>
Foam::flameletTable::New(const fvMesh& mesh, const word& tableName)
{
    const word modelName
    (
        IOdictionary
        (
            IOobject
            (
                "tableProperties",
                mesh.time().constant(),
                mesh,
                IOobject::MUST_READ,
                IOobject::NO_WRITE,
                false
            )
        ).lookup("interpolationType")
    );

    dictionaryConstructorTable::iterator cstrIter =
    dictionaryConstructorTablePtr_->find(modelName);

    return cstrIter()(mesh, tableName);
}
Exemple #18
0
Foam::combustionModels::PaSR<Type>::PaSR
(
    const word& modelType,
    const fvMesh& mesh,
    const word& phaseName
)
:
    laminar<Type>(modelType, mesh, phaseName),
    Cmix_(readScalar(this->coeffs().lookup("Cmix"))),
    turbulentReaction_(this->coeffs().lookup("turbulentReaction")),
    kappa_
    (
        IOobject
        (
            IOobject::groupName("PaSR:kappa", phaseName),
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh,
        dimensionedScalar("kappa", dimless, 0.0)
    )
{}
void setResultForContribution<FaFieldValuePluginFunction>(
    const fvMesh &mesh,
    ExpressionResult &result,
    const scalarField &values
) {
    autoPtr<areaScalarField> pResult(
        new areaScalarField(
            IOobject(
                "contributionFrom_", // +Driver::driverName(),
                mesh.time().timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            FaCommonValueExpressionDriver::faRegionMesh(mesh),
            dimensionedScalar("contribution",dimless,0)
        )
    );

    pResult->internalField()=values;
    pResult->correctBoundaryConditions();

    result.setObjectResult(pResult);
}
Foam::radiation::greyMeanAbsorptionEmissionSoot::greyMeanAbsorptionEmissionSoot
(
    const dictionary& dict,
    const fvMesh& mesh
)
:
    absorptionEmissionModel(dict, mesh),
    coeffsDict_((dict.subDict(typeName + "Coeffs"))),
    speciesNames_(0),
    specieIndex_(0),
    lookUpTable_
    (
        fileName(coeffsDict_.lookup("lookUpTableFileName")),
        mesh.time().constant(),
        mesh
    ),
    thermo_(mesh.lookupObject<basicThermo>("thermophysicalProperties")),
    EhrrCoeff_(readScalar(coeffsDict_.lookup("EhrrCoeff"))),
    Yj_(nSpecies_)
{
    label nFunc = 0;
    const dictionary& functionDicts = dict.subDict(typeName + "Coeffs");

    forAllConstIter(dictionary, functionDicts, iter)
    {
        // safety:
        if (!iter().isDict())
        {
            continue;
        }
        const word& key = iter().keyword();
        speciesNames_.insert(key, nFunc);
        const dictionary& dict = iter().dict();
        coeffs_[nFunc].initialise(dict);
        nFunc++;
    }

    // Check that all the species on the dictionary are present in the
    // look-up table and save the corresponding indices of the look-up table

    label j = 0;
    forAllConstIter(HashTable<label>, speciesNames_, iter)
    {
        if (mesh.foundObject<volScalarField>("ft"))
        {
            if (lookUpTable_.found(iter.key()))
            {
                label index = lookUpTable_.findFieldIndex(iter.key());

                Info<< "specie: " << iter.key() << " found on look-up table "
                    << " with index: " << index << endl;

                specieIndex_[iter()] = index;
            }
            else if (mesh.foundObject<volScalarField>(iter.key()))
            {
                volScalarField& Y =
                    const_cast<volScalarField&>
                    (
                        mesh.lookupObject<volScalarField>(iter.key())
                    );
                Yj_.set(j, &Y);
                specieIndex_[iter()] = 0;
                j++;
                Info<< "specie: " << iter.key() << " is being solved" << endl;
            }
            else
            {
                FatalErrorIn
                (
                    "Foam::radiation::greyMeanAbsorptionEmissionSoot(const"
                    "dictionary& dict, const fvMesh& mesh)"
                )   << "specie: " << iter.key()
                    << " is neither in look-up table: "
                    << lookUpTable_.tableName()
                    << " nor is being solved" << nl
                    << exit(FatalError);
            }
        }
        else
        {
            FatalErrorIn
            (
                "Foam::radiation::greyMeanAbsorptionEmissionSoot(const"
                "dictionary& dict, const fvMesh& mesh)"
            )   << "specie ft is not present " << nl
                << exit(FatalError);

        }
    }
}
Foam::autoPtr<Foam::solidChemistryModel> Foam::solidChemistryModel::New
(
    const fvMesh& mesh
)
{
    IOdictionary chemistryPropertiesDict
    (
        IOobject
        (
            "chemistryProperties",
            mesh.time().constant(),
            mesh,
            IOobject::MUST_READ,
            IOobject::NO_WRITE,
            false
        )
    );

    const word userModel(chemistryPropertiesDict.lookup("solidChemistryModel"));

    const word ODEModelName(chemistryPropertiesDict.lookup("chemistrySolver"));
    const word gasThermoName(chemistryPropertiesDict.lookup("gasThermoModel"));

    // construct chemistry model type name by inserting first template argument
    const label tempOpen = userModel.find('<');
    const label tempClose = userModel.find('>');

    const word className = userModel(0, tempOpen);
    const word thermoTypeName =
        userModel(tempOpen + 1, tempClose - tempOpen - 1);

    const word modelType =
        ODEModelName + '<' + className
      + '<' + typeName + ',' + thermoTypeName + ',' + gasThermoName + ">>";


    if (debug)
    {
        Info<< "Selecting solidChemistryModel " << modelType << endl;
    }
    else
    {
        Info<< "Selecting solidChemistryModel " << userModel + gasThermoName
            << endl;
    }

    fvMeshConstructorTable::iterator cstrIter =
        fvMeshConstructorTablePtr_->find(modelType);

    if (cstrIter == fvMeshConstructorTablePtr_->end())
    {
        if (debug)
        {
            FatalErrorIn("solidChemistryModel::New(const mesh&)")
                << "Unknown solidChemistryModel type "
                << modelType << nl << nl
                << "Valid solidChemistryModel types are:" << nl
                << fvMeshConstructorTablePtr_->sortedToc() << nl
                << exit(FatalError);
        }
        else
        {
            wordList models = fvMeshConstructorTablePtr_->sortedToc();
            forAll(models, i)
            {
                models[i] = models[i].replace(typeName + ',', "");
            }

            FatalErrorIn("solidChemistryModel::New(const mesh&)")
                << "Unknown solidChemistryModel type "
                << userModel << nl << nl
                << "Valid solidChemistryModel types are:" << nl
                << models << nl
                << exit(FatalError);
        }
    }
// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
Foam::cfdemCloud::cfdemCloud
(
    const fvMesh& mesh
)
:
    mesh_(mesh),
    couplingProperties_
    (
        IOobject
        (
            "couplingProperties",
            mesh_.time().constant(),
            mesh_,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    ),
    liggghtsCommandDict_
    (
        IOobject
        (
            "liggghtsCommands",
            mesh_.time().constant(),
            mesh_,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    ),
    verbose_(false),
    ignore_(false),
    modelType_(couplingProperties_.lookup("modelType")),
    positions_(NULL),
    velocities_(NULL),
    fluidVel_(NULL),
    impForces_(NULL),
    expForces_(NULL),
    DEMForces_(NULL),
    Cds_(NULL),
    radii_(NULL),
    voidfractions_(NULL),
    cellIDs_(NULL),
    particleWeights_(NULL),
    particleVolumes_(NULL),
    numberOfParticles_(0),
    numberOfParticlesChanged_(false),
    arraysReallocated_(false),
    forceModels_(couplingProperties_.lookup("forceModels")),
    momCoupleModels_(couplingProperties_.lookup("momCoupleModels")),
    liggghtsCommandModelList_(liggghtsCommandDict_.lookup("liggghtsCommandModels")),
    turbulenceModelType_(couplingProperties_.lookup("turbulenceModelType")),
    cgOK_(true),
    impDEMdrag_(false),
    useDDTvoidfraction_(false),
    ddtVoidfraction_
    (   
        IOobject
        (
            "ddtVoidfraction",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh,
        dimensionedScalar("zero", dimensionSet(0,0,-1,0,0), 0)  // 1/s
    ),
    turbulence_
    (
        #if defined(version21) || defined(version16ext)
            #ifdef comp
                mesh.lookupObject<compressible::turbulenceModel>
            #else
                mesh.lookupObject<incompressible::turbulenceModel>
            #endif
        #elif defined(version15)
            mesh.lookupObject<incompressible::RASModel>
        #endif
        (
            turbulenceModelType_
        )
    ),
    locateModel_
    (
        locateModel::New
        (
            couplingProperties_,
            *this
        )
    ),
    /*momCoupleModel_
    (
        momCoupleModel::New
        (
            couplingProperties_,
            *this
        )
    ),*/
    dataExchangeModel_
    (
        dataExchangeModel::New
        (
            couplingProperties_,
            *this
        )
    ),
    IOModel_
    (
        IOModel::New
        (
            couplingProperties_,
            *this
        )
    ),
    probeModel_
    (
        probeModel::New
        (
            couplingProperties_,
            *this,
            "none",
            "none"
        )
    ),
    voidFractionModel_
    (
        voidFractionModel::New
        (
            couplingProperties_,
            *this
        )
    ),
    averagingModel_
    (
        averagingModel::New
        (
            couplingProperties_,
            *this
        )
    ),
    clockModel_
    (
        clockModel::New
        (
            couplingProperties_,
            *this
        )
    ),
    smoothingModel_
    (
        smoothingModel::New
        (
            couplingProperties_,
            *this
        )
    ),
    meshMotionModel_
    (
        meshMotionModel::New
        (
            couplingProperties_,
            *this
        )
    )
{
    #include "versionInfo.H"

    Info << "If BC are important, please provide volScalarFields -imp/expParticleForces-" << endl;

    if (couplingProperties_.found("verbose")) verbose_=true;
    if (couplingProperties_.found("ignore")) ignore_=true;
    if (turbulenceModelType_=="LESProperties")
        Info << "WARNING - LES functionality not yet tested!" << endl;

    if (couplingProperties_.found("useDDTvoidfraction"))
        useDDTvoidfraction_=true;
    else        
        Info << "ignoring ddt(voidfraction)" << endl;

    forceModel_ = new autoPtr<forceModel>[nrForceModels()];
    for (int i=0;i<nrForceModels();i++)
    {
        forceModel_[i] = forceModel::New
        (
            couplingProperties_,
            *this,
            forceModels_[i]
        );
    }

    momCoupleModel_ = new autoPtr<momCoupleModel>[momCoupleModels_.size()];
    for (int i=0;i<momCoupleModels_.size();i++)
    {
        momCoupleModel_[i] = momCoupleModel::New
        (
            couplingProperties_,
            *this,
            momCoupleModels_[i]
        );
    }

    // run liggghts commands from cfdem
    liggghtsCommand_ = new autoPtr<liggghtsCommandModel>[liggghtsCommandModelList_.size()];
    for (int i=0;i<liggghtsCommandModelList_.size();i++)
    {
        liggghtsCommand_[i] = liggghtsCommandModel::New
        (
            liggghtsCommandDict_,
            *this,
            liggghtsCommandModelList_[i],
            i
        );
    }

    dataExchangeM().setCG();
    if (!cgOK_ && forceM(0).cg() > 1) FatalError<< "at least one of your models is not fit for cg !!!"<< abort(FatalError); 
}
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<ChemistryModel> Foam::basicChemistryModel::New
(
    const fvMesh& mesh
)
{
    IOdictionary chemistryDict
    (
        IOobject
        (
            "chemistryProperties",
            mesh.time().constant(),
            mesh,
            IOobject::MUST_READ,
            IOobject::NO_WRITE,
            false
        )
    );

    word chemistryTypeName;

    if (chemistryDict.isDict("chemistryType"))
    {
        const dictionary& chemistryTypeDict
        (
            chemistryDict.subDict("chemistryType")
        );

        Info<< "Selecting chemistry type " << chemistryTypeDict << endl;

        const int nCmpt = 8;
        const char* cmptNames[nCmpt] =
        {
            "chemistrySolver",
            "chemistryModel",
            "chemistryThermo",
            "transport",
            "thermo",
            "equationOfState",
            "specie",
            "energy"
        };

        IOdictionary thermoDict
        (
            IOobject
            (
                "thermophysicalProperties",
                mesh.time().constant(),
                mesh,
                IOobject::MUST_READ_IF_MODIFIED,
                IOobject::NO_WRITE,
                false
            )
        );

        word thermoTypeName;

        if (thermoDict.isDict("thermoType"))
        {
            const dictionary& thermoTypeDict(thermoDict.subDict("thermoType"));
            thermoTypeName =
                word(thermoTypeDict.lookup("transport")) + '<'
              + word(thermoTypeDict.lookup("thermo")) + '<'
              + word(thermoTypeDict.lookup("equationOfState")) + '<'
              + word(thermoTypeDict.lookup("specie")) + ">>,"
              + word(thermoTypeDict.lookup("energy")) + ">";
        }
        else
        {
             FatalIOErrorIn
             (
                 (ChemistryModel::typeName + "::New(const mesh&)").c_str(),
                 thermoDict
             )   << "thermoType is in the old format and must be upgraded"
                 << exit(FatalIOError);
        }

        Switch isTDAC(chemistryTypeDict.lookupOrDefault("TDAC",false));

        // Construct the name of the chemistry type from the components
        if (isTDAC)
        {
            chemistryTypeName =
                word(chemistryTypeDict.lookup("chemistrySolver")) + '<'
              + "TDACChemistryModel<"
              + word(chemistryTypeDict.lookup("chemistryThermo")) + ','
              + thermoTypeName + ">>";
        }
        else
        {
            chemistryTypeName =
                word(chemistryTypeDict.lookup("chemistrySolver")) + '<'
              + "chemistryModel<"
              + word(chemistryTypeDict.lookup("chemistryThermo")) + ','
              + thermoTypeName + ">>";
        }
        typename ChemistryModel::fvMeshConstructorTable::iterator cstrIter =
            ChemistryModel::fvMeshConstructorTablePtr_->find(chemistryTypeName);

        if (cstrIter == ChemistryModel::fvMeshConstructorTablePtr_->end())
        {

            FatalErrorIn(ChemistryModel::typeName + "::New(const mesh&)")
                << "Unknown " << ChemistryModel::typeName << " type " << nl
                << "chemistryType" << chemistryTypeDict << nl << nl
                << "Valid " << ChemistryModel ::typeName << " types are:"
                << nl << nl;


            // Get the list of all the suitable chemistry packages available
            wordList validChemistryTypeNames
            (
                ChemistryModel::fvMeshConstructorTablePtr_->sortedToc()
            );


            // Build a table of the thermo packages constituent parts
            // Note: row-0 contains the names of constituent parts
            List<wordList> validChemistryTypeNameCmpts
            (
                validChemistryTypeNames.size() + 1
            );

            validChemistryTypeNameCmpts[0].setSize(nCmpt);
            forAll(validChemistryTypeNameCmpts[0], j)
            {
                validChemistryTypeNameCmpts[0][j] = cmptNames[j];
            }

            // Split the thermo package names into their constituent parts
            forAll(validChemistryTypeNames, i)
            {
                validChemistryTypeNameCmpts[i+1] = basicThermo::splitThermoName
                (
                    validChemistryTypeNames[i],
                    nCmpt
                );
            }

            // Print the table of available packages
            // in terms of their constituent parts
            printTable(validChemistryTypeNameCmpts, FatalError);

            FatalError<< exit(FatalError);
        }
conservativeMeshToMesh::conservativeMeshToMesh
(
    const fvMesh& srcMesh,
    const fvMesh& tgtMesh,
    const label nThreads,
    const bool forceRecalculation,
    const bool writeAddressing
)
:
    meshSrc_(srcMesh),
    meshTgt_(tgtMesh),
    addressing_
    (
        IOobject
        (
            "addressing",
            tgtMesh.time().timeName(),
            tgtMesh,
            IOobject::READ_IF_PRESENT,
            IOobject::NO_WRITE
        ),
        tgtMesh.nCells()
    ),
    weights_
    (
        IOobject
        (
            "weights",
            tgtMesh.time().timeName(),
            tgtMesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        tgtMesh.nCells()
    ),
    centres_
    (
        IOobject
        (
            "centres",
            tgtMesh.time().timeName(),
            tgtMesh,
            IOobject::READ_IF_PRESENT,
            IOobject::NO_WRITE
        ),
        tgtMesh.nCells()
    ),
    cellAddressing_(tgtMesh.nCells()),
    counter_(0),
    boundaryAddressing_(tgtMesh.boundaryMesh().size())
{
    if (addressing_.headerOk() && weights_.headerOk() && centres_.headerOk())
    {
        // Check if sizes match. Otherwise, re-calculate.
        if
        (
            addressing_.size() == tgtMesh.nCells() &&
            weights_.size() == tgtMesh.nCells() &&
            centres_.size() == tgtMesh.nCells() &&
           !forceRecalculation
        )
        {
            Info<< " Reading addressing from file." << endl;

            return;
        }

        Info<< " Recalculating addressing." << endl;
    }
    else
    {
        Info<< " Calculating addressing." << endl;
    }

    // Check if the source mesh has a calculated addressing
    // If yes, try and invert that.
    IOobject srcHeader
    (
        "addressing",
        srcMesh.time().timeName(),
        srcMesh,
        IOobject::READ_IF_PRESENT,
        IOobject::NO_WRITE
    );

    if (srcHeader.headerOk() && !addressing_.headerOk())
    {
        Info<< " Found addressing in source directory."
            << " Checking for compatibility." << endl;

        if (invertAddressing())
        {
            Info<< " Inversion successful. " << endl;
            return;
        }
    }

    // Track calculation time
    clockTime calcTimer;

    // Compute nearest cell addressing
    calcCellAddressing();

    if (nThreads == 1)
    {
        calcAddressingAndWeights(0, tgtMesh.nCells(), true);
    }
    else
    {
        // Prior to multi-threaded operation,
        // force calculation of demand-driven data
        tgtMesh.cells();
        srcMesh.cells();
        srcMesh.cellCentres();
        srcMesh.cellCells();

        multiThreader threader(nThreads);

        // Set one handler per thread
        PtrList<handler> hdl(threader.getNumThreads());

        forAll(hdl, i)
        {
            hdl.set(i, new handler(*this, threader));
        }

        // Simple, but inefficient load-balancing scheme
        labelList tStarts(threader.getNumThreads(), 0);
        labelList tSizes(threader.getNumThreads(), 0);

        label index = tgtMesh.nCells(), j = 0;

        while (index--)
        {
            tSizes[(j = tSizes.fcIndex(j))]++;
        }

        label total = 0;

        for (label i = 1; i < tStarts.size(); i++)
        {
            tStarts[i] = tSizes[i-1] + total;

            total += tSizes[i-1];
        }

        if (debug)
        {
            Info<< " Load starts: " << tStarts << endl;
            Info<< " Load sizes: " << tSizes << endl;
        }

        // Set the argument list for each thread
        forAll(hdl, i)
        {
            // Size up the argument list
            hdl[i].setSize(2);

            // Set the start/end cell indices
            hdl[i].set(0, &tStarts[i]);
            hdl[i].set(1, &tSizes[i]);

            // Lock the slave thread first
            hdl[i].lock(handler::START);
            hdl[i].unsetPredicate(handler::START);

            hdl[i].lock(handler::STOP);
            hdl[i].unsetPredicate(handler::STOP);
        }
Foam::phaseModel::phaseModel
(
    const fvMesh& mesh,
    const dictionary& transportProperties,
    const word& phaseName
)
:
    dict_
    (
        transportProperties.subDict("phase" + phaseName)
    ),
    name_(phaseName),
    d_
    (
        dict_.lookup("d")
    ),
    nu_
    (
        dict_.lookup("nu")
    ),
    rho_
    (
        dict_.lookup("rho")
    ),
    U_
    (
        IOobject
        (
            "U" + phaseName,
            mesh.time().timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        mesh
    )
{
    const word phiName = "phi" + phaseName;

    IOobject phiHeader
    (
        phiName,
        mesh.time().timeName(),
        mesh,
        IOobject::NO_READ
    );

    if (phiHeader.headerOk())
    {
        Info<< "Reading face flux field " << phiName << endl;

        phiPtr_.reset
        (
            new surfaceScalarField
            (
                IOobject
                (
                    phiName,
                    mesh.time().timeName(),
                    mesh,
                    IOobject::MUST_READ,
                    IOobject::AUTO_WRITE
                ),
                mesh
            )
        );
    }
    else
    {
        Info<< "Calculating face flux field " << phiName << endl;

        wordList phiTypes
        (
            U_.boundaryField().size(),
            calculatedFvPatchScalarField::typeName
        );

        for (label i=0; i<U_.boundaryField().size(); i++)
        {
            if (isType<fixedValueFvPatchVectorField>(U_.boundaryField()[i]))
            {
                phiTypes[i] = fixedValueFvPatchScalarField::typeName;
            }
        }

        phiPtr_.reset
        (
            new surfaceScalarField
            (
                IOobject
                (
                    phiName,
                    mesh.time().timeName(),
                    mesh,
                    IOobject::NO_READ,
                    IOobject::AUTO_WRITE
                ),
                fvc::interpolate(U_) & mesh.Sf(),
                phiTypes
            )
        );
    }
}
void reportValues(
    const word &fieldName,
    const fvMesh &mesh,
    CommonValueExpressionDriver &driver,
    const string &entName
) {
    startLine(
        mesh.time(),
        entName
    );

    Field<Type> result(
        driver.evaluate<Type>(fieldName)
    );

    AccumulationCalculation<Type> calculator(
        result,
        false,
        driver
    );

    writeData(Info,calculator.size(),"Size | Weight Sum","size");
    Info << " | ";
    writeData(Info,calculator.weightSum(),"","weight_sum",true);

    writeData(Info,calculator.minimum(),"Range (min-max)","minimum");
    Info << " | ";
    writeData(Info,calculator.maximum(),"","maximum",true);

    writeData(
        Info,calculator.average(),
        "Average | weighted","average");
    Info << " | ";
    writeData(
        Info,calculator.weightedAverage(),
        "","average_weighted",true);

    writeData(
        Info,calculator.sum(),
        "Sum | weighted","sum");
    Info << " | ";
    writeData(
        Info,calculator.weightedSum(),
        "","sum_weighted",true);

    writeData(
        Info,calculator.distribution().median(),
        "Median | weighted","median");
    Info << " | ";
    writeData(
        Info,calculator.weightedDistribution().median(),
        "","median_weighted",true);

    if(nrOfQuantiles) {
        scalar dx=1./nrOfQuantiles;
        for(label i=1;i<nrOfQuantiles;i++) {
            scalar thisQuantile=dx*i;
            NumericAccumulationNamedEnum::accuSpecification quant(
                NumericAccumulationNamedEnum::numQuantile,
                thisQuantile
            );
            NumericAccumulationNamedEnum::accuSpecification wquant(
                NumericAccumulationNamedEnum::numWeightedQuantile,
                thisQuantile
            );
            OStringStream annotation;
            annotation << thisQuantile << " quantile | weighted";

            writeData(
                Info,calculator(quant),
                annotation.str(),NumericAccumulationNamedEnum::toString(quant));
            Info << " | ";
            writeData(
                Info,calculator(wquant),
                "",NumericAccumulationNamedEnum::toString(wquant),true);
        }
    }

    forAll(fractionSmallerThan,i) {
        scalar value=fractionSmallerThan[i];
        NumericAccumulationNamedEnum::accuSpecification smaller(
            NumericAccumulationNamedEnum::numSmaller,
            value
        );
        NumericAccumulationNamedEnum::accuSpecification wsmaller(
            NumericAccumulationNamedEnum::numWeightedSmaller,
            value
        );
        OStringStream annotation;
        annotation << "x <= " << value << " | weighted";

        writeData(
            Info,calculator(smaller),
            annotation.str(),NumericAccumulationNamedEnum::toString(smaller));
        Info << " | ";
        writeData(
            Info,calculator(wsmaller),
            "",NumericAccumulationNamedEnum::toString(wsmaller),true);
    }
bool caseIsCompressible(const fvMesh& mesh)
{
    // Attempt flux field
    IOobject phiHeader
    (
        "phi",
        mesh.time().timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::NO_WRITE
    );

    if (phiHeader.headerOk())
    {
        surfaceScalarField phi(phiHeader, mesh);
        if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
        {
            return true;
        }
    }

    // Attempt density field
    IOobject rhoHeader
    (
        "rho",
        mesh.time().timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::NO_WRITE
    );

    if (rhoHeader.headerOk())
    {
        volScalarField rho(rhoHeader, mesh);
        if (rho.dimensions() == dimDensity)
        {
            return true;
        }
    }

    // Attempt pressure field
    IOobject pHeader
    (
        "p",
        mesh.time().timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::NO_WRITE
    );

    if (pHeader.headerOk())
    {
        volScalarField p(pHeader, mesh);
        if (p.dimensions() == dimMass/sqr(dimTime)/dimLength)
        {
            return true;
        }
    }

    // If none of the above are true, assume that the case is incompressible
    return false;
}
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 field
    word backupName(dict.name() + ".old");
    Info<< "    copying " << dict.name() << " to "
        << backupName << endl;
    IOdictionary dictOld = dict;
    dictOld.rename(backupName);
    dictOld.regIOobject::write();

    // Loop through boundary patches and update
    const polyBoundaryMesh& bMesh = mesh.boundaryMesh();
    dictionary& boundaryDict = dict.subDict("boundaryField");
    forAll(bMesh, patchI)
    {
        if (bMesh[patchI].isWall())
        {
            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();
}
Foam::quadratureNode<weightType, abscissaType>::quadratureNode
(
    const word& name,
    const label nSecondaryNodes,
    const fvMesh& mesh,
    const dimensionSet& weightDimensions,
    const dimensionSet& abscissaDimensions
)
:
    name_(name),
    nSecondaryNodes_(nSecondaryNodes),
    primaryWeight_
    (
        IOobject
        (
            IOobject::groupName(name_, "primaryWeight"),
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        dimensionedScalar("zeroWeight", weightDimensions, 0.0)
    ),
    primaryAbscissa_
    (
        IOobject
        (
            IOobject::groupName(name_, "primaryAbscissa"),
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        dimensionedScalar("zeroAbscissa", abscissaDimensions, 0.0)
    ),
    secondaryWeights_(nSecondaryNodes_),
    secondaryAbscissae_(nSecondaryNodes_),
    sigma_
    (
        IOobject
        (
            IOobject::groupName(name_, "sigma"),
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        dimensionedScalar("zeroSigma", dimless, 0.0)
    ),
    extended_(true)
{
    forAll(secondaryWeights_, nodeI)
    {
        secondaryWeights_.set
        (
            nodeI,
            new weightType
            (
                IOobject
                (
                    IOobject::groupName
                    (
                        name_,
                        "secondaryWeight." + Foam::name(nodeI)
                    ),
                    mesh.time().timeName(),
                    mesh,
                    IOobject::NO_READ,
                    IOobject::NO_WRITE
                ),
                mesh,
                dimensionedScalar("zeroWeight", dimless, 0.0)
            )
        );

        secondaryAbscissae_.set
        (
            nodeI,
            new abscissaType
            (
                IOobject
                (
                    IOobject::groupName
                    (
                        name_,
                        "secondaryAbscissa." + Foam::name(nodeI)
                    ),
                    mesh.time().timeName(),
                    mesh,
                    IOobject::NO_READ,
                    IOobject::NO_WRITE
                ),
                mesh,
                dimensionedScalar("zeroAbscissa", abscissaDimensions, 0.0)            
            )
        );
    }