int main(int argc, char *argv[])
{

#   include "setRootCase.H"

#   include "createTime.H"

    // Get times list
    instantList Times = runTime.times();

    const label startTime = 1;
    const label endTime = Times.size();
    const label nSnapshots = Times.size() - 1;

    Info << "Number of snapshots: " << nSnapshots << endl;

    // Create a list of snapshots
    PtrList<volVectorField> fields(nSnapshots);

    runTime.setTime(Times[startTime], startTime);

#   include "createMesh.H"

    IOdictionary PODsolverDict
    (
        IOobject
        (
            "PODsolverDict",
            runTime.system(),
            mesh,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    );

    scalar accuracy =
        readScalar
        (
            PODsolverDict.subDict("scalarTransportCoeffs").lookup("accuracy")
        );

    Info << "Seeking accuracy: " << accuracy << endl;

    word fieldName
    (
        PODsolverDict.subDict("scalarTransportCoeffs").lookup("velocity")
    );

    label snapI = 0;

    labelList timeIndices(nSnapshots);

    for (label i = startTime; i < endTime; i++)
    {
        runTime.setTime(Times[i], i);

        Info<< "Time = " << runTime.timeName() << endl;

        mesh.readUpdate();

        Info<< "    Reading " << fieldName << endl;
        fields.set
        (
            snapI,
            new volVectorField
            (
                IOobject
                (
                    fieldName,
                    runTime.timeName(),
                    mesh,
                    IOobject::MUST_READ
                ),
                mesh
            )
        );

        // Rename the field
        fields[snapI].rename(fieldName + name(i));
        timeIndices[snapI] = i;
        snapI++;

        Info<< endl;
    }

    timeIndices.setSize(snapI);

    vectorPODOrthoNormalBase eb(fields, accuracy);

    const RectangularMatrix<vector>& coeffs = eb.interpolationCoeffs();

    // Check all snapshots
    forAll (fields, fieldI)
    {
        runTime.setTime(Times[timeIndices[fieldI]], timeIndices[fieldI]);

        volVectorField reconstruct
        (
            IOobject
            (
                fieldName + "PODreconstruct",
                runTime.timeName(),
                mesh,
                IOobject::NO_READ
            ),
            mesh,
            dimensionedVector
            (
                "zero",
                fields[fieldI].dimensions(),
                vector::zero
            )
        );

        for (label baseI = 0; baseI < eb.baseSize(); baseI++)
        {
            reconstruct +=
                cmptMultiply
                (
                    eb.orthoField(baseI),
                    coeffs[fieldI][baseI]
                );
        }

        scalar sumFieldError =
            sumMag
            (
                reconstruct.internalField()
              - fields[fieldI].internalField()
            );

        scalar measure = sumMag(fields[fieldI].internalField()) + SMALL;

        Info<< "Field error: absolute = " << sumFieldError << " relative = "
            << sumFieldError/measure << " measure = " << measure
            << endl;

        reconstruct.write();
    }
void dsmcCLLWallPatch::setProperties()
{
    velocity_ = propsDict_.lookup("velocity");
    temperature_ = readScalar(propsDict_.lookup("temperature"));
}
示例#3
0
void Foam::MULES::implicitSolve
(
    const RhoType& rho,
    volScalarField& psi,
    const surfaceScalarField& phi,
    surfaceScalarField& phiPsi,
    const SpType& Sp,
    const SuType& Su,
    const scalar psiMax,
    const scalar psiMin
)
{
    const fvMesh& mesh = psi.mesh();

    const dictionary& MULEScontrols = mesh.solverDict(psi.name());

    label maxIter
    (
        readLabel(MULEScontrols.lookup("maxIter"))
    );

    label nLimiterIter
    (
        readLabel(MULEScontrols.lookup("nLimiterIter"))
    );

    scalar maxUnboundedness
    (
        readScalar(MULEScontrols.lookup("maxUnboundedness"))
    );

    scalar CoCoeff
    (
        readScalar(MULEScontrols.lookup("CoCoeff"))
    );

    scalarField allCoLambda(mesh.nFaces());

    {
        surfaceScalarField Cof
        (
            mesh.time().deltaT()*mesh.surfaceInterpolation::deltaCoeffs()
           *mag(phi)/mesh.magSf()
        );

        slicedSurfaceScalarField CoLambda
        (
            IOobject
            (
                "CoLambda",
                mesh.time().timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE,
                false
            ),
            mesh,
            dimless,
            allCoLambda,
            false   // Use slices for the couples
        );

        CoLambda == 1.0/max(CoCoeff*Cof, scalar(1));
    }

    scalarField allLambda(allCoLambda);
    //scalarField allLambda(mesh.nFaces(), 1.0);

    slicedSurfaceScalarField lambda
    (
        IOobject
        (
            "lambda",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE,
            false
        ),
        mesh,
        dimless,
        allLambda,
        false   // Use slices for the couples
    );

    linear<scalar> CDs(mesh);
    upwind<scalar> UDs(mesh, phi);
    //fv::uncorrectedSnGrad<scalar> snGrads(mesh);

    fvScalarMatrix psiConvectionDiffusion
    (
        fvm::ddt(rho, psi)
      + fv::gaussConvectionScheme<scalar>(mesh, phi, UDs).fvmDiv(phi, psi)
        //- fv::gaussLaplacianScheme<scalar, scalar>(mesh, CDs, snGrads)
        //.fvmLaplacian(Dpsif, psi)
      - fvm::Sp(Sp, psi)
      - Su
    );

    surfaceScalarField phiBD(psiConvectionDiffusion.flux());

    surfaceScalarField& phiCorr = phiPsi;
    phiCorr -= phiBD;

    for (label i=0; i<maxIter; i++)
    {
        if (i != 0 && i < 4)
        {
            allLambda = allCoLambda;
        }

        limiter
        (
            allLambda,
            rho,
            psi,
            phiBD,
            phiCorr,
            Sp.field(),
            Su.field(),
            psiMax,
            psiMin,
            nLimiterIter
        );

        solve
        (
            psiConvectionDiffusion + fvc::div(lambda*phiCorr),
            MULEScontrols
        );

        scalar maxPsiM1 = gMax(psi.internalField()) - 1.0;
        scalar minPsi = gMin(psi.internalField());

        scalar unboundedness = max(max(maxPsiM1, 0.0), -min(minPsi, 0.0));

        if (unboundedness < maxUnboundedness)
        {
            break;
        }
        else
        {
            Info<< "MULES: max(" << psi.name() << " - 1) = " << maxPsiM1
                << " min(" << psi.name() << ") = " << minPsi << endl;

            phiBD = psiConvectionDiffusion.flux();

            /*
            word gammaScheme("div(phi,gamma)");
            word gammarScheme("div(phirb,gamma)");

            const surfaceScalarField& phir =
                mesh.lookupObject<surfaceScalarField>("phir");

            phiCorr =
                fvc::flux
                (
                    phi,
                    psi,
                    gammaScheme
                )
              + fvc::flux
                (
                    -fvc::flux(-phir, scalar(1) - psi, gammarScheme),
                    psi,
                    gammarScheme
                )
                - phiBD;
            */
        }
    }

    phiPsi = psiConvectionDiffusion.flux() + lambda*phiCorr;
}
// Construct from components
Foam::autoHexMeshDriver::autoHexMeshDriver
(
    fvMesh& mesh,
    const bool overwrite,
    const dictionary& dict,
    const dictionary& decomposeDict
)
:
    mesh_(mesh),
    dict_(dict),
    debug_(readLabel(dict_.lookup("debug"))),
    mergeDist_(getMergeDistance(readScalar(dict_.lookup("mergeTolerance"))))
{
    if (debug_ > 0)
    {
        meshRefinement::debug = debug_;
        autoHexMeshDriver::debug = debug_;
        autoRefineDriver::debug = debug;
        autoSnapDriver::debug = debug;
        autoLayerDriver::debug = debug;
    }

    refinementParameters refineParams(dict, 1);

    Info<< "Overall cell limit                         : "
        << refineParams.maxGlobalCells() << endl;
    Info<< "Per processor cell limit                   : "
        << refineParams.maxLocalCells() << endl;
    Info<< "Minimum number of cells to refine          : "
        << refineParams.minRefineCells() << endl;
    Info<< "Curvature                                  : "
        << refineParams.curvature() << nl << endl;
    Info<< "Layers between different refinement levels : "
        << refineParams.nBufferLayers() << endl;

    PtrList<dictionary> shellDicts(dict_.lookup("refinementShells"));

    PtrList<dictionary> surfaceDicts(dict_.lookup("surfaces"));


    // Read geometry
    // ~~~~~~~~~~~~~

    {
        Info<< "Reading all geometry." << endl;

        // Construct dictionary with all shells and all refinement surfaces
        dictionary geometryDict;

        forAll(shellDicts, shellI)
        {
            dictionary shellDict = shellDicts[shellI];
            const word name(shellDict.lookup("name"));
            shellDict.remove("name");
            shellDict.remove("level");
            shellDict.remove("refineInside");
            geometryDict.add(name, shellDict);
        }

        forAll(surfaceDicts, surfI)
        {
            dictionary surfDict = surfaceDicts[surfI];
            const word name(string::validate<word>(surfDict.lookup("file")));
            surfDict.remove("file");
            surfDict.remove("regions");
            if (!surfDict.found("name"))
            {
                surfDict.add("name", name);
            }
            surfDict.add("type", triSurfaceMesh::typeName);
            geometryDict.add(name, surfDict);
        }
Foam::liquidProperties::liquidProperties(Istream& is)
:
    W_(readScalar(is)),
    Tc_(readScalar(is)),
    Pc_(readScalar(is)),
    Vc_(readScalar(is)),
    Zc_(readScalar(is)),
    Tt_(readScalar(is)),
    Pt_(readScalar(is)),
    Tb_(readScalar(is)),
    dipm_(readScalar(is)),
    omega_(readScalar(is)),
    delta_(readScalar(is))
{}
// * * * * * * * * * * * * * * * * 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
        )
    ),
    solveFlow_(true),
    solveScalarTransport_(true),
    verbose_(false),
    debug_(false),
    allowCFDsubTimestep_(true),
    ignore_(false),
    modelType_(couplingProperties_.lookup("modelType")),
    positions_(NULL),
    velocities_(NULL),
    fluidVel_(NULL),
    fAcc_(NULL),
    impForces_(NULL),
    expForces_(NULL),
    DEMForces_(NULL),
    Cds_(NULL),
    radii_(NULL),
    voidfractions_(NULL),
    cellIDs_(NULL),
    particleWeights_(NULL),
    particleVolumes_(NULL),
    particleV_(NULL),
    dragPrev_(NULL),
    numberOfParticles_(0),
    d32_(-1),
    numberOfParticlesChanged_(false),
    arraysReallocated_(false),
    forceModels_(couplingProperties_.lookup("forceModels")),
    momCoupleModels_(couplingProperties_.lookup("momCoupleModels")),
    liggghtsCommandModelList_(liggghtsCommandDict_.lookup("liggghtsCommandModels")),
    turbulenceModelType_(couplingProperties_.lookup("turbulenceModelType")),
    isLES_(false),
    cg_(1.),
    cgOK_(true),
    impDEMdrag_(false),
    impDEMdragAcc_(false),
    imExSplitFactor_(1.0),
    treatVoidCellsAsExplicitForce_(false),
    useDDTvoidfraction_("off"),
    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
    ),
    checkPeriodicCells_(false),
    turbulence_
    (
        #if defined(version24Dev)
            mesh.lookupObject<turbulenceModel>
        #elif defined(version21) || defined(version16ext)
            #ifdef compre
                mesh.lookupObject<compressible::turbulenceModel>
            #else
                mesh.lookupObject<incompressible::turbulenceModel>
            #endif
        #elif defined(version15)
            mesh.lookupObject<incompressible::RASModel>
        #endif
        (
            turbulenceModelType_
        )
    ),
    turbulenceMultiphase_
    (   
        IOobject
        (
            "turbulenceMultiphase",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh,
#ifdef compre
        dimensionedScalar("zero", dimensionSet(1,-1,-1,0,0), 0)  // kg/m/s
#else
        dimensionedScalar("zero", dimensionSet(0,2,-1,0,0), 0)  // m²/s
#endif
    ),    
    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,
            (char *)"none",
            (char *)"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"
    global buildInfo(couplingProperties_,*this);
    buildInfo.info();

    //-- apply debug Mode to sub models

    // set debug flag according to env
    debug_ = buildInfo.debugMode();

    // overwrite debug flag if found in dict
    if (couplingProperties_.found("debug"))
        debug_=Switch(couplingProperties_.lookup("debug"));

    // apply flag
    if(!debugMode()) ddtVoidfraction_.writeOpt() = IOobject::NO_WRITE;
    if(!debugMode()) turbulenceMultiphase_.writeOpt() = IOobject::NO_WRITE;
    voidFractionM().applyDebugSettings(debugMode());
    averagingM().applyDebugSettings(debugMode());
    //--

    dataExchangeM().setCG();

    Info << "If BC are important, please provide volScalarFields -imp/expParticleForces-" << endl;
    if (couplingProperties_.found("solveFlow"))
        solveFlow_=Switch(couplingProperties_.lookup("solveFlow"));
    if (couplingProperties_.found("solveScalarTransport"))
        solveScalarTransport_=Switch(couplingProperties_.lookup("solveScalarTransport"));
    if (couplingProperties_.found("imExSplitFactor"))
        imExSplitFactor_ = readScalar(couplingProperties_.lookup("imExSplitFactor"));

    if(imExSplitFactor_>1.0)
            FatalError  << "You have set imExSplitFactor > 1 in your couplingProperties. Must be <=1."
                       << abort(FatalError);
    if(imExSplitFactor_<0.0)
            FatalError  << "You have set imExSplitFactor < 0 in your couplingProperties. Must be >=0"
                       << abort(FatalError);

    if (couplingProperties_.found("treatVoidCellsAsExplicitForce"))
        treatVoidCellsAsExplicitForce_ = readBool(couplingProperties_.lookup("treatVoidCellsAsExplicitForce"));
    if (couplingProperties_.found("verbose")) verbose_=true;
    if (couplingProperties_.found("ignore")) ignore_=true;
    if (turbulenceModelType_=="LESProperties")
    {
        isLES_ = true;
        Info << "WARNING - LES functionality not yet tested!" << endl;
    }

    if (couplingProperties_.found("useDDTvoidfraction"))
    {
        useDDTvoidfraction_=word(couplingProperties_.lookup("useDDTvoidfraction"));

        if(useDDTvoidfraction_==word("a") || 
           useDDTvoidfraction_==word("b") ||
           useDDTvoidfraction_==word("off")
          )
            Info << "choice for ddt(voidfraction) = " << useDDTvoidfraction_ << endl;
        else
            FatalError << "Model " << useDDTvoidfraction_ 
                       << " is not a valid choice for ddt(voidfraction). Choose a or b or off."
                       << abort(FatalError);
    }
    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]
        );
        forceModel_[i]().applyDebugSettings(debugMode());
    }

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

    // 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
        );
    }

    Switch cgWarnOnly_(couplingProperties_.lookupOrDefault<Switch>("cgWarnOnly", true));
    if (!cgOK_ && cg_ > 1)
    {
        if(cgWarnOnly_)
            Warning<< "at least one of your models is not fit for cg !!!"<< endl; 
        else
            FatalError<< "at least one of your models is not fit for cg !!!"<< abort(FatalError); 
    }

    // check if sim is fully peridic box
    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
    int nPatchesCyclic(0);
    int nPatchesNonCyclic(0);
    forAll(patches, patchI)
    {
        const polyPatch& pp = patches[patchI];
        #if defined(versionExt32)
        if (isA<cyclicPolyPatch>(pp))
            nPatchesCyclic++;
        else if (!isA<processorPolyPatch>(pp))
            nPatchesNonCyclic++;
        #else
        if (isA<cyclicPolyPatch>(pp) || isA<cyclicAMIPolyPatch>(pp))
            nPatchesCyclic++;
        else if (!isA<processorPolyPatch>(pp))
            nPatchesNonCyclic++;
        #endif
    }
    if(nPatchesNonCyclic==0)
        checkPeriodicCells_=true;
    if(nPatchesCyclic>0 && nPatchesNonCyclic>0)
    {
        if(verbose_) Info << "nPatchesNonCyclic=" << nPatchesNonCyclic << ", nPatchesCyclic=" << nPatchesCyclic << endl;
        Warning << "Periodic handing is disabled because the domain is not fully periodic!\n" << endl;
    }
}
示例#7
0
Foam::Istream& Foam::ISstream::read(token& t)
{
    static const int maxLen = 128;
    static char buf[maxLen];

    // Return the put back token if it exists
    if (Istream::getBack(t))
    {
        return *this;
    }

    // Assume that the streams supplied are in working order.
    // Lines are counted by '\n'

    // Get next 'valid character': i.e. proceed through any whitespace
    // and/or comments until a semantically valid character is found

    char c = nextValid();

    // Set the line number of this token to the current stream line number
    t.lineNumber() = lineNumber();

    // return on error
    if (!c)
    {
        t.setBad();
        return *this;
    }

    // Analyse input starting with this character.
    switch (c)
    {
        // Check for punctuation first

        case token::END_STATEMENT :
        case token::BEGIN_LIST :
        case token::END_LIST :
        case token::BEGIN_SQR :
        case token::END_SQR :
        case token::BEGIN_BLOCK :
        case token::END_BLOCK :
        case token::COLON :
        case token::COMMA :
        case token::ASSIGN :
        case token::ADD :
        // NB: token::SUBTRACT handled later as the possible start of a Number
        case token::MULTIPLY :
        case token::DIVIDE :
        {
            t = token::punctuationToken(c);
            return *this;
        }


        // String: enclosed by double quotes.
        case token::BEGIN_STRING :
        {
            putback(c);
            string* sPtr = new string;

            if (read(*sPtr).bad())
            {
                delete sPtr;
                t.setBad();
            }
            else
            {
                t = sPtr;
            }

            return *this;
        }
        // Possible verbatim string or dictionary functionEntry
        case token::HASH :
        {
            char nextC;
            if (read(nextC).bad())
            {
                // Return hash as word
                t = token(word(c));
                return *this;
            }
            else if (nextC == token::BEGIN_BLOCK)
            {
                // Verbatim string
                string* sPtr = new string;

                if (readVerbatim(*sPtr).bad())
                {
                    delete sPtr;
                    t.setBad();
                }
                else
                {
                    t = sPtr;
                    t.type() = token::VERBATIMSTRING;
                }

                return *this;
            }
            else
            {
                // Word beginning with #
                putback(nextC);
                putback(c);

                readWordToken(t);

                return *this;
            }
        }

        case '$':
        {
            // Look ahead
            char nextC;
            if (read(nextC).bad())
            {
                // Return $ as word
                t = token(word(c));
                return *this;
            }
            else if (nextC == token::BEGIN_BLOCK)
            {
                putback(nextC);
                putback(c);

                string* sPtr = new string;

                if (readVariable(*sPtr).bad())
                {
                    delete sPtr;
                    t.setBad();
                }
                else
                {
                    t = sPtr;
                    t.type() = token::VARIABLE;
                }
                return *this;
            }
            else
            {
                putback(nextC);
                putback(c);
                readWordToken(t);
                return *this;
            }
        }

        // Number: integer or floating point
        //
        // ideally match the equivalent of this regular expression
        //
        //    /[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)([Ee][-+]?[0-9]+)?/
        //
        case '-' :
        case '.' :
        case '0' : case '1' : case '2' : case '3' : case '4' :
        case '5' : case '6' : case '7' : case '8' : case '9' :
        {
            bool asLabel = (c != '.');

            int nChar = 0;
            buf[nChar++] = c;

            // get everything that could resemble a number and let
            // readScalar determine the validity
            while
            (
                is_.get(c)
             && (
                    isdigit(c)
                 || c == '+'
                 || c == '-'
                 || c == '.'
                 || c == 'E'
                 || c == 'e'
                )
            )
            {
                if (asLabel)
                {
                    asLabel = isdigit(c);
                }

                buf[nChar++] = c;
                if (nChar == maxLen)
                {
                    // runaway argument - avoid buffer overflow
                    buf[maxLen-1] = '\0';

                    FatalIOErrorIn("ISstream::read(token&)", *this)
                        << "number '" << buf << "...'\n"
                        << "    is too long (max. " << maxLen << " characters)"
                        << exit(FatalIOError);

                    t.setBad();
                    return *this;
                }
            }
            buf[nChar] = '\0';

            setState(is_.rdstate());
            if (is_.bad())
            {
                t.setBad();
            }
            else
            {
                is_.putback(c);

                if (nChar == 1 && buf[0] == '-')
                {
                    // a single '-' is punctuation
                    t = token::punctuationToken(token::SUBTRACT);
                }
                else
                {
                    if (asLabel)
                    {
                        label labelVal = 0;
                        if (Foam::read(buf, labelVal))
                        {
                            t = labelVal;
                        }
                        else
                        {
                            // Maybe too big? Try as scalar
                            scalar scalarVal;
                            if (readScalar(buf, scalarVal))
                            {
                                t = scalarVal;
                            }
                            else
                            {
                                t.setBad();
                            }
                        }
                    }
                    else
                    {
                        scalar scalarVal;
                        if (readScalar(buf, scalarVal))
                        {
                            t = scalarVal;
                        }
                        else
                        {
                            t.setBad();
                        }
                    }
                }
            }

            return *this;
        }


        // Should be a word (which can also be a single character)
        default:
        {
            putback(c);
            readWordToken(t);

            return *this;
        }
    }
}
void Foam::pistonSliding::addZonesAndModifiers()
{
    // Add the zones and mesh modifiers to operate piston motion

    if
    (
        pointZones().size() > 0
     || faceZones().size() > 0
     || cellZones().size() > 0
     || topoChanger_.size() > 0
    )
    {
        Info<< "Time = " << engTime().theta() << endl;
        Info<< "void Foam::verticalValvesGambit::addZonesAndModifiers() : "
            << "Zones and modifiers already present.  Skipping."
            << endl;

        setVirtualPositions();
//        checkAndCalculate();

        Info << "Point zones found = " << pointZones().size() << endl;
        Info << "Face zones found = " << faceZones().size() << endl;
        Info << "Cell zones found = " << cellZones().size() << endl;

        return;

    }

    if
    (
        engTime().engineDict().found("zOffsetGambit")
     && engTime().engineDict().found("zDisplGambit")
    )
    {
        Info << "Assembling the cylinder mesh" << endl;

        scalar zOffset
        (
            readScalar(engTime().engineDict().lookup("zOffsetGambit"))
        );

        scalar zDispl
        (
            readScalar(engTime().engineDict().lookup("zDisplGambit"))
        );

        pointField pDispl = points();

        forAll(points(), pointI)
        {
            const point p = points()[pointI];

            if(p.z() >= zOffset)
            {
                pDispl[pointI].z() -= zDispl;
            }
        }

        movePoints(pDispl);
        write();
        resetMotion();

        Info << "Cylinder mesh assembled" << endl;
    }
示例#9
0
// Construct from dictionary
Foam::engineValve::engineValve
(
    const word& name,
    const polyMesh& mesh,
    const dictionary& dict
)
:
    name_(name),
    mesh_(mesh),
    engineDB_(refCast<const engineTime>(mesh_.time())),
    csPtr_
    (
        coordinateSystem::New
        (
            "coordinateSystem",
            dict.subDict("coordinateSystem")
        )
    ),
    bottomPatch_(dict.lookup("bottomPatch"), mesh.boundaryMesh()),
    poppetPatch_(dict.lookup("poppetPatch"), mesh.boundaryMesh()),
    stemPatch_(dict.lookup("stemPatch"), mesh.boundaryMesh()),
    curtainInPortPatch_
    (
        dict.lookup("curtainInPortPatch"),
        mesh.boundaryMesh()
    ),
    curtainInCylinderPatch_
    (
        dict.lookup("curtainInCylinderPatch"),
        mesh.boundaryMesh()
    ),
    detachInCylinderPatch_
    (
        dict.lookup("detachInCylinderPatch"),
        mesh.boundaryMesh()
    ),
    detachInPortPatch_
    (
        dict.lookup("detachInPortPatch"),
        mesh.boundaryMesh()
    ),
    detachFaces_(dict.lookup("detachFaces")),
    liftProfile_
    (
        "theta",
        "lift",
        name_,
        IFstream
        (
            mesh.time().path()/mesh.time().constant()/
            word(dict.lookup("liftProfileFile"))
        )()
    ),
    liftProfileStart_(min(liftProfile_.x())),
    liftProfileEnd_(max(liftProfile_.x())),
    minLift_(readScalar(dict.lookup("minLift"))),
    minTopLayer_(readScalar(dict.lookup("minTopLayer"))),
    maxTopLayer_(readScalar(dict.lookup("maxTopLayer"))),
    minBottomLayer_(readScalar(dict.lookup("minBottomLayer"))),
    maxBottomLayer_(readScalar(dict.lookup("maxBottomLayer"))),
    diameter_(readScalar(dict.lookup("diameter")))
{}
示例#10
0
int main(int argc, char *argv[])
{
    #include "setRootCase.H"
    #include "createTime.H"
    #include "createMesh.H"

{
    scalarField samples(4);
    samples[0] = 0;
    samples[1] = 1;
    samples[2] = 2;
    samples[3] = 3;
    scalarField values(4);
    values = 1.0;
    //values[0] = 0.0;
    //values[1] = 1.0;

    linearInterpolationWeights interpolator
    //splineInterpolationWeights interpolator
    (
        samples
    );
    labelList indices;
    scalarField weights;

    interpolator.integrationWeights(1.1, 1.2, indices, weights);
    Pout<< "indices:" << indices << endl;
    Pout<< "weights:" << weights << endl;

    scalar baseSum = interpolator.weightedSum
    (
        weights,
        UIndirectList<scalar>(values, indices)
    );
    Pout<< "baseSum=" << baseSum << nl << nl << endl;


//    interpolator.integrationWeights(-0.01, 0, indices, weights);
//    scalar partialSum = interpolator.weightedSum
//    (
//        weights,
//        UIndirectList<scalar>(values, indices)
//    );
//    Pout<< "partialSum=" << partialSum << nl << nl << endl;
//
//
//    interpolator.integrationWeights(-0.01, 1, indices, weights);
//    //Pout<< "samples:" << samples << endl;
//    //Pout<< "indices:" << indices << endl;
//    //Pout<< "weights:" << weights << endl;
//    scalar sum = interpolator.weightedSum
//    (
//        weights,
//        UIndirectList<scalar>(values, indices)
//    );
//    Pout<< "integrand=" << sum << nl << nl << endl;


    return 1;
}

    IOdictionary function1Properties
    (
        IOobject
        (
            "function1Properties",
            runTime.constant(),
            mesh,
            IOobject::MUST_READ_IF_MODIFIED,
            IOobject::NO_WRITE
        )
    );

    autoPtr<Function1<scalar>> function1
    (
        Function1<scalar>::New
        (
            "function1",
            function1Properties
        )
    );

    scalar x0 = readScalar(function1Properties.lookup("x0"));
    scalar x1 = readScalar(function1Properties.lookup("x1"));

    Info<< "Data entry type: " << function1().type() << nl << endl;

    Info<< "Inputs" << nl
        << "    x0 = " << x0 << nl
        << "    x1 = " << x1 << nl
        << endl;

    Info<< "Interpolation" << nl
        << "    f(x0) = " << function1().value(x0) << nl
        << "    f(x1) = " << function1().value(x1) << nl
        << endl;

    Info<< "Integration" << nl
        << "    int(f(x)) lim(x0->x1) = " << function1().integrate(x0, x1) << nl
        << endl;

    return 0;
}
// Construct from dictionary
Foam::dirichletNeumannFriction::dirichletNeumannFriction
(
    const word& name,
    const fvPatch& patch,
    const dictionary& dict,
    const label masterPatchID,
    const label slavePatchID,
    const label masterFaceZoneID,
    const label slaveFaceZoneID
)
:
  frictionContactModel
  (
      name,
      patch,
      dict,
      masterPatchID,
      slavePatchID,
      masterFaceZoneID,
      slaveFaceZoneID
      ),
  frictionContactModelDict_(dict.subDict(name+"FrictionModelDict")),
  frictionLawPtr_(NULL),
  mesh_(patch.boundaryMesh().mesh()),
  slaveDisp_(mesh().boundaryMesh()[slavePatchID].size(), vector::zero),
  oldSlaveDisp_(slaveDisp_),
  oldSlip_(slaveDisp_.size(), vector::zero),
  slaveTraction_(mesh().boundaryMesh()[slavePatchID].size(), vector::zero),
  oldSlaveTraction_(slaveTraction_),
  slaveValueFrac_(mesh_.boundaryMesh()[slavePatchID].size(), symmTensor::zero),
  oldSlaveValueFrac_(slaveValueFrac_),
  relaxationFactor_
  (readScalar(frictionContactModelDict_.lookup("relaxationFactor"))),
  contactIterNum_(0),
  infoFreq_(readInt(frictionContactModelDict_.lookup("infoFrequency"))),
  oscillationCorr_(frictionContactModelDict_.lookup("oscillationCorrection")),
  smoothingSteps_(readInt(frictionContactModelDict_.lookup("smoothingSteps"))),
  oldStickSlip_(slaveDisp_.size(), 0.0),
  contactFilePtr_(NULL)
{
  // create friction law
  frictionLawPtr_ = frictionLaw::New(
                     frictionContactModelDict_.lookup("frictionLaw"),
                     frictionContactModelDict_
                     ).ptr();

  // master proc open contact info file
  if (Pstream::master())
    {
      word masterName = mesh_.boundary()[masterPatchID].name();
      word slaveName = mesh_.boundary()[slavePatchID].name();
      contactFilePtr_ =
          new OFstream
          (fileName("frictionContact_"+masterName+"_"+slaveName+".txt"));
      OFstream& contactFile = *contactFilePtr_;
      int width = 20;
      contactFile << "time";
      contactFile.width(width);
      contactFile << "iterNum";
      contactFile.width(width);
      contactFile << "relaxationFactor";
      contactFile.width(width);
      contactFile << "slipFaces";
      contactFile.width(width);
      contactFile << "stickFaces";
      contactFile.width(width);
      contactFile << "maxMagSlaveTraction" << endl;
    }
}
Foam::PatchInjection<CloudType>::PatchInjection
(
    const dictionary& dict,
    CloudType& owner
)
:
    InjectionModel<CloudType>(dict, owner, typeName),
    patchName_(this->coeffDict().lookup("patchName")),
    duration_(readScalar(this->coeffDict().lookup("duration"))),
    parcelsPerSecond_
    (
        readScalar(this->coeffDict().lookup("parcelsPerSecond"))
    ),
    U0_(this->coeffDict().lookup("U0")),
    volumeFlowRate_
    (
        DataEntry<scalar>::New
        (
            "volumeFlowRate",
            this->coeffDict()
        )
    ),
    parcelPDF_
    (
        pdf::New
        (
            this->coeffDict().subDict("parcelPDF"),
            owner.rndGen()
        )
    ),
    cellOwners_(),
    fraction_(1.0)
{
    label patchId = owner.mesh().boundaryMesh().findPatchID(patchName_);

    if (patchId < 0)
    {
        FatalErrorIn
        (
            "PatchInjection<CloudType>::PatchInjection"
            "("
                "const dictionary&, "
                "CloudType&"
            ")"
        )   << "Requested patch " << patchName_ << " not found" << nl
            << "Available patches are: " << owner.mesh().boundaryMesh().names()
            << nl << exit(FatalError);
    }

    const polyPatch& patch = owner.mesh().boundaryMesh()[patchId];

    cellOwners_ = patch.faceCells();

    label patchSize = cellOwners_.size();
    label totalPatchSize = patchSize;
    reduce(totalPatchSize, sumOp<label>());
    fraction_ = scalar(patchSize)/totalPatchSize;

    // Set total volume/mass to inject
    this->volumeTotal_ = fraction_*volumeFlowRate_().integrate(0.0, duration_);
    this->massTotal_ *= fraction_;
}
Foam::liquidProperties::liquidProperties(const dictionary& dict)
:
    W_(readScalar(dict.lookup("W"))),
    Tc_(readScalar(dict.lookup("Tc"))),
    Pc_(readScalar(dict.lookup("Pc"))),
    Vc_(readScalar(dict.lookup("Vc"))),
    Zc_(readScalar(dict.lookup("Zc"))),
    Tt_(readScalar(dict.lookup("Tt"))),
    Pt_(readScalar(dict.lookup("Pt"))),
    Tb_(readScalar(dict.lookup("Tb"))),
    dipm_(readScalar(dict.lookup("dipm"))),
    omega_(readScalar(dict.lookup("omega"))),
    delta_(readScalar(dict.lookup("delta")))
{}
示例#14
0
void Foam::CSV<Type>::read()
{
    fileName expandedFile(fName_);
    IFstream is(expandedFile.expand());

    if (!is.good())
    {
        FatalIOErrorIn("CSV<Type>::read()", is)
            << "Cannot open CSV file for reading."
            << exit(FatalIOError);
    }

    DynamicList<Tuple2<scalar, Type> > values;

    // skip header
    for (label i = 0; i < nHeaderLine_; i++)
    {
        string line;
        is.getLine(line);
    }

    label nEntries = max(componentColumns_);

    // read data
    while (is.good())
    {
        string line;
        is.getLine(line);


        label n = 0;
        std::size_t pos = 0;
        DynamicList<string> splitted;

        if (mergeSeparators_)
        {
            std::size_t nPos = 0;

            while ((pos != std::string::npos) && (n <= nEntries))
            {
                bool found = false;
                while (!found)
                {
                    nPos = line.find(separator_, pos);

                    if ((nPos != std::string::npos) && (nPos - pos == 0))
                    {
                        pos = nPos + 1;
                    }
                    else
                    {
                        found = true;
                    }
                }

                nPos = line.find(separator_, pos);

                if (nPos == std::string::npos)
                {
                    splitted.append(line.substr(pos));
                    pos = nPos;
                    n++;
                }
                else
                {
                    splitted.append(line.substr(pos, nPos - pos));
                    pos = nPos + 1;
                    n++;
                }
            }
        }
        else
        {
            while ((pos != std::string::npos) && (n <= nEntries))
            {
                std::size_t nPos = line.find(separator_, pos);

                if (nPos == std::string::npos)
                {
                    splitted.append(line.substr(pos));
                    pos = nPos;
                    n++;
                }
                else
                {
                    splitted.append(line.substr(pos, nPos - pos));
                    pos = nPos + 1;
                    n++;
                }
            }
        }


        if (splitted.size() <= 1)
        {
            break;
        }

        scalar x = readScalar(IStringStream(splitted[refColumn_])());
        Type value = readValue(splitted);

        values.append(Tuple2<scalar,Type>(x, value));
    }

    this->table_.transfer(values);
}
示例#15
0
Foam::jjc2014Zone::jjc2014Zone
(
    const word& name,
    const fvMesh& mesh,
    const dictionary& dict
)
:
    name_(name),
    mesh_(mesh),
    dict_(dict),
    cellZoneID_(mesh_.cellZones().findZoneID(name)),
#if OFVERSION<230 || EXTBRANCH == 1
    coordSys_(dict, mesh),
#else
    coordSys_(mesh, dict),
#endif
    porosity_( readScalar( dict_.lookup("porosity") ) ),
    addedMassCoeff_( readScalar( dict_.lookup("gammaAddedMass") ) ),
    D_("D", dimensionSet(0, -2, 0, 0, 0), tensor::zero),
    F_("F", dimensionSet(0, -1, 0, 0, 0), tensor::zero)
{
    Info<< "Creating porous zone: " << name_ << endl;

    autoPtr<Foam::porosityCoefficient> pcPtr( Foam::porosityCoefficient::New( dict ) );

    bool foundZone = (cellZoneID_ != -1);
    reduce(foundZone, orOp<bool>());

    if (!foundZone && Pstream::master())
    {
        FatalErrorIn
        (
            "Foam::jjc2014Zone::jjc2014Zone"
            "(const fvMesh&, const word&, const dictionary&)"
        )   << "cannot find porous cellZone " << name_
            << exit(FatalError);
    }

    // porosity
    if (porosity_ <= 0.0 || porosity_ > 1.0)
    {
        FatalIOErrorIn
        (
                "Foam::jjc2014Zone::jjc2014Zone"
                "(const fvMesh&, const word&, const dictionary&)",
                dict_
        )
        << "out-of-range porosity value " << porosity_
        << exit(FatalIOError);
    }

    // local-to-global transformation tensor
#if OFVERSION<230 || EXTBRANCH == 1
    const tensor& E = coordSys_.R();
#else
    const tensor E = coordSys_.R().R();
#endif

    dimensionedVector d( pcPtr->linearCoefficient() );

    if (D_.dimensions() != d.dimensions())
    {
        FatalIOErrorIn
        (
            "Foam::jjc2014Zone::jjc2014Zone"
            "(const fvMesh&, const word&, const dictionary&)",
            dict_
        )   << "incorrect dimensions for d: " << d.dimensions()
        << " should be " << D_.dimensions()
        << exit(FatalIOError);
    }

    checkNegativeResistance(d);

    D_.value().xx() = d.value().x();
    D_.value().yy() = d.value().y();
    D_.value().zz() = d.value().z();
    D_.value() = (E & D_ & E.T()).value();


    dimensionedVector f( pcPtr->quadraticCoefficient() );

    if (F_.dimensions() != f.dimensions())
    {
        FatalIOErrorIn
        (
            "Foam::jjc2014Zone::jjc2014Zone"
            "(const fvMesh&, const word&, const dictionary&)",
            dict_
        )   << "incorrect dimensions for f: " << f.dimensions()
        << " should be " << F_.dimensions()
        << exit(FatalIOError);
    }

    checkNegativeResistance(f);

    F_.value().xx() = 0.5 * f.value().x();
    F_.value().yy() = 0.5 * f.value().y();
    F_.value().zz() = 0.5 * f.value().z();
    F_.value() = (E & F_ & E.T()).value();

    // it is an error not to define anything
    if
    (
        magSqr(D_.value()) <= VSMALL
     && magSqr(F_.value()) <= VSMALL
    )
    {
        FatalIOErrorIn
        (
            "Foam::jjc2014Zone::jjc2014Zone"
            "(const fvMesh&, const word&, const dictionary&)",
            dict_
        )   << "neither powerLaw (C0/C1) "
               "nor Darcy-Forchheimer law (d/f) specified"
            << exit(FatalIOError);
    }
}
Foam::radiation::greyMeanAbsorptionEmission::greyMeanAbsorptionEmission
(
    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::greyMeanAbsorptionEmission(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::greyMeanAbsorptionEmission(const"
                "dictionary& dict, const fvMesh& mesh)"
            )   << "specie ft is not present " << nl
                << exit(FatalError);

        }
    }
}
void Foam::movingConeTopoFvMesh::addZonesAndModifiers()
{
    // Add zones and modifiers for motion action

    if
    (
        pointZones().size()
     || faceZones().size()
     || cellZones().size()
     || topoChanger_.size()
    )
    {
        Info<< "void movingConeTopoFvMesh::addZonesAndModifiers() : "
            << "Zones and modifiers already present.  Skipping."
            << endl;

        return;
    }

    Info<< "Time = " << time().timeName() << endl
        << "Adding zones and modifiers to the mesh" << endl;

    const vectorField& fc = faceCentres();
    const vectorField& fa = faceAreas();

    labelList zone1(fc.size());
    boolList flipZone1(fc.size(), false);
    label nZoneFaces1 = 0;

    labelList zone2(fc.size());
    boolList flipZone2(fc.size(), false);
    label nZoneFaces2 = 0;

    forAll(fc, faceI)
    {
        if
        (
            fc[faceI].x() > -0.003501
         && fc[faceI].x() < -0.003499
        )
        {
            if ((fa[faceI] & vector(1, 0, 0)) < 0)
            {
                flipZone1[nZoneFaces1] = true;
            }

            zone1[nZoneFaces1] = faceI;
            Info<< "face " << faceI << " for zone 1.  Flip: "
                << flipZone1[nZoneFaces1] << endl;
            nZoneFaces1++;
        }
        else if
        (
            fc[faceI].x() > -0.00701
         && fc[faceI].x() < -0.00699
        )
        {
            zone2[nZoneFaces2] = faceI;

            if ((fa[faceI] & vector(1, 0, 0)) > 0)
            {
                flipZone2[nZoneFaces2] = true;
            }

            Info<< "face " << faceI << " for zone 2.  Flip: "
                << flipZone2[nZoneFaces2] << endl;
            nZoneFaces2++;
        }
    }

    zone1.setSize(nZoneFaces1);
    flipZone1.setSize(nZoneFaces1);

    zone2.setSize(nZoneFaces2);
    flipZone2.setSize(nZoneFaces2);

    Info<< "zone: " << zone1 << endl;
    Info<< "zone: " << zone2 << endl;

    List<pointZone*> pz(0);
    List<faceZone*> fz(2);
    List<cellZone*> cz(0);

    label nFz = 0;

    fz[nFz] =
        new faceZone
        (
            "rightExtrusionFaces",
            zone1,
            flipZone1,
            nFz,
            faceZones()
        );
    nFz++;

    fz[nFz] =
        new faceZone
        (
            "leftExtrusionFaces",
            zone2,
            flipZone2,
            nFz,
            faceZones()
        );
    nFz++;

    fz.setSize(nFz);

    Info<< "Adding mesh zones." << endl;
    addZones(pz, fz, cz);


    // Add layer addition/removal interfaces

    List<polyMeshModifier*> tm(2);
    label nMods = 0;

    tm[nMods] =
        new layerAdditionRemoval
        (
            "right",
            nMods,
            topoChanger_,
            "rightExtrusionFaces",
            readScalar
            (
                motionDict_.subDict("right").lookup("minThickness")
            ),
            readScalar
            (
                motionDict_.subDict("right").lookup("maxThickness")
            )
        );
    nMods++;

    tm[nMods] = new layerAdditionRemoval
    (
        "left",
        nMods,
        topoChanger_,
        "leftExtrusionFaces",
        readScalar
        (
            motionDict_.subDict("left").lookup("minThickness")
        ),
        readScalar
        (
            motionDict_.subDict("left").lookup("maxThickness")
        )
    );
    nMods++;
    tm.setSize(nMods);

    Info<< "Adding " << nMods << " mesh modifiers" << endl;
    topoChanger_.addTopologyModifiers(tm);

    write();
}
bool Foam::motionSmoother::checkMesh
(
    const bool report,
    const polyMesh& mesh,
    const dictionary& dict,
    const labelList& checkFaces,
    const List<labelPair>& baffles,
    labelHashSet& wrongFaces
)
{
    const scalar maxNonOrtho
    (
        readScalar(dict.lookup("maxNonOrtho", true))
    );
    const scalar minVol
    (
        readScalar(dict.lookup("minVol", true))
    );
    const scalar maxConcave
    (
        readScalar(dict.lookup("maxConcave", true))
    );
    const scalar minArea
    (
        readScalar(dict.lookup("minArea", true))
    );
    const scalar maxIntSkew
    (
        readScalar(dict.lookup("maxInternalSkewness", true))
    );
    const scalar maxBounSkew
    (
        readScalar(dict.lookup("maxBoundarySkewness", true))
    );
    const scalar minWeight
    (
        readScalar(dict.lookup("minFaceWeight", true))
    );
    const scalar minVolRatio
    (
        readScalar(dict.lookup("minVolRatio", true))
    );
    const scalar minTwist
    (
        readScalar(dict.lookup("minTwist", true))
    );
    const scalar minTriangleTwist
    (
        readScalar(dict.lookup("minTriangleTwist", true))
    );
    const scalar minDet
    (
        readScalar(dict.lookup("minDeterminant", true))
    );

    label nWrongFaces = 0;

    Info<< "Checking faces in error :" << endl;
    //Pout.setf(ios_base::left);

    if (maxNonOrtho < 180.0-SMALL)
    {
        polyMeshGeometry::checkFaceDotProduct
        (
            report,
            maxNonOrtho,
            mesh,
            mesh.cellCentres(),
            mesh.faceAreas(),
            checkFaces,
            baffles,
            &wrongFaces
        );

        label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());

        Info<< "    non-orthogonality > "
            << setw(3) << maxNonOrtho
            << " degrees                        : "
            << nNewWrongFaces-nWrongFaces << endl;

        nWrongFaces = nNewWrongFaces;
    }

    if (minVol > -GREAT)
    {
        polyMeshGeometry::checkFacePyramids
        (
            report,
            minVol,
            mesh,
            mesh.cellCentres(),
            mesh.points(),
            checkFaces,
            baffles,
            &wrongFaces
        );

        label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());

        Info<< "    faces with face pyramid volume < "
            << setw(5) << minVol << "                 : "
            << nNewWrongFaces-nWrongFaces << endl;

        nWrongFaces = nNewWrongFaces;
    }

    if (maxConcave < 180.0-SMALL)
    {
        polyMeshGeometry::checkFaceAngles
        (
            report,
            maxConcave,
            mesh,
            mesh.faceAreas(),
            mesh.points(),
            checkFaces,
            &wrongFaces
        );

        label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());

        Info<< "    faces with concavity > "
            << setw(3) << maxConcave
            << " degrees                     : "
            << nNewWrongFaces-nWrongFaces << endl;

        nWrongFaces = nNewWrongFaces;
    }

    if (minArea > -SMALL)
    {
        polyMeshGeometry::checkFaceArea
        (
            report,
            minArea,
            mesh,
            mesh.faceAreas(),
            checkFaces,
            &wrongFaces
        );

        label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());

        Info<< "    faces with area < "
            << setw(5) << minArea
            << " m^2                            : "
            << nNewWrongFaces-nWrongFaces << endl;

        nWrongFaces = nNewWrongFaces;
    }

    if (maxIntSkew > 0 || maxBounSkew > 0)
    {
        polyMeshGeometry::checkFaceSkewness
        (
            report,
            maxIntSkew,
            maxBounSkew,
            mesh,
            mesh.cellCentres(),
            mesh.faceCentres(),
            mesh.faceAreas(),
            checkFaces,
            baffles,
            &wrongFaces
        );

        label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());

        Info<< "    faces with skewness > "
            << setw(3) << maxIntSkew
            << " (internal) or " << setw(3) << maxBounSkew
            << " (boundary) : " << nNewWrongFaces-nWrongFaces << endl;

        nWrongFaces = nNewWrongFaces;
    }

    if (minWeight >= 0 && minWeight < 1)
    {
        polyMeshGeometry::checkFaceWeights
        (
            report,
            minWeight,
            mesh,
            mesh.cellCentres(),
            mesh.faceCentres(),
            mesh.faceAreas(),
            checkFaces,
            baffles,
            &wrongFaces
        );

        label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());

        Info<< "    faces with interpolation weights (0..1)  < "
            << setw(5) << minWeight
            << "       : "
            << nNewWrongFaces-nWrongFaces << endl;

        nWrongFaces = nNewWrongFaces;
    }

    if (minVolRatio >= 0)
    {
        polyMeshGeometry::checkVolRatio
        (
            report,
            minVolRatio,
            mesh,
            mesh.cellVolumes(),
            checkFaces,
            baffles,
            &wrongFaces
        );

        label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());

        Info<< "    faces with volume ratio of neighbour cells < "
            << setw(5) << minVolRatio
            << "     : "
            << nNewWrongFaces-nWrongFaces << endl;

        nWrongFaces = nNewWrongFaces;
    }

    if (minTwist > -1)
    {
        //Pout<< "Checking face twist: dot product of face normal "
        //    << "with face triangle normals" << endl;
        polyMeshGeometry::checkFaceTwist
        (
            report,
            minTwist,
            mesh,
            mesh.cellCentres(),
            mesh.faceAreas(),
            mesh.faceCentres(),
            mesh.points(),
            checkFaces,
            &wrongFaces
        );

        label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());

        Info<< "    faces with face twist < "
            << setw(5) << minTwist
            << "                          : "
            << nNewWrongFaces-nWrongFaces << endl;

        nWrongFaces = nNewWrongFaces;
    }

    if (minTriangleTwist > -1)
    {
        //Pout<< "Checking triangle twist: dot product of consecutive triangle"
        //    << " normals resulting from face-centre decomposition" << endl;
        polyMeshGeometry::checkTriangleTwist
        (
            report,
            minTriangleTwist,
            mesh,
            mesh.faceAreas(),
            mesh.faceCentres(),
            mesh.points(),
            checkFaces,
            &wrongFaces
        );

        label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());

        Info<< "    faces with triangle twist < "
            << setw(5) << minTriangleTwist
            << "                      : "
            << nNewWrongFaces-nWrongFaces << endl;

        nWrongFaces = nNewWrongFaces;
    }

    if (minDet > -1)
    {
        polyMeshGeometry::checkCellDeterminant
        (
            report,
            minDet,
            mesh,
            mesh.faceAreas(),
            checkFaces,
            polyMeshGeometry::affectedCells(mesh, checkFaces),
            &wrongFaces
        );

        label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());

        Info<< "    faces on cells with determinant < "
            << setw(5) << minDet << "                : "
            << nNewWrongFaces-nWrongFaces << endl;

        nWrongFaces = nNewWrongFaces;
    }

    //Pout.setf(ios_base::right);

    return nWrongFaces > 0;
}
Foam::sixDoFRigidBodyMotionSolver::sixDoFRigidBodyMotionSolver
(
    const polyMesh& mesh,
    const dictionary& dict
)
:
    displacementMotionSolver(mesh, dict, typeName),
    motion_
    (
        coeffDict(),
        IOobject
        (
            "sixDoFRigidBodyMotionState",
            mesh.time().timeName(),
            "uniform",
            mesh
        ).typeHeaderOk<IOdictionary>(true)
      ? IOdictionary
        (
            IOobject
            (
                "sixDoFRigidBodyMotionState",
                mesh.time().timeName(),
                "uniform",
                mesh,
                IOobject::READ_IF_PRESENT,
                IOobject::NO_WRITE,
                false
            )
        )
      : coeffDict()
    ),
    patches_(wordReList(coeffDict().lookup("patches"))),
    patchSet_(mesh.boundaryMesh().patchSet(patches_)),
    di_(readScalar(coeffDict().lookup("innerDistance"))),
    do_(readScalar(coeffDict().lookup("outerDistance"))),
    test_(coeffDict().lookupOrDefault<Switch>("test", false)),
    rhoInf_(1.0),
    rhoName_(coeffDict().lookupOrDefault<word>("rho", "rho")),
    scale_
    (
        IOobject
        (
            "motionScale",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE,
            false
        ),
        pointMesh::New(mesh),
        dimensionedScalar(dimless, 0)
    ),
    curTimeIndex_(-1)
{
    if (rhoName_ == "rhoInf")
    {
        rhoInf_ = readScalar(coeffDict().lookup("rhoInf"));
    }

    // Calculate scaling factor everywhere
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    {
        const pointMesh& pMesh = pointMesh::New(mesh);

        pointPatchDist pDist(pMesh, patchSet_, points0());

        // Scaling: 1 up to di then linear down to 0 at do away from patches
        scale_.primitiveFieldRef() =
            min
            (
                max
                (
                    (do_ - pDist.primitiveField())/(do_ - di_),
                    scalar(0)
                ),
                scalar(1)
            );

        // Convert the scale function to a cosine
        scale_.primitiveFieldRef() =
            min
            (
                max
                (
                    0.5
                  - 0.5
                   *cos(scale_.primitiveField()
                   *Foam::constant::mathematical::pi),
                    scalar(0)
                ),
                scalar(1)
            );

        pointConstraints::New(pMesh).constrain(scale_);
        scale_.write();
    }
}