예제 #1
0
int main(int argc, char *argv[])
{
    timeSelector::addOptions();
    #include "addRegionOption.H"
    Foam::argList::addOption
    (
        "dir",
        "word",
        "Direction to remove in TKE. -dir x, or y, or z."
    );
    #include "setRootCase.H"
    #include "createTime.H"
    instantList timeDirs = timeSelector::select0(runTime, args);
    #include "createNamedMesh.H"
    
    if (args.optionFound("dir")==true)
    {
        word dir(args.optionRead<word>("dir"));
        
        forAll(timeDirs, timeI)
        {
            runTime.setTime(timeDirs[timeI], timeI);
            Info<< "Time = " << runTime.timeName() << endl;
            
            
            IOobject UPrime2MeanHeader
            (
                "UPrime2Mean",
                runTime.timeName(),
                mesh,
                IOobject::MUST_READ
            );
            
            volScalarField TKE2D
            (
                IOobject
                (
                    "TKE2D",
                    runTime.timeName(),
                    mesh,
                    IOobject::NO_READ,
                    IOobject::AUTO_WRITE
                ),
                mesh,
                dimensionedScalar
                (
                    "dimTKE2D",
                    pow(dimLength,2)/pow(dimTime,2),
                    0
                ),
                "zeroGradient"
            );
            
            if (UPrime2MeanHeader.headerOk())
            {
                Info<< "    Reading average field UPrime2Mean" << endl;
                volSymmTensorField UPrime2Mean(UPrime2MeanHeader, mesh);         
                
                if (dir=="x")
                {
                    Info << "    Calculating 2D turbulent kinetic energy TKE2D without the " 
                         << dir << "component." << endl;
                    TKE2D = 0.5 * (
//                               UPrime2Mean.component(0)
                              UPrime2Mean.component(3)
                            + UPrime2Mean.component(5)
                            );
                }
                else if (dir=="y")
                {
                    Info << "    Calculating 2D turbulent kinetic energy TKE2D without the " 
                         << dir << "component." << endl;
                    TKE2D = 0.5 * (
                              UPrime2Mean.component(0)
//                             + UPrime2Mean.component(3)
                            + UPrime2Mean.component(5)
                            );
                }
                else if (dir=="z")
                {
                    Info << "    Calculating 2D turbulent kinetic energy TKE2D without the " 
                         << dir << "component." << endl;
                    TKE2D = 0.5 * (
                              UPrime2Mean.component(0)
                            + UPrime2Mean.component(3)
//                             + UPrime2Mean.component(5)
                            );
                }
                else
                {
                    Info << "    dir must be x, y or z" << endl;
                }
            
            TKE2D.write();


            }
            else
            {
                Info << "No UPrime2Mean." << endl;
                return 1;
            }

        } 
// ***********************************************************
// Construct from components for scalarGeneralExchangePhaseChange
scalarGeneralExchange::scalarGeneralExchange
(
    const dictionary& dict,
    cfdemCloud& sm,
    word        dictName
)
:
    forceModel(dict,sm),
    propsDict_(dict.subDict(dictName + "Props")),
    scalarTransportProperties_                  //this is clumsy, but effective
    (
        IOobject
        (
            "scalarTransportProperties",
            sm.mesh().time().constant(),
            sm.mesh(),
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    ),
    generalPropsDict_(scalarTransportProperties_.subDict("generalManualProps")),
    voidfractionFieldName_(propsDict_.lookup("voidfractionFieldName")),             //common names/data
    velFieldName_(propsDict_.lookup("velFieldName")),
    tempFieldName_(propsDict_.lookup("tempFieldName")),                             //temperature names/data
    partTempName_(propsDict_.lookup("partTempName")),
    partHeatFluxName_(propsDict_.lookupOrDefault<word>(      "partHeatFluxName", "none")),
    partHeatTransCoeffName_(propsDict_.lookupOrDefault<word>("partHeatTransCoeffName", "none")),
    partHeatFluidName_(propsDict_.lookupOrDefault<word>(     "partHeatFluidName", "none")),
    partDat_(NULL),
    partDatFlux_(NULL),
    partDatTransCoeff_(NULL),
    partDatFluid_(NULL),
    partDatTmpExpl_(NULL),
    partDatTmpImpl_(NULL),
    validPartFlux_(false),
    validPartTransCoeff_(false),
    validPartFluid_(false),
    haveTemperatureEqn_(false),
    useLiMason_(false),
    useGeneralCorrelation_(false),
    lambda_(readScalar(propsDict_.lookup("lambda"))),
    Prandtl_(readScalar(propsDict_.lookup("Prandtl"))),
    eulerianFieldNames_( generalPropsDict_.lookup("eulerianFields")), 
    partSpeciesNames_(propsDict_.lookup("partSpeciesNames")),                       
    partSpeciesFluxNames_(propsDict_.lookup("partSpeciesFluxNames")),
    partSpeciesTransCoeffNames_(propsDict_.lookup("partSpeciesTransCoeffNames")),
    partSpeciesFluidNames_(propsDict_.lookup("partSpeciesFluidNames")),
    DMolecular_(propsDict_.lookup("DMolecular")),
    partHeatFluxPositionInRegister_(-1),
    partHeatTransCoeffPositionInRegister_(-1),
    partHeatFluidPositionInRegister_(-1),
    maxSource_(1e30),
    scaleDia_(1.)

{
    setForceSubModels(propsDict_);
    setupModel();
    if (probeIt_ && propsDict_.found("suppressProbe"))
        probeIt_=!Switch(propsDict_.lookup("suppressProbe"));
    if(probeIt_)
    {
      forAll(eulerianFieldNames_, fieldIt)
      {
        particleCloud_.probeM().initialize(dictName, dictName + "_" + eulerianFieldNames_[fieldIt] + ".logDat");
        particleCloud_.probeM().vectorFields_.append("Urel");               //first entry must the be the vector to probe
        if(eulerianFieldNames_[fieldIt]==tempFieldName_) //this is the temperature
        {
            particleCloud_.probeM().scalarFields_.append("Rep");            
            particleCloud_.probeM().scalarFields_.append("Nu");                 //other are debug
        }
        else                
            particleCloud_.probeM().scalarFields_.append("Sh"); 
        particleCloud_.probeM().scalarFields_.append("exchangeRate");
        particleCloud_.probeM().writeHeader();
      }
    }
예제 #3
0
bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
(
    const fileName& filename
)
{
    const bool mustTriangulate = this->isTri();
    this->clear();

    IFstream is(filename);
    if (!is.good())
    {
        FatalErrorInFunction
            << "Cannot read file " << filename
            << exit(FatalError);
    }

    // assume that the groups are not intermixed
    bool sorted = true;


    // Construct dummy time so we have something to create an objectRegistry
    // from
    Time dummyTime
    (
        "dummyRoot",
        "dummyCase",
        "system",
        "constant",
        false           // enableFunctionObjects
    );

    // Make dummy object registry
    objectRegistry obr
    (
        IOobject
        (
            "dummy",
            dummyTime,
            IOobject::NO_READ,
            IOobject::NO_WRITE,
            false
        )
    );

    // Read all
    vtkUnstructuredReader reader(obr, is);
    const faceList& faces = reader.faces();

    // Assume all faces in zone0 unless a region field is present
    labelList zones(faces.size(), 0);
    if (reader.cellData().foundObject<scalarIOField>("region"))
    {
        const scalarIOField& region =
            reader.cellData().lookupObject<scalarIOField>
            (
                "region"
            );
        forAll(region, i)
        {
            zones[i] = label(region[i]);
        }
    }
예제 #4
0
void Foam::fileControl::initialVertices
(
    pointField& pts,
    scalarField& sizes,
    triadField& alignments
) const
{
    Info<< "    Reading points from file     : " << pointsFile_ << endl;

    pointIOField pointsTmp
    (
        IOobject
        (
            pointsFile_,
            runTime_.constant(),
            runTime_,
            IOobject::MUST_READ,
            IOobject::NO_WRITE,
            false
        )
    );

    pts.transfer(pointsTmp);

    Info<< "    Reading sizes from file      : " << sizesFile_ << endl;

    scalarIOField sizesTmp
    (
        IOobject
        (
            sizesFile_,
            runTime_.constant(),
            runTime_,
            IOobject::MUST_READ,
            IOobject::NO_WRITE,
            false
        )
    );

    sizes.transfer(sizesTmp);

    Info<< "    Reading alignments from file : " << alignmentsFile_ << endl;

    triadIOField alignmentsTmp
    (
        IOobject
        (
            alignmentsFile_,
            runTime_.constant(),
            runTime_,
            IOobject::MUST_READ,
            IOobject::NO_WRITE,
            false
        )
    );

    alignments.transfer(alignmentsTmp);

    if ((pts.size() != sizes.size()) || (pts.size() != alignments.size()))
    {
        FatalErrorInFunction
            << "Size of list of points, sizes and alignments do not match:"
            << nl
            << "Points size     = " << pts.size() << nl
            << "Sizes size      = " << sizes.size() << nl
            << "Alignments size = " << alignments.size()
            << abort(FatalError);
    }
}
Foam::autoPtr<Foam::dynamicFvMesh> Foam::dynamicFvMesh::New(const IOobject& io)
{
    wordList libNames(1);
    libNames[0]=word("mesquiteMotionSolver");

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

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

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

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

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

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

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

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

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

    return autoPtr<dynamicFvMesh>(cstrIter()(io));
}
예제 #6
0
void Foam::calcTypes::fieldMap2d::preCalc
(
  const argList& args,
  const Time& runTime,
  const fvMesh& mesh
)
{
  
  const word dictName("fieldMap2dDict");
  IOdictionary dict
  (
    IOobject
    (
      dictName,
      runTime.system(),
      mesh,
      IOobject::MUST_READ,
      IOobject::NO_WRITE
    )
  );

  if( !dict.readIfPresent<word>("patchName", patchName) )
  {
    SeriousErrorIn("preCalc")
          << "There is no patchName parameter in fieldMap2dDict dictionary"
          << exit(FatalError);
  }
  
  if( !dict.readIfPresent<word>("geometry", geometry) )
  {
    SeriousErrorIn("preCalc")
          << "There is no geometry parameter in fieldMap2dDict dictionary"
          << exit(FatalError);
  }
  
  point minPoint;
  if( !dict.readIfPresent<point>("minPoint", minPoint) )
  {
    SeriousErrorIn("preCalc")
          << "There is no minPoint parameter in fieldMap2dDict dictionary"
          << exit(FatalError);
  }
  point maxPoint;
  if( !dict.readIfPresent<point>("maxPoint", maxPoint) )
  {
    SeriousErrorIn("preCalc")
          << "There is no maxPoint parameter in fieldMap2dDict dictionary"
          << exit(FatalError);
  }

  int integrationDir;
  if( !dict.readIfPresent<int>("integrationDirection", integrationDir) )
  {
    SeriousErrorIn("preCalc")
          << "There is no integrationDirection parameter "
             "in fieldMap2dDict dictionary"
          << exit(FatalError);
  }
  intDir = integrationDir;
  
  int flowDir;
  if( !dict.readIfPresent<int>("flowDirection", flowDir) )
  {
    SeriousErrorIn("preCalc")
          << "There is no flowDirection parameter "
             "in fieldMap2dDict dictionary"
          << exit(FatalError);
  }
  majDir = flowDir;

  int expectedNumberOfIntersections;
  if
  (
    !dict.readIfPresent<int>
          (
            "expectedNumberOfIntersections", 
            expectedNumberOfIntersections
          ) 
  )
  {
    SeriousErrorIn("preCalc")
          << "There is no expectedNumberOfIntersections parameter "
             "in fieldMap2dDict dictionary"
          << exit(FatalError);
  }
  expNI = expectedNumberOfIntersections;
  
  int numberOfIntegrationPoints;
  if
  (
    !dict.readIfPresent<int>
          (
            "numberOfIntegrationPoints",
            numberOfIntegrationPoints
          ) 
  )
  {
    SeriousErrorIn("preCalc")
          << "There is no numberOfIntegrationPoints parameter "
             "in fieldMap2dDict dictionary"
          << exit(FatalError);
  }
  
  
  #ifdef FOAM_DEV
    const word& processingType = args.additionalArgs()[1];
    const word& Nword = args.additionalArgs()[2];
    const word& Mword = args.additionalArgs()[3];
    const word& Kword = args.additionalArgs()[4];

    N_ = std::atoi( Nword.c_str() );
    M_ = std::atoi( Mword.c_str() );
    Info << "FOAM_DEV true: "<< FOAM_DEV <<nl;
  #else
    const word processingType = args[2];
    N_ = std::atoi( args[3].c_str() );
    M_ = std::atoi( args[4].c_str() );
    Info << "FOAM_DEV false: " <<nl;
  #endif
  processingType_ = const_cast<word&>(processingType);
  latDir = 3 - (intDir + majDir);
  
  Info<<"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"
          <<nl
          <<"Post-processing parameters:"<<nl
          <<"patchName:                 "<< patchName<<nl
          <<"geometry:                  "<< geometry<<nl
          <<"minPoint:                  "<< minPoint<<nl
          <<"maxPoint:                  "<< maxPoint<<nl
          <<"major direction:           "<< majDir<<nl
          <<"lateral direction:         "<< latDir<<nl
          <<"integration direction:     "<< intDir<<nl
          <<"number of intersections:   "<<expNI<<nl
          <<"number of integration points: "<< numberOfIntegrationPoints
          <<endl;
  
  if
  (
    processingType_!="ccAll" && geometry == "concentricCylinders"
  )
  {
    SeriousErrorIn("preCalc")
          << "Concentric cylinders geometry should have proc type ccAll"
          << exit(FatalError);
  }

  N1_ = N_+1;
  M1_ = M_+1;
  K_  = numberOfIntegrationPoints;
  K1_ = numberOfIntegrationPoints+1;
  
  N1M1 = N1_*M1_;

  // need temporary arguments in order to add a 0 time directory
  /*
  argList argsTmp = args;
  argsTmp.setOption("time", "0");
  Foam::Time timeTmp(Foam::Time::controlDictName, argsTmp);
  Foam::instantList timeDirs = Foam::timeSelector::select0(timeTmp, argsTmp);
  timeTmp.setTime(timeDirs[0], 0);
  
  Foam::fvMesh meshTmp
  (
      Foam::IOobject
      (
          Foam::fvMesh::defaultRegion,
          timeTmp.timeName(),
          timeTmp,
          Foam::IOobject::MUST_READ
      )
  );
  if( timeTmp.timeName()!="0" )
  {
    SeriousErrorIn("fieldOperations::getInletAreaT0")
            <<"There is no 0 time directory. Check your decomposition as well!"<<nl
            <<"TimeTmp: "<< timeTmp.timeName()<<nl
            <<exit(FatalError);
  }
  */
  
  //Info << "Calculating the max and min coordinates"<<nl;
  //const pointField &allPoints = meshTmp.points();
  //minPosX = min( allPoints.component(vector::X) );
  //minPosY = min( allPoints.component(vector::Y) );
  //minPosZ = min( allPoints.component(vector::Z) );
  
  if(geometry=="flat")
  {
    minPosMaj = minPoint.component(majDir);
    minPosLat = minPoint.component(latDir);
    minPosInt = minPoint.component(intDir);

    maxPosMaj = maxPoint.component(majDir);
    maxPosLat = maxPoint.component(latDir);
    maxPosInt = maxPoint.component(intDir);

    // z becomes x; x becomes y
    dx = (maxPosMaj - minPosMaj) / static_cast<scalar>(N_);
    dy = (maxPosLat - minPosLat) / static_cast<scalar>(M_);
  }
  else if(geometry=="concentricCylinders")
  {
    minPosMaj = minPoint.component(majDir);
    minPosLat = 0.0;
    minPosInt = 0.0;

    maxPosMaj = maxPoint.component(majDir);
    maxPosLat = constant::mathematical::twoPi;
    maxPosInt = maxPoint.component(intDir);

    // in case of concentric cylinders we go around the circle
    dx = (maxPosMaj - minPosMaj) / static_cast<scalar>(N_);
    dy = (maxPosLat - minPosLat) / static_cast<scalar>(M_);
  }
  else
  {
    FatalError<<"Unknown geometry"<<nl<<exit(FatalError);
  }
  
  
  // calculate the size of the current pattern being not bigger then 10^7
  thisTimeSize = min(N1M1, maxNumProcPoints);
  curNum = 0;
  curEnd = thisTimeSize;
  
  totNumLoop = (N1M1-1) / maxNumProcPoints + 1;
}
예제 #7
0
autoPtr<DMDModel<Type> > 
DMDModel<Type>::New
(
   const fvMesh& mesh
)
{
    // get model name, but do not register the dictionary
    // otherwise it is registered in the database twice
    const word DMDModelName
    (
        IOdictionary
        (
            IOobject
            (
                "DMDProperties",
                mesh.time().constant(),
                mesh,
                IOobject::MUST_READ_IF_MODIFIED,
                IOobject::NO_WRITE,
                false
            )
        ).lookup("DMDModel")
    );

    Info<< "Selecting DMD model " << DMDModelName << endl;

    if (!dictionaryConstructorTablePtr_)
    {
        FatalErrorIn
        (
            "DMDModel::New"
            "("
                "const fvMesh& mesh,"
                "const PtrList<GeometricField<Type, fvPatchField, volMesh> >& fields"
            ")"
        )   << "DMD model table is empty"
            << exit(FatalError);
    }

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

    if (cstrIter == dictionaryConstructorTablePtr_->end())
    {
        FatalErrorIn
        (
            "DMDModel::New"
            "("
                "const fvMesh& mesh,"
                "const PtrList<GeometricField<Type, fvPatchField, volMesh> >& fields"
            ")"
        )   << "Unknown DMDModel type "
            << DMDModelName << nl << nl
            << "Valid DMDModel types:" << endl
            << dictionaryConstructorTablePtr_->sortedToc()
            << exit(FatalError);
    }

    return autoPtr<Foam::DMDModel<Type> >
    (
        cstrIter()(mesh, DMDModelName)
    );
}
Foam::tmp<Foam::surfaceScalarField> Foam::harmonic<Type>::weights
(
    const GeometricField<Type, fvPatchField, volMesh>& phi
) const
{
    // Implement weights-based stabilised harmonic interpolation using
    // magnitude of type
    // Algorithm:
    // 1) calculate magnitude of internal field and neighbour field
    // 2) calculate harmonic mean magnitude
    // 3) express harmonic mean magnitude as: mean = w*mOwn + (1 - w)*mNei
    // 4) Based on above, calculate w = (mean - mNei)/(mOwn - mNei)
    // 5) Use weights to interpolate values

    tmp<surfaceScalarField> tw
    (
        new surfaceScalarField
        (
            IOobject
            (
                "harmonicWeightingFactors" + phi.name(),
                this->mesh().time().timeName(),
                this->mesh()
            ),
            this->mesh() ,
            dimless
        )
    );

    const surfaceScalarField& deltaCoeffs = this->mesh().deltaCoeffs();
    const surfaceScalarField& weights = this->mesh().weights();

    const magLongDelta& mld = magLongDelta::New(this->mesh());
    const surfaceScalarField& longDelta = mld.magDelta();

    surfaceScalarField& w = tw();

    const unallocLabelList& owner = this->mesh().owner();
    const unallocLabelList& neighbour = this->mesh().neighbour();

    scalarField magPhi = mag(phi);

    scalarField& wIn = w.internalField();

    // Larger small for complex arithmetic accuracy
    const scalar kSmall = 1000*SMALL;

    // Calculate internal weights using field magnitude
    forAll (owner, faceI)
    {
        label own = owner[faceI];
        label nei = neighbour[faceI];

        scalar mOwn = magPhi[own]/(1 - weights[faceI]);
        scalar mNei = magPhi[nei]/weights[faceI];

        scalar den = magPhi[nei] - magPhi[own];

        scalar mean = mOwn*mNei/
            ((mOwn + mNei)*longDelta[faceI]*deltaCoeffs[faceI]);

        // Note: complex arithmetic requires extra accuracy
        // This is a division of two close subtractions
        // HJ, 28/Sep/2011
        if (mag(den) > kSmall)
        {
            // Limit weights for round-off safety
            wIn[faceI] =
                Foam::max(0, Foam::min((magPhi[nei] - mean)/den, 1));
        }
        else
        {
            wIn[faceI] = 0.5;
        }
    }
Foam::quadraticFitSnGradData::quadraticFitSnGradData
(
    const fvMesh& mesh,
    const scalar cWeight
)
:
    MeshObject<fvMesh, quadraticFitSnGradData>(mesh),
    centralWeight_(cWeight),
    #ifdef SPHERICAL_GEOMETRY
        dim_(2),
    #else
        dim_(mesh.nGeometricD()),
    #endif
    minSize_
    (
        dim_ == 1 ? 3 :
        dim_ == 2 ? 6 :
        dim_ == 3 ? 9 : 0
    ),
    stencil_(mesh),
    fit_(mesh.nInternalFaces())
{
    if (debug)
    {
        Info<< "Contructing quadraticFitSnGradData" << endl;
    }

    // check input
    if (centralWeight_ < 1 - SMALL)
    {
        FatalErrorIn("quadraticFitSnGradData::quadraticFitSnGradData")
            << "centralWeight requested = " << centralWeight_
            << " should not be less than one"
            << exit(FatalError);
    }

    if (minSize_ == 0)
    {
        FatalErrorIn("quadraticFitSnGradData")
            << " dimension must be 1,2 or 3, not" << dim_ << exit(FatalError);
    }

    // store the polynomial size for each face to write out
    surfaceScalarField snGradPolySize
    (
        IOobject
        (
            "quadraticFitSnGradPolySize",
            "constant",
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        dimensionedScalar("quadraticFitSnGradPolySize", dimless, scalar(0))
    );

    // Get the cell/face centres in stencil order.
    // Centred face stencils no good for triangles of tets. Need bigger stencils
    List<List<point> > stencilPoints(stencil_.stencil().size());
    stencil_.collectData
    (
        mesh.C(),
        stencilPoints
    );

    // find the fit coefficients for every face in the mesh

    for (label faci = 0; faci < mesh.nInternalFaces(); faci++)
    {
        snGradPolySize[faci] = calcFit(stencilPoints[faci], faci);
    }

    if (debug)
    {
        snGradPolySize.write();
        Info<< "quadraticFitSnGradData::quadraticFitSnGradData() :"
            << "Finished constructing polynomialFit data"
            << endl;
    }
}
            );

            // What to do with exposed internal faces if put into this patch?
        }
    }


    // Create the complete field from the pieces
    tmp<GeometricField<Type, fvPatchField, volMesh> > tresF
    (
        new GeometricField<Type, fvPatchField, volMesh>
        (
            IOobject
            (
                "subset"+vf.name(),
                sMesh.time().timeName(),
                sMesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            sMesh,
            vf.dimensions(),
            internalField,
            patchFields
        )
    );

    return tresF;
}


template<class Type>
void Foam::scalarTransportPOD::calcDerivativeCoeffs() const
{
    if (derivativeMatrixPtr_)
    {
        FatalErrorIn
        (
            "void scalarTransportPOD::calcDerivativeCoeffs() const"
        )   << "Derivative matrix already calculated"
            << abort(FatalError);
    }

    // Calculate coefficients for differential equation
    // Get times list
    Time& runTime = const_cast<Time&>(this->mesh().time());

    // Remember time index to restore it
    label origTimeIndex = runTime.timeIndex();

    // Read diffusivity

    IOdictionary transportProperties
    (
        IOobject
        (
            "transportProperties",
            runTime.constant(),
            this->mesh(),
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    );

    Info<< "Reading diffusivity D\n" << endl;

    dimensionedScalar DT
    (
        transportProperties.lookup("DT")
    );

    // Find velocity field

    word Uname(this->dict().lookup("velocity"));

    instantList Times = runTime.times();

    volVectorField* Uptr = NULL;

    forAll (Times, i)
    {
        runTime.setTime(Times[i], i);

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

        IOobject Uheader
        (
            Uname,
            runTime.timeName(),
            this->mesh(),
            IOobject::MUST_READ
        );

        if (Uheader.headerOk())
        {
            Info<< "    Reading " << Uname << endl;

            Uptr = new volVectorField(Uheader, this->mesh());
            break;
        }
        else
        {
            Info<< "    No " << Uname << endl;
        }
    }
Foam::multiSolidBodyMotionFvMesh::multiSolidBodyMotionFvMesh(const IOobject& io)
:
    dynamicFvMesh(io),
    dynamicMeshCoeffs_
    (
        IOdictionary
        (
            IOobject
            (
                "dynamicMeshDict",
                io.time().constant(),
                *this,
                IOobject::MUST_READ_IF_MODIFIED,
                IOobject::NO_WRITE,
                false
            )
        ).subDict(typeName + "Coeffs")
    ),
    undisplacedPoints_
    (
        IOobject
        (
            "points",
            io.time().constant(),
            meshSubDir,
            *this,
            IOobject::MUST_READ,
            IOobject::NO_WRITE,
            false
        )
    )
{
    if (undisplacedPoints_.size() != nPoints())
    {
        FatalIOErrorInFunction
        (
            dynamicMeshCoeffs_
        )   << "Read " << undisplacedPoints_.size()
            << " undisplaced points from " << undisplacedPoints_.objectPath()
            << " but the current mesh has " << nPoints()
            << exit(FatalIOError);
    }


    zoneIDs_.setSize(dynamicMeshCoeffs_.size());
    SBMFs_.setSize(dynamicMeshCoeffs_.size());
    pointIDs_.setSize(dynamicMeshCoeffs_.size());
    label zoneI = 0;

    forAllConstIter(dictionary, dynamicMeshCoeffs_, iter)
    {
        if (iter().isDict())
        {
            zoneIDs_[zoneI] = cellZones().findZoneID(iter().keyword());

            if (zoneIDs_[zoneI] == -1)
            {
                FatalIOErrorInFunction
                (
                    dynamicMeshCoeffs_
                )   << "Cannot find cellZone named " << iter().keyword()
                    << ". Valid zones are " << cellZones().names()
                    << exit(FatalIOError);
            }

            const dictionary& subDict = iter().dict();

            SBMFs_.set
            (
                zoneI,
                solidBodyMotionFunction::New(subDict, io.time())
            );

            // Collect points of cell zone.
            const cellZone& cz = cellZones()[zoneIDs_[zoneI]];

            boolList movePts(nPoints(), false);

            forAll(cz, i)
            {
                label celli = cz[i];
                const cell& c = cells()[celli];
                forAll(c, j)
                {
                    const face& f = faces()[c[j]];
                    forAll(f, k)
                    {
                        label pointi = f[k];
                        movePts[pointi] = true;
                    }
                }
            }
예제 #13
0
    forAll(databases_, proci)
    {
        meshes_.set
        (
            proci,
            new fvMesh
            (
                IOobject
                (
                    meshName_,
                    databases_[proci].timeName(),
                    databases_[proci]
                )
            )
        );

        pointProcAddressing_.set
        (
            proci,
            new labelIOList
            (
                IOobject
                (
                    "pointProcAddressing",
                    meshes_[proci].facesInstance(),
                    meshes_[proci].meshSubDir,
                    meshes_[proci],
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE
                )
            )
        );

        faceProcAddressing_.set
        (
            proci,
            new labelIOList
            (
                IOobject
                (
                    "faceProcAddressing",
                    meshes_[proci].facesInstance(),
                    meshes_[proci].meshSubDir,
                    meshes_[proci],
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE
                )
            )
        );

        cellProcAddressing_.set
        (
            proci,
            new labelIOList
            (
                IOobject
                (
                    "cellProcAddressing",
                    meshes_[proci].facesInstance(),
                    meshes_[proci].meshSubDir,
                    meshes_[proci],
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE
                )
            )
        );

        boundaryProcAddressing_.set
        (
            proci,
            new labelIOList
            (
                IOobject
                (
                    "boundaryProcAddressing",
                    meshes_[proci].facesInstance(),
                    meshes_[proci].meshSubDir,
                    meshes_[proci],
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE
                )
            )
        );
    }
Foam::radiation::radiativeIntensityRay::radiativeIntensityRay
(
    const fvDOM& dom,
    const fvMesh& mesh,
    const scalar phi,
    const scalar theta,
    const scalar deltaPhi,
    const scalar deltaTheta,
    const label nLambda,
    const absorptionEmissionModel& absorptionEmission,
    const blackBodyEmission& blackBody
)
:
    dom_(dom),
    mesh_(mesh),
    absorptionEmission_(absorptionEmission),
    blackBody_(blackBody),
    I_
    (
        IOobject
        (
            "I" + name(rayId),
            mesh_.time().timeName(),
            mesh_,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh_,
        dimensionedScalar("I", dimMass/pow3(dimTime), 0.0)
    ),
    Qr_
    (
        IOobject
        (
            "Qr" + name(rayId),
            mesh_.time().timeName(),
            mesh_,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh_,
        dimensionedScalar("Qr", dimMass/pow3(dimTime), 0.0)
    ),
    d_(vector::zero),
    dAve_(vector::zero),
    theta_(theta),
    phi_(phi),
    omega_(0.0),
    nLambda_(nLambda),
    ILambda_(nLambda)
{
    scalar sinTheta = Foam::sin(theta);
    scalar cosTheta = Foam::cos(theta);
    scalar sinPhi = Foam::sin(phi);
    scalar cosPhi = Foam::cos(phi);

    omega_ = 2.0*sinTheta*Foam::sin(deltaTheta/2.0)*deltaPhi;
    d_ = vector(sinTheta*sinPhi, sinTheta*cosPhi, cosTheta);
    dAve_ = vector
    (
        sinPhi
       *Foam::sin(0.5*deltaPhi)
       *(deltaTheta - Foam::cos(2.0*theta)
       *Foam::sin(deltaTheta)),
        cosPhi
       *Foam::sin(0.5*deltaPhi)
       *(deltaTheta - Foam::cos(2.0*theta)
       *Foam::sin(deltaTheta)),
        0.5*deltaPhi*Foam::sin(2.0*theta)*Foam::sin(deltaTheta)
    );


    autoPtr<volScalarField> IDefaultPtr;

    forAll(ILambda_, lambdaI)
    {
        IOobject IHeader
        (
            intensityPrefix + "_" + name(rayId) + "_" + name(lambdaI),
            mesh_.time().timeName(),
            mesh_,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        );

        // check if field exists and can be read
        if (IHeader.headerOk())
        {
            ILambda_.set
            (
                lambdaI,
                new volScalarField(IHeader, mesh_)
            );
        }
        else
        {
            // Demand driven load the IDefault field
            if (!IDefaultPtr.valid())
            {
                IDefaultPtr.reset
                (
                    new volScalarField
                    (
                        IOobject
                        (
                            "IDefault",
                            mesh_.time().timeName(),
                            mesh_,
                            IOobject::MUST_READ,
                            IOobject::NO_WRITE
                        ),
                        mesh_
                    )
                );
            }

            // Reset the MUST_READ flag
            IOobject noReadHeader(IHeader);
            noReadHeader.readOpt() = IOobject::NO_READ;

            ILambda_.set
            (
                lambdaI,
                new volScalarField(noReadHeader, IDefaultPtr())
            );
        }
    }
multivariateSelectionScheme<Type>::multivariateSelectionScheme
(
    const fvMesh& mesh,
    const typename multivariateSurfaceInterpolationScheme<Type>::
        fieldTable& fields,
    const surfaceScalarField& faceFlux,
    Istream& schemeData
)
:
    multivariateSurfaceInterpolationScheme<Type>
    (
        mesh,
        fields,
        faceFlux,
        schemeData
    ),
    schemes_(schemeData),
    faceFlux_(faceFlux),
    weights_
    (
        IOobject
        (
            "multivariateWeights",
            mesh.time().timeName(),
            mesh
        ),
        mesh,
        dimless
    )
{
    typename multivariateSurfaceInterpolationScheme<Type>::
        fieldTable::const_iterator iter = this->fields().begin();

    surfaceScalarField limiter =
    (
        limitedSurfaceInterpolationScheme<Type>::New
        (
            mesh,
            faceFlux_,
            schemes_.lookup(iter()->name())
        )().limiter(*iter())
    );

    for (++iter; iter != this->fields().end(); ++iter)
    {
        limiter = min
        (
            limiter,
            limitedSurfaceInterpolationScheme<Type>::New
            (
                mesh,
                faceFlux_,
                schemes_.lookup(iter()->name())
            )().limiter(*iter())
        );
    }

    weights_ =
        limiter*mesh.surfaceInterpolation::weights()
      + (scalar(1) - limiter)*upwind<Type>(mesh, faceFlux_).weights();
}
예제 #16
0
Foam::fvSchemes::fvSchemes(const objectRegistry& obr)
:
    IOdictionary
    (
        IOobject
        (
            "fvSchemes",
            obr.time().system(),
            obr,
//             IOobject::MUST_READ,
            IOobject::READ_IF_PRESENT,  // Allow default dictionary creation
            IOobject::NO_WRITE
        )
    ),
    ddtSchemes_
    (
        ITstream
        (
            objectPath() + "::ddtSchemes",
            tokenList()
        )()
    ),
    defaultDdtScheme_
    (
        ddtSchemes_.name() + "::default",
        tokenList()
    ),
    d2dt2Schemes_
    (
        ITstream
        (
            objectPath() + "::d2dt2Schemes",
            tokenList()
        )()
    ),
    defaultD2dt2Scheme_
    (
        d2dt2Schemes_.name() + "::default",
        tokenList()
    ),
    interpolationSchemes_
    (
        ITstream
        (
            objectPath() + "::interpolationSchemes",
            tokenList()
        )()
    ),
    defaultInterpolationScheme_
    (
        interpolationSchemes_.name() + "::default",
        tokenList()
    ),
    divSchemes_
    (
        ITstream
        (
            objectPath() + "::divSchemes",
            tokenList()
        )()
    ),
    defaultDivScheme_
    (
        divSchemes_.name() + "::default",
        tokenList()
    ),
    gradSchemes_
    (
        ITstream
        (
            objectPath() + "::gradSchemes",
            tokenList()
        )()
    ),
    defaultGradScheme_
    (
        gradSchemes_.name() + "::default",
        tokenList()
    ),
    snGradSchemes_
    (
        ITstream
        (
            objectPath() + "::snGradSchemes",
            tokenList()
        )()
    ),
    defaultSnGradScheme_
    (
        snGradSchemes_.name() + "::default",
        tokenList()
    ),
    laplacianSchemes_
    (
        ITstream
        (
            objectPath() + "::laplacianSchemes",
            tokenList()
        )()
    ),
    defaultLaplacianScheme_
    (
        laplacianSchemes_.name() + "::default",
        tokenList()
    ),
    fluxRequired_
    (
        ITstream
        (
            objectPath() + "::fluxRequired",
            tokenList()
        )()
    ),
    defaultFluxRequired_(false),
    cacheFields_
    (
        ITstream
        (
            objectPath() + "::cacheFields",
            tokenList()
        )()
    )
{
    if (!headerOk())
    {
        if (debug)
        {
            InfoIn
            (
                "fvSchemes::fvSchemes(const objectRegistry& obr)"
            )   << "fvSchemes dictionary not found.  Creating default."
                << endl;
        }

        regIOobject::write();
    }

    read();
}
void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
{
    // Initialise
    if (startSampleTime_ == -1 && endSampleTime_ == -1)
    {
        const polyMesh& pMesh = this->patch().boundaryMesh().mesh()();

        // Read the initial point position
        pointField meshPts;

        if (pMesh.pointsInstance() == pMesh.facesInstance())
        {
            meshPts = pointField(pMesh.points(), this->patch().meshPoints());
        }
        else
        {
            // Load points from facesInstance
            if (debug)
            {
                Info<< "Reloading points0 from " << pMesh.facesInstance()
                    << endl;
            }

            pointIOField points0
            (
                IOobject
                (
                    "points",
                    pMesh.facesInstance(),
                    polyMesh::meshSubDir,
                    pMesh,
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE,
                    false
                )
            );
            meshPts = pointField(points0, this->patch().meshPoints());
        }

        pointIOField samplePoints
        (
            IOobject
            (
                "points",
                this->db().time().constant(),
                "boundaryData"/this->patch().name(),
                this->db(),
                IOobject::MUST_READ,
                IOobject::AUTO_WRITE,
                false
            )
        );

        mapperPtr_.reset
        (
            new pointToPointPlanarInterpolation
            (
                samplePoints,
                meshPts,
                perturb_
            )
        );

        // Read the times for which data is available

        const fileName samplePointsFile = samplePoints.filePath();
        const fileName samplePointsDir = samplePointsFile.path();
        sampleTimes_ = Time::findTimes(samplePointsDir);

        if (debug)
        {
            Info<< "timeVaryingMappedFixedValuePointPatchField : In directory "
                << samplePointsDir << " found times "
                << pointToPointPlanarInterpolation::timeNames(sampleTimes_)
                << endl;
        }
    }

    // Find current time in sampleTimes
    label lo = -1;
    label hi = -1;

    bool foundTime = mapperPtr_().findTime
    (
        sampleTimes_,
        startSampleTime_,
        this->db().time().value(),
        lo,
        hi
    );

    if (!foundTime)
    {
        FatalErrorIn
        (
            "timeVaryingMappedFixedValuePointPatchField<Type>::checkTable"
        )   << "Cannot find starting sampling values for current time "
            << this->db().time().value() << nl
            << "Have sampling values for times "
            << pointToPointPlanarInterpolation::timeNames(sampleTimes_) << nl
            << "In directory "
            <<  this->db().time().constant()/"boundaryData"/this->patch().name()
            << "\n    on patch " << this->patch().name()
            << " of field " << fieldTableName_
            << exit(FatalError);
    }


    // Update sampled data fields.

    if (lo != startSampleTime_)
    {
        startSampleTime_ = lo;

        if (startSampleTime_ == endSampleTime_)
        {
            // No need to reread since are end values
            if (debug)
            {
                Pout<< "checkTable : Setting startValues to (already read) "
                    <<   "boundaryData"
                        /this->patch().name()
                        /sampleTimes_[startSampleTime_].name()
                    << endl;
            }
            startSampledValues_ = endSampledValues_;
            startAverage_ = endAverage_;
        }
        else
        {
            if (debug)
            {
                Pout<< "checkTable : Reading startValues from "
                    <<   "boundaryData"
                        /this->patch().name()
                        /sampleTimes_[lo].name()
                    << endl;
            }

            // Reread values and interpolate
            AverageIOField<Type> vals
            (
                IOobject
                (
                    fieldTableName_,
                    this->db().time().constant(),
                    "boundaryData"
                   /this->patch().name()
                   /sampleTimes_[startSampleTime_].name(),
                    this->db(),
                    IOobject::MUST_READ,
                    IOobject::AUTO_WRITE,
                    false
                )
            );

            if (vals.size() != mapperPtr_().sourceSize())
            {
                FatalErrorIn
                (
                    "timeVaryingMappedFixedValuePointPatchField<Type>::"
                    "checkTable()"
                )   << "Number of values (" << vals.size()
                    << ") differs from the number of points ("
                    <<  mapperPtr_().sourceSize()
                    << ") in file " << vals.objectPath() << exit(FatalError);
            }

            startAverage_ = vals.average();
            startSampledValues_ = mapperPtr_().interpolate(vals);
        }
    }

    if (hi != endSampleTime_)
    {
        endSampleTime_ = hi;

        if (endSampleTime_ == -1)
        {
            // endTime no longer valid. Might as well clear endValues.
            if (debug)
            {
                Pout<< "checkTable : Clearing endValues" << endl;
            }
            endSampledValues_.clear();
        }
        else
        {
            if (debug)
            {
                Pout<< "checkTable : Reading endValues from "
                    <<   "boundaryData"
                        /this->patch().name()
                        /sampleTimes_[endSampleTime_].name()
                    << endl;
            }
            // Reread values and interpolate
            AverageIOField<Type> vals
            (
                IOobject
                (
                    fieldTableName_,
                    this->db().time().constant(),
                    "boundaryData"
                   /this->patch().name()
                   /sampleTimes_[endSampleTime_].name(),
                    this->db(),
                    IOobject::MUST_READ,
                    IOobject::AUTO_WRITE,
                    false
                )
            );

            if (vals.size() != mapperPtr_().sourceSize())
            {
                FatalErrorIn
                (
                    "timeVaryingMappedFixedValuePointPatchField<Type>::"
                    "checkTable()"
                )   << "Number of values (" << vals.size()
                    << ") differs from the number of points ("
                    <<  mapperPtr_().sourceSize()
                    << ") in file " << vals.objectPath() << exit(FatalError);
            }

            endAverage_ = vals.average();
            endSampledValues_ = mapperPtr_().interpolate(vals);
        }
    }
}
예제 #18
0
int main(int argc, char *argv[])
{
    timeSelector::addOptions();

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

    instantList timeDirs = timeSelector::select0(runTime, args);

#   include "createMesh.H"

    forAll(timeDirs, timeI)
    {
        runTime.setTime(timeDirs[timeI], timeI);

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

        IOobject pheader
        (
            "p",
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ
        );

        IOobject Uheader
        (
            "U",
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ
        );


        // Check p and U exist
        if (pheader.headerOk() && Uheader.headerOk())
        {
            mesh.readUpdate();

            Info<< "    Reading p" << endl;
            volScalarField p(pheader, mesh);

            Info<< "    Reading U" << endl;
            volVectorField U(Uheader, mesh);

            Info<< "    Calculating ptot" << endl;
            if (p.dimensions() == dimensionSet(0, 2, -2, 0, 0))
            {
                volScalarField ptot
                (
                    IOobject
                    (
                        "ptot",
                        runTime.timeName(),
                        mesh,
                        IOobject::NO_READ
                    ),
                    p + 0.5*magSqr(U)
                );
                ptot.write();
            }
            else
            {
                IOobject rhoheader
                (
                    "rho",
                    runTime.timeName(),
                    mesh,
                    IOobject::MUST_READ
                );

                // Check rho exists
                if (rhoheader.headerOk())
                {
                    Info<< "    Reading rho" << endl;
                    volScalarField rho(rhoheader, mesh);

                    volScalarField ptot
                    (
                        IOobject
                        (
                            "ptot",
                            runTime.timeName(),
                            mesh,
                            IOobject::NO_READ
                        ),
                        p + 0.5*rho*magSqr(U)
                    );
                    ptot.write();
                }
                else
                {
                    Info<< "    No rho" << endl;
                }
            }
        }
        else
        {
            Info<< "    No p or U" << endl;
        }

        Info<< endl;
    }
예제 #19
0
freeSurface::freeSurface
(
    dynamicFvMesh& m,
    const volScalarField& rho,
    volVectorField& Ub,
    volScalarField& Pb,
    const surfaceScalarField& sfPhi
)
:
    IOdictionary
    (
        IOobject
        (
            "freeSurfaceProperties",
            Ub.mesh().time().constant(),
            Ub.mesh(),
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    ),
    mesh_(m),
    rho_(rho),
    U_(Ub),
    p_(Pb),
    phi_(sfPhi),
    curTimeIndex_(Ub.mesh().time().timeIndex()),
    twoFluids_
    (
        this->lookup("twoFluids")
    ),
    normalMotionDir_
    (
        this->lookup("normalMotionDir")
    ),
    motionDir_(0, 0, 0),
    cleanInterface_
    (
        this->lookup("cleanInterface")
    ),
    aPatchID_(-1),
    bPatchID_(-1),
    muFluidA_
    (
        this->lookup("muFluidA")
    ),
    muFluidB_
    (
        this->lookup("muFluidB")
    ),
    rhoFluidA_
    (
        this->lookup("rhoFluidA")
    ),
    rhoFluidB_
    (
        this->lookup("rhoFluidB")
    ),
    g_(this->lookup("g")),
    cleanInterfaceSurfTension_
    (
        this->lookup("surfaceTension")
    ),
    fixedFreeSurfacePatches_
    (
        this->lookup("fixedFreeSurfacePatches")
    ),
    pointNormalsCorrectionPatches_
    (
        this->lookup("pointNormalsCorrectionPatches")
    ),
    nFreeSurfCorr_
    (
        readInt(this->lookup("nFreeSurfaceCorrectors"))
    ),
    smoothing_(false),
    interpolatorABPtr_(NULL),
    interpolatorBAPtr_(NULL),
    controlPointsPtr_(NULL),
    motionPointsMaskPtr_(NULL),
    pointsDisplacementDirPtr_(NULL),
    facesDisplacementDirPtr_(NULL),
    totalDisplacementPtr_(NULL),
    aMeshPtr_(NULL),
    UsPtr_(NULL),
    phisPtr_(NULL),
    surfactConcPtr_(NULL),
    surfaceTensionPtr_(NULL),
    surfactantPtr_(NULL),
    fluidIndicatorPtr_(NULL)
{
    //Read motion direction
    if (!normalMotionDir_)
    {
        motionDir_ = vector(this->lookup("motionDir"));
        motionDir_ /= mag(motionDir_) + SMALL;
    }

    // Set point normal correction patches
    boolList& correction = aMesh().correctPatchPointNormals();

    forAll(pointNormalsCorrectionPatches_, patchI)
    {
        word patchName = pointNormalsCorrectionPatches_[patchI];

        label patchID = aMesh().boundary().findPatchID(patchName);

        if(patchID == -1)
        {
            FatalErrorIn
            (
                "freeSurface::freeSurface(...)"
            )   << "Patch name for point normals correction does not exist"
                << abort(FatalError);
        }

        correction[patchID] = true;
    }
예제 #20
0
    polyIdPairs::polyIdPairs
    (
        const polyMesh& mesh,
        const potential& pot
    )
    :
    coeffVals_(),
    coeffNames_(),
    coeffNumIds_(),
    nIds_(0),
    coeffSize_(0),
    coeffType_("")
    {
        
        IOdictionary potentialDict
        (
            IOobject
            (
                "potentialDict",
             mesh.time().system(),
             mesh,
             IOobject::MUST_READ,
             IOobject::NO_WRITE
            )
        );
       
	//obtain information about pairs from pair subdict inside potentialdict 
        const dictionary& pairDict(potentialDict.subDict("pair"));
	List<word> pairs(pairDict.toc());//generate list of pairs
	nIds_ = pot.siteIdList().size();//obtain size of siteidlist
	label coeffsize = 0; 
        /**
         * traverse throught the list of pairs excluding electrostatic
         * further checking for interactions in pairs to take the total number
         * of species found which essentially provides a size of dynamic array
         * to be formed
         * loop until the first existing of coefficients are found after that
         * the loop is broken and no further traversal is done.
         */
        
        
	for(int i = 0;i<pairs.size();i++){
		if(pairs[i] != "electrostatic")
		{
			word pp = pairDict.subDict(pairs[i]).lookup("pairPotential");
			if(pp!="noInteraction"){
				List<word> coeff(pairDict.subDict(pairs[i]).subDict(pp+"Coeffs").toc());
                                //get the number of coeff's available
				coeffsize = coeff.size();
                                //set the size of coeffnames followed by generating
                                //coeff names into coeffnames array
                                coeffNames_.setSize(coeffsize);
                                coeffVals_.setSize(coeffsize);//set the size of variables
                                coeffNumIds_.setSize(coeffsize);
                                coeffSize_ = coeffsize;
                                coeffType_ = pp;
                                
                                for(int k=0; k<coeffsize;++k){
                                    coeffNames_[k] = coeff[k];
                                    coeffNumIds_[k] = k;
                                }
				break;//break if the first existence of coeff found
			}
		}
			
	}
       
	int c = 0;
	for(;c < coeffsize; ++c)
		coeffVals_[c].setSize(nIds_); 
	for(c = 0; c < coeffsize; ++c)
		for(int b = 0; b < nIds_; b++)
			coeffVals_[c][b].setSize(nIds_);
        
        //make the coeffs zero
        for(c=0;c < coeffsize; ++c){
            for(int i=0; i<nIds_; ++i){
                for(int j=0; j<nIds_; ++j){
                    coeffVals_[c][i][j] = 0;
                }
            }
        }

/*
 * loop over each potential site id list to form pairs of each site id with another
 * essentially two loops a and b will be running on each site id to form pairs.
 * 
 * for each pair created it will be checked with corresponding pairs inside potentialDict
 * if found pairPotential value for that pair will be obtained.
 *
 * if the obtained pair potential is not "noInteraction" then the resultant pairPotential value
 * will be used to form coeff string to determine "*Coeffs" value which could correspond to 
 * 'lennardJonesCoeffs', 'morseCoeffs', '*Coeffs' anything related with pairPotential value for that
 * particular pair.
 *
 * further to read each value for the N species inside the coeffs we will be using coeffsize variable
 * value obtained at the beginning which essentially consists of number of Species inside coeffs, subsequently
 * we will be traversing the loop and will use the list of species name inside coeffsNames_ array
 */
        for(int a=0; a<nIds_; a++)
        {
            word idA = pot.siteIdList()[a];
            for(int b=0; b<nIds_; b++)
            {
                word idB = pot.siteIdList()[b];
		word pname = idA+"-"+idB;
		if(pairDict.found(pname)){
			word pp = pairDict.subDict(pname)
				.lookup("pairPotential");
			if(pp!="noInteraction"){
				const dictionary& coeffs = pairDict
						.subDict(pname)
						.subDict(pp+"Coeffs");
				for(c=0; c<coeffsize; ++c){
					scalar temp = readScalar(coeffs.lookup(coeffNames_[c]));
					coeffVals_[c][a][b] = temp;
					coeffVals_[c][b][a] = temp;
				}//c loop ends
			}//no interaction if ends
		}//first if condition ends
            }//b loop ends
        }//a loop ends
        
    }//end function
Foam::compressibleTwoPhaseMixture::compressibleTwoPhaseMixture
(
    const fvMesh& mesh,
    const dictionary& dict
)
:
    liqPhaseName_(dict.lookupOrDefault<word>("LiqPhaseName", "Liq")),
    gasPhaseName_(dict.lookupOrDefault<word>("GasPhaseName", "Gas")),

    YLiq_
    (
        IOobject
        (
            IOobject::groupName("Y", liqPhaseName_),
            mesh.time().timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        mesh
    ),

    YGas_
    (
        IOobject
        (
            IOobject::groupName("Y", gasPhaseName_),
            mesh.time().timeName(),
            mesh
        ),
        1.0 - YLiq_
    ),

    YbarLiq_
    (
        IOobject
        (
            IOobject::groupName("Ybar", liqPhaseName_),
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh,
        dimensionedScalar("zero", dimless, 0.0)
    ),

    YbarGas_
    (
        IOobject
        (
            IOobject::groupName("Ybar", gasPhaseName_),
            mesh.time().timeName(),
            mesh
        ),
        1.0 - YbarLiq_
    ),
    
    rhoEff_
    (
        IOobject
        (
            "thermo:rho",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh,
        dimDensity
    )
{
    YGas_ = 1.0 - YLiq_;
}
Foam::timeActivatedExplicitSource::timeActivatedExplicitSource
(
    const word& sourceName,
    const fvMesh& mesh
)
:
    dict_
    (
        IOobject
        (
            sourceName + "Properties",
            mesh.time().constant(),
            mesh,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    ),
    mesh_(mesh),
    runTime_(mesh.time()),
    cellSource_(dict_.lookup("cellSource")),
    timeStart_(dimensionedScalar(dict_.lookup("timeStart")).value()),
    duration_(dimensionedScalar(dict_.lookup("duration")).value()),
    onValue_(dict_.lookup("onValue")),
    offValue_(dict_.lookup("offValue")),
    currentValue_(dimensionedScalar("zero", onValue_.dimensions(), 0.0)),
    cellSelector_
    (
        topoSetSource::New
        (
            cellSource_,
            mesh,
            dict_.subDict(cellSource_ + "Coeffs")
        )
    ),
    selectedCellSet_
    (
        mesh,
        "timeActivatedExplicitSourceCellSet",
        mesh.nCells()/10 + 1  // Reasonable size estimate.
    )
{
    // Check dimensions of on/off values are consistent
    if (onValue_.dimensions() != offValue_.dimensions())
    {
        FatalErrorIn
        (
            "Foam::timeActivatedExplicitSource::timeActivatedExplicitSource"
        )<< "Dimensions of on and off values must be equal" << nl
         << "onValue = " << onValue_ << nl
         << "offValue = " << offValue_ << exit(FatalError);
    }

    // Create the cell set
    cellSelector_->applyToSet
    (
        topoSetSource::NEW,
        selectedCellSet_
    );

    // Give some feedback
    Info<< "timeVaryingExplitSource(" << sourceName << ")" << nl
        << "Selected " << returnReduce(selectedCellSet_.size(), sumOp<label>())
        << " cells." << endl;

    // Initialise the value
    update();
}
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type, fvPatchField, volMesh
>
>
fourthGrad<Type>::grad
(
    const GeometricField<Type, fvPatchField, volMesh>& vsf
) const
{
    // The fourth-order gradient is calculated in two passes.  First,
    // the standard least-square gradient is assembled.  Then, the
    // fourth-order correction is added to the second-order accurate
    // gradient to complete the accuracy.

    typedef typename outerProduct<vector, Type>::type GradType;

    const fvMesh& mesh = vsf.mesh();

    // Assemble the second-order least-square gradient
    // Calculate the second-order least-square gradient
    tmp<GeometricField<GradType, fvPatchField, volMesh> > tsecondfGrad
        = leastSquaresGrad<Type>(mesh).grad(vsf);
    const GeometricField<GradType, fvPatchField, volMesh>& secondfGrad =
        tsecondfGrad();

    tmp<GeometricField<GradType, fvPatchField, volMesh> > tfGrad
    (
        new GeometricField<GradType, fvPatchField, volMesh>
        (
            IOobject
            (
                "grad("+vsf.name()+')',
                vsf.instance(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            secondfGrad
        )
    );
    GeometricField<GradType, fvPatchField, volMesh>& fGrad = tfGrad();

    const vectorField& C = mesh.C();

    const surfaceScalarField& lambda = mesh.weights();

    // Get reference to least square vectors
    const leastSquaresVectors& lsv = leastSquaresVectors::New(mesh);
    const surfaceVectorField& ownLs = lsv.pVectors();
    const surfaceVectorField& neiLs = lsv.nVectors();

    // owner/neighbour addressing
    const unallocLabelList& own = mesh.owner();
    const unallocLabelList& nei = mesh.neighbour();

    // Assemble the fourth-order gradient

    // Internal faces
    forAll(own, facei)
    {
        Type dDotGradDelta = 0.5*
                             (
                                 (C[nei[facei]] - C[own[facei]])
                                 & (secondfGrad[nei[facei]] - secondfGrad[own[facei]])
                             );

        fGrad[own[facei]] -= lambda[facei]*ownLs[facei]*dDotGradDelta;
        fGrad[nei[facei]] -= (1.0 - lambda[facei])*neiLs[facei]*dDotGradDelta;
    }
void Foam::fieldAverage::addPrime2MeanField
(
    const label fieldI,
    const wordList& meanFieldList,
    wordList& prime2MeanFieldList
) const
{
    if (faItems_[fieldI].mean() && meanFieldList[fieldI].size())
    {
        typedef GeometricField<Type1, fvPatchField, volMesh> fieldType1;
        typedef GeometricField<Type2, fvPatchField, volMesh> fieldType2;

        const word& fieldName = faItems_[fieldI].fieldName();

        word meanFieldName = fieldName + EXT_PRIME2MEAN;
        if
        (
            (faItems_[fieldI].window() > 0)
         && (faItems_[fieldI].windowName() != "")
        )
        {
            meanFieldName = meanFieldName + "_" + faItems_[fieldI].windowName();
        }

        Info<< "Reading/calculating field " << meanFieldName << nl << endl;

        if (obr_.foundObject<fieldType2>(meanFieldName))
        {
            prime2MeanFieldList[fieldI] = meanFieldName;
        }
        else if (obr_.found(meanFieldName))
        {
            Info<< "Cannot allocate average field " << meanFieldName
                << " since an object with that name already exists."
                << " Disabling averaging." << nl << endl;
            prime2MeanFieldList[fieldI] = word::null;
        }
        else
        {
            const fieldType1& baseField =
                obr_.lookupObject<fieldType1>(fieldName);
            const fieldType1& meanField =
                obr_.lookupObject<fieldType1>(meanFieldList[fieldI]);

            obr_.store
            (
                new fieldType2
                (
                    IOobject
                    (
                        meanFieldName,
                        obr_.time().timeName(),
                        obr_,
                        IOobject::READ_IF_PRESENT,
                        IOobject::NO_WRITE
                    ),
                    sqr(baseField) - sqr(meanField)
                )
            );

            prime2MeanFieldList[fieldI] = meanFieldName;
        }
    }
}
예제 #25
0
int main(int argc, char *argv[])
{
    timeSelector::addOptions();

    #include "addRegionOption.H"

    argList::addBoolOption
    (
        "compressible",
        "calculate compressible y+"
    );

    #include "setRootCase.H"
    #include "createTime.H"
    instantList timeDirs = timeSelector::select0(runTime, args);
    #include "createNamedMesh.H"

    const bool compressible = args.optionFound("compressible");

    forAll(timeDirs, timeI)
    {
        runTime.setTime(timeDirs[timeI], timeI);
        Info<< "Time = " << runTime.timeName() << endl;
        fvMesh::readUpdateState state = mesh.readUpdate();

        // Wall distance
        if (timeI == 0 || state != fvMesh::UNCHANGED)
        {
            Info<< "Calculating wall distance\n" << endl;
            wallDist y(mesh, true);
            Info<< "Writing wall distance to field " << y.name() << nl << endl;
            y.write();
        }

        volScalarField yPlus
        (
            IOobject
            (
                "yPlus",
                runTime.timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            mesh,
            dimensionedScalar("yPlus", dimless, 0.0)
        );

        IOobject UHeader
        (
            "U",
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        );

        if (UHeader.headerOk())
        {
            Info<< "Reading field U\n" << endl;
            volVectorField U(UHeader, mesh);

            if (compressible)
            {
                calcCompressibleYPlus(mesh, runTime, U, yPlus);
            }
            else
            {
                calcIncompressibleYPlus(mesh, runTime, U, yPlus);
            }
        }
        else
        {
            Info<< "    no U field" << endl;
        }

        Info<< "Writing yPlus to field " << yPlus.name() << nl << endl;

        yPlus.write();
    }
// Construct from components
eulerianScalarField::eulerianScalarField
(
    const dictionary&   dict,
    cfdemCloud&         sm,
    word                modelType,
    int                 modelID
)
:
    dict_(dict),
    particleCloud_(sm),
    fieldName_(modelType),
    cpVolumetricFieldName_(dict_.lookupOrDefault<word>("cpVolumetricFieldName", "na")),
    cpVolumetric_(dict_.lookupOrDefault<scalar>("cpVolumetric", 0.0)),
    updateMixtureProperties_(dict_.lookupOrDefault<bool>("updateMixtureProperties", false)),
    rho_(dict_.lookupOrDefault<scalar>("rho"+fieldName_, -1)),
    rhoCarrier_(dict_.lookupOrDefault<scalar>("rhoCarrier", -1)),
    cp_(dict_.lookupOrDefault<scalar>("cp"+fieldName_, -1)),
    cpCarrier_(dict_.lookupOrDefault<scalar>("cpCarrier", -1)),
    m_
    (   IOobject
        (
            fieldName_,
            sm.mesh().time().timeName(),
            sm.mesh(),
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        sm.mesh()
    ),
    mSource_
    (   IOobject
        (
            fieldName_+"Source",
            sm.mesh().time().timeName(),
            sm.mesh(),
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        sm.mesh()
    ),
    mSourceKImpl_
    (   IOobject
        (
            fieldName_+"SourceKImpl",
            sm.mesh().time().timeName(),
            sm.mesh(),
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        0.0*mSource_ /( m_ + dimensionedScalar("dummy", m_.dimensions(), 1e-32) ) //initi with zero
    ),
    fieldType_("undefined")
    #ifndef versionExt32
    ,fvOptions_(sm.mesh())
    #endif
{


    if ( m_.dimensions() == dimensionSet(0, 0, 0, 1, 0) )
    {
        speciesID_ = -1;
        fieldType_ = "temperature";
        Info << "eulerianScalarField:: found a Temperature field! " << endl;
    }
    else
    {
        speciesID_ = modelID;
        fieldType_ = "species";
        Info << "eulerianScalarField:: found a species field, will assign speciesID: " 
             << speciesID_
             << endl;
    }

    #ifndef versionExt32
    fvOptions_.reset(dict.subDict("fvOptions"+fieldName_));
    #endif

    if( (cpVolumetricFieldName_=="na"||!updateMixtureProperties_) && cpVolumetric_<=0.0)
        FatalError <<"You did not specify a cpVolumetricFieldName (or you do not updateMixtureProperties) and also cpVolumetric is zero (or negative)! Either provide the field name, or set cpVolumetric to a reasonable value. \n" 
                   << abort(FatalError);    

    if(speciesID_>-1 && updateMixtureProperties_ && (rho_<=0 || cp_<=0) )
        FatalError <<"You like to update the phase properties, but density and cp of the eulerianScalarField with name '" 
                   << fieldName_
                   <<"' are not specified or zero. \n" 
                   << abort(FatalError);    

    if(speciesID_>-1 && updateMixtureProperties_ && (rhoCarrier_<=0 || cpCarrier_<=0) )
        FatalError <<"You like to update the phase properties, but density and cp of the carrier phase are not specified or zero \n" 
                   << abort(FatalError);    
                   
    //Report options for cp 
    if(fieldType_=="temperature")
    {
        if(cpVolumetric_!=0.0 && cpVolumetricFieldName_!="na")
        FatalError <<"eulerianScalarField:: You have specified 'cpVolumetric' and 'cpVolumetricFieldName' in a dictionary in '/constant'. This might be confusing. Please unset one of these two inputs to avoid confusion. \n" 
                   << abort(FatalError);    

        if(cpVolumetricFieldName_=="na" || !updateMixtureProperties_) //use also if mixture properties are not updated
            Info << "eulerianScalarField:: will use the following FIXED VOLUMETRIC HEAT CAPACITY: " 
                 << cpVolumetric_ << " [J/K/m³]" << endl;
        else
            Info << "eulerianScalarField:: will use the a SPATIALLY-VARAIBLE VOLUMETRIC HEAT CAPACITY with name: " << cpVolumetricFieldName_ << endl;
    }
}
Foam::radiation::fvDOM::fvDOM(const volScalarField& T)
:
    radiationModel(typeName, T),
    G_
    (
        IOobject
        (
            "G",
            mesh_.time().timeName(),
            T.db(),
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh_,
        dimensionedScalar("G", dimMass/pow3(dimTime), 0.0)
    ),
    Qr_
    (
        IOobject
        (
            "Qr",
            mesh_.time().timeName(),
            T.db(),
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh_,
        dimensionedScalar("Qr", dimMass/pow3(dimTime), 0.0)
    ),
    a_
    (
        IOobject
        (
            "a",
            mesh_.time().timeName(),
            T.db(),
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh_,
        dimensionedScalar("a", dimless/dimLength, 0.0)
    ),
    e_
    (
        IOobject
        (
            "e",
            mesh_.time().timeName(),
            T.db(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh_,
        dimensionedScalar("a", dimless/dimLength, 0.0)
    ),
    E_
    (
        IOobject
        (
            "E",
            mesh_.time().timeName(),
            T.db(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        mesh_,
        dimensionedScalar("E", dimMass/dimLength/pow3(dimTime), 0.0)
    ),
    nTheta_(readLabel(coeffs_.lookup("nTheta"))),
    nPhi_(readLabel(coeffs_.lookup("nPhi"))),
    nRay_(0),
    nLambda_(absorptionEmission_->nBands()),
    aLambda_(nLambda_),
    blackBody_(nLambda_, T),
    IRay_(0),
    convergence_(coeffs_.lookupOrDefault<scalar>("convergence", 0.0)),
    maxIter_(coeffs_.lookupOrDefault<label>("maxIter", 50))
{
    if (mesh_.nSolutionD() == 3)    //3D
    {
        nRay_ = 4*nPhi_*nTheta_;
        IRay_.setSize(nRay_);
        scalar deltaPhi = mathematicalConstant::pi/(2.0*nPhi_);
        scalar deltaTheta = mathematicalConstant::pi/nTheta_;
        label i = 0;
        for (label n = 1; n <= nTheta_; n++)
        {
            for (label m = 1; m <= 4*nPhi_; m++)
            {
                scalar thetai = (2.0*n - 1.0)*deltaTheta/2.0;
                scalar phii = (2.0*m - 1.0)*deltaPhi/2.0;
                IRay_.set
                (
                    i,
                    new radiativeIntensityRay
                    (
                        *this,
                        mesh_,
                        phii,
                        thetai,
                        deltaPhi,
                        deltaTheta,
                        nLambda_,
                        absorptionEmission_,
                        blackBody_
                    )
                );
                i++;
            }
        }
    }
    else
    {
        if (mesh_.nSolutionD() == 2)    //2D (X & Y)
        {
            scalar thetai = mathematicalConstant::piByTwo;
            scalar deltaTheta = mathematicalConstant::pi;
            nRay_ = 4*nPhi_;
            IRay_.setSize(nRay_);
            scalar deltaPhi = mathematicalConstant::pi/(2.0*nPhi_);
            label i = 0;
            for (label m = 1; m <= 4*nPhi_; m++)
            {
                scalar phii = (2.0*m - 1.0)*deltaPhi/2.0;
                IRay_.set
                (
                    i,
                    new radiativeIntensityRay
                    (
                        *this,
                        mesh_,
                        phii,
                        thetai,
                        deltaPhi,
                        deltaTheta,
                        nLambda_,
                        absorptionEmission_,
                        blackBody_
                    )
                );
                i++;
            }
        }
        else    //1D (X)
        {
            scalar thetai = mathematicalConstant::piByTwo;
            scalar deltaTheta = mathematicalConstant::pi;
            nRay_ = 2;
            IRay_.setSize(nRay_);
            scalar deltaPhi = mathematicalConstant::pi;
            label i = 0;
            for (label m = 1; m <= 2; m++)
            {
                scalar phii = (2.0*m - 1.0)*deltaPhi/2.0;
                IRay_.set
                (
                    i,
                    new radiativeIntensityRay
                    (
                        *this,
                        mesh_,
                        phii,
                        thetai,
                        deltaPhi,
                        deltaTheta,
                        nLambda_,
                        absorptionEmission_,
                        blackBody_
                    )
                );
                i++;
            }

        }
    }


    // Construct absorption field for each wavelength
    forAll(aLambda_, lambdaI)
    {
        aLambda_.set
        (
            lambdaI,
            new volScalarField
            (
                IOobject
                (
                    "aLambda_" + Foam::name(lambdaI) ,
                    mesh_.time().timeName(),
                    T.db(),
                    IOobject::NO_READ,
                    IOobject::NO_WRITE
                ),
                a_
            )
        );
    }
예제 #28
0
int main(int argc, char *argv[])
{
    #include "setRootCase.H"
    #include "createTime.H"
    #include "createMesh.H"

    IOdictionary mdInitialiseDict
    (
        IOobject
        (
            "mdInitialiseDict",
            runTime.system(),
            runTime,
            IOobject::MUST_READ_IF_MODIFIED,
            IOobject::NO_WRITE,
            false
        )
    );

    IOdictionary idListDict
    (
        IOobject
        (
            "idList",
            mesh.time().constant(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        )
    );

    potential pot(mesh, mdInitialiseDict, idListDict);

    moleculeCloud molecules(mesh, pot, mdInitialiseDict);

    label totalMolecules = molecules.size();

    if (Pstream::parRun())
    {
        reduce(totalMolecules, sumOp<label>());
    }

    Info<< nl << "Total number of molecules added: " << totalMolecules
        << nl << endl;

    IOstream::defaultPrecision(15);

    if (!mesh.write())
    {
        FatalErrorInFunction
            << "Failed writing moleculeCloud."
            << nl << exit(FatalError);
    }

    Info<< nl << "ClockTime = " << runTime.elapsedClockTime() << " s"
        << nl << endl;

    Info<< "\nEnd\n" << endl;

    return 0;
}
Foam::FieldActivatedInjection<CloudType>::FieldActivatedInjection
(
    const dictionary& dict,
    CloudType& owner
)
    :
    InjectionModel<CloudType>(dict, owner, typeName),
    factor_(readScalar(this->coeffDict().lookup("factor"))),
    referenceField_
    (
       owner.db().objectRegistry::lookupObject<volScalarField>
       (
           this->coeffDict().lookup("referenceField")
       )
    ),
    thresholdField_
    (
       owner.db().objectRegistry::lookupObject<volScalarField>
       (
           this->coeffDict().lookup("thresholdField")
       )
    ),
    positionsFile_(this->coeffDict().lookup("positionsFile")),
    positions_
    (
       IOobject
       (
           positionsFile_,
           owner.db().time().constant(),
           owner.mesh(),
           IOobject::MUST_READ,
           IOobject::NO_WRITE
       )
    ),
    injectorCells_(positions_.size()),
    nParcelsPerInjector_
    (
       readLabel(this->coeffDict().lookup("parcelsPerInjector"))
    ),
    nParcelsInjected_(positions_.size(), 0),
    U0_(this->coeffDict().lookup("U0")),
    diameters_(positions_.size()),
    parcelPDF_
    (
       pdfs::pdf::New
       (
           this->coeffDict().subDict("parcelPDF"),
           owner.rndGen()
       )
    )
{
    // Construct parcel diameters - one per injector cell
    forAll(diameters_, i)
    {
        diameters_[i] = parcelPDF_->sample();
    }

    // Determine total volume of particles to inject
    this->volumeTotal_ =
        nParcelsPerInjector_*sum(pow3(diameters_))*mathematicalConstant::pi/6.0;

    // Set/cache the injector cells
    forAll(positions_, i)
    {
        this->findCellAtPosition
        (
            injectorCells_[i],
            positions_[i]
        );
    }
Foam::diameterModels::ADD::ADD
(
    const dictionary& diameterProperties,
    const phaseModel& phase
)
:
    diameterModel(diameterProperties, phase),
    
    d_
    (
        IOobject
        (
            IOobject::groupName("d", phase.name()),
            phase_.U().time().timeName(),
            phase_.U().mesh(),
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        phase_.U().mesh()
    ),
    dMax_
    (
        "dMax",
        dimLength,
        diameterProperties_.lookup("dMax")
    ),
    dMin_
    (
        "dMin",
        dimLength,
        diameterProperties_.lookup("dMin")
    ),
    residualAlpha_
    (
        "residualAlpha",
        dimless,
        diameterProperties_.lookup("residualAlpha")
    ),
    n_
    (
        "n",
        dimless,
        diameterProperties_.lookup("n")
    ),
    m_
    (
        "m",
        dimless,
        diameterProperties_.lookup("m")
    ),
    C1_
    (
        "C1",
        dimless,
        diameterProperties_.lookup("C1")
    ),
    C2_
    (
        "C2",
        dimLength,
        diameterProperties_.lookup("C2")
    ),
    Cb_
    (
        "Cb",
        dimless,
        diameterProperties_.lookup("Cb")
    ),
    Cc_
    (
        "Cc",
        dimless,
        diameterProperties_.lookup("Cc")
    ),
    Cmu_
    (
        "Cmu",
        dimless,
        diameterProperties_.lookup("Cmu")
    ),
    alphaMax_
    (
        "alphaMax",
        dimless,
        diameterProperties_.lookup("alphaMax")
    ),
    Deff_
    (
        IOobject
        (
            "Deff",
            phase_.U().time().timeName(),
            phase_.U().mesh()
        ),
        phase_.U().mesh(),
        dimensionedScalar("zero", dimensionSet(1, -1, -1, 0, 0, 0, 0), 0.0)
    ),
    deq_
    (
        IOobject
        (
            "deq",
            phase_.U().time().timeName(),
            phase_.U().mesh()
        ),
        phase_.U().mesh(),
        dimensionedScalar("zero", dimensionSet(0, 1, 0, 0, 0, 0, 0), 0.0)
    ),
    tauRel_
    (
        IOobject
        (
            "tauRel",
            phase_.U().time().timeName(),
            phase_.U().mesh()
        ),
        phase_.U().mesh(),
        dimensionedScalar("zero", dimensionSet(0, 0, 1, 0, 0, 0, 0), 0.0)
    )
{}