Merge branch 'master' into cvm

Conflicts:
	src/OpenFOAM/meshes/primitiveShapes/plane/plane.C
	src/edgeMesh/Make/options
This commit is contained in:
graham
2010-02-10 15:00:34 +00:00
488 changed files with 21796 additions and 8444 deletions

View File

@ -15,8 +15,7 @@ EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lengine \

View File

@ -1,6 +1,10 @@
regionProperties/regionProperties.C
derivedFvPatchFields/solidWallHeatFluxTemperature/solidWallHeatFluxTemperatureFvPatchScalarField.C
derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.C
fluid/compressibleCourantNo.C
solid/solidRegionDiffNo.C
chtMultiRegionFoam.C

View File

@ -2,11 +2,11 @@ EXE_INC = \
-Ifluid \
-Isolid \
-IregionProperties \
-Iinclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
-I$(LIB_SRC)/turbulenceModels/compressible/RAS/lnInclude
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel
EXE_LIBS = \
-lbasicThermophysicalModels \

View File

@ -37,6 +37,7 @@ Description
#include "fixedGradientFvPatchFields.H"
#include "regionProperties.H"
#include "compressibleCourantNo.H"
#include "solidRegionDiffNo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -56,23 +57,24 @@ int main(int argc, char *argv[])
#include "initContinuityErrs.H"
#include "readTimeControls.H"
#include "readSolidTimeControls.H"
#include "compressibleMultiRegionCourantNo.H"
#include "solidRegionDiffusionNo.H"
#include "setInitialMultiRegionDeltaT.H"
if (fluidRegions.size())
{
#include "compressibleMultiRegionCourantNo.H"
#include "setInitialDeltaT.H"
}
while (runTime.run())
{
#include "readTimeControls.H"
#include "readSolidTimeControls.H"
#include "readPIMPLEControls.H"
if (fluidRegions.size())
{
#include "compressibleMultiRegionCourantNo.H"
#include "setDeltaT.H"
}
#include "compressibleMultiRegionCourantNo.H"
#include "solidRegionDiffusionNo.H"
#include "setMultiRegionDeltaT.H"
runTime++;
@ -117,7 +119,7 @@ int main(int argc, char *argv[])
<< nl << endl;
}
Info<< "End\n" << endl;
Info << "End\n" << endl;
return 0;
}

View File

@ -0,0 +1,382 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "solidWallMixedTemperatureCoupledFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "directMappedPatchBase.H"
#include "regionProperties.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::solidWallMixedTemperatureCoupledFvPatchScalarField::interfaceOwner
(
const polyMesh& nbrRegion
) const
{
const fvMesh& myRegion = patch().boundaryMesh().mesh();
const regionProperties& props =
myRegion.objectRegistry::parent().lookupObject<regionProperties>
(
"regionProperties"
);
label myIndex = findIndex(props.fluidRegionNames(), myRegion.name());
if (myIndex == -1)
{
label i = findIndex(props.solidRegionNames(), myRegion.name());
if (i == -1)
{
FatalErrorIn
(
"solidWallMixedTemperatureCoupledFvPatchScalarField"
"::interfaceOwner(const polyMesh&) const"
) << "Cannot find region " << myRegion.name()
<< " neither in fluids " << props.fluidRegionNames()
<< " nor in solids " << props.solidRegionNames()
<< exit(FatalError);
}
myIndex = props.fluidRegionNames().size() + i;
}
label nbrIndex = findIndex(props.fluidRegionNames(), nbrRegion.name());
if (nbrIndex == -1)
{
label i = findIndex(props.solidRegionNames(), nbrRegion.name());
if (i == -1)
{
FatalErrorIn("coupleManager::interfaceOwner(const polyMesh&) const")
<< "Cannot find region " << nbrRegion.name()
<< " neither in fluids " << props.fluidRegionNames()
<< " nor in solids " << props.solidRegionNames()
<< exit(FatalError);
}
nbrIndex = props.fluidRegionNames().size() + i;
}
return myIndex < nbrIndex;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::solidWallMixedTemperatureCoupledFvPatchScalarField::
solidWallMixedTemperatureCoupledFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
mixedFvPatchScalarField(p, iF),
neighbourFieldName_("undefined-neighbourFieldName"),
KName_("undefined-K")
{
this->refValue() = 0.0;
this->refGrad() = 0.0;
this->valueFraction() = 1.0;
this->fixesValue_ = true;
}
Foam::solidWallMixedTemperatureCoupledFvPatchScalarField::
solidWallMixedTemperatureCoupledFvPatchScalarField
(
const solidWallMixedTemperatureCoupledFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchScalarField(ptf, p, iF, mapper),
neighbourFieldName_(ptf.neighbourFieldName_),
KName_(ptf.KName_),
fixesValue_(ptf.fixesValue_)
{}
Foam::solidWallMixedTemperatureCoupledFvPatchScalarField::
solidWallMixedTemperatureCoupledFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchScalarField(p, iF),
neighbourFieldName_(dict.lookup("neighbourFieldName")),
KName_(dict.lookup("K"))
{
if (!isA<directMappedPatchBase>(this->patch().patch()))
{
FatalErrorIn
(
"solidWallMixedTemperatureCoupledFvPatchScalarField::"
"solidWallMixedTemperatureCoupledFvPatchScalarField\n"
"(\n"
" const fvPatch& p,\n"
" const DimensionedField<scalar, volMesh>& iF,\n"
" const dictionary& dict\n"
")\n"
) << "\n patch type '" << p.type()
<< "' not type '" << directMappedPatchBase::typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << dimensionedInternalField().name()
<< " in file " << dimensionedInternalField().objectPath()
<< exit(FatalError);
}
fvPatchScalarField::operator=(scalarField("value", dict, p.size()));
if (dict.found("refValue"))
{
// Full restart
refValue() = scalarField("refValue", dict, p.size());
refGrad() = scalarField("refGradient", dict, p.size());
valueFraction() = scalarField("valueFraction", dict, p.size());
fixesValue_ = readBool(dict.lookup("fixesValue"));
}
else
{
// Start from user entered data. Assume fixedValue.
refValue() = *this;
refGrad() = 0.0;
valueFraction() = 1.0;
fixesValue_ = true;
}
}
Foam::solidWallMixedTemperatureCoupledFvPatchScalarField::
solidWallMixedTemperatureCoupledFvPatchScalarField
(
const solidWallMixedTemperatureCoupledFvPatchScalarField& wtcsf,
const DimensionedField<scalar, volMesh>& iF
)
:
mixedFvPatchScalarField(wtcsf, iF),
neighbourFieldName_(wtcsf.neighbourFieldName_),
KName_(wtcsf.KName_),
fixesValue_(wtcsf.fixesValue_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::fvPatchScalarField&
Foam::solidWallMixedTemperatureCoupledFvPatchScalarField::K() const
{
return this->patch().lookupPatchField<volScalarField, scalar>(KName_);
}
void Foam::solidWallMixedTemperatureCoupledFvPatchScalarField::updateCoeffs()
{
if (updated())
{
return;
}
// Get the coupling information from the directMappedPatchBase
const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
(
patch().patch()
);
const polyMesh& nbrMesh = mpp.sampleMesh();
// Force recalculation of mapping and schedule
const mapDistribute& distMap = mpp.map();
(void)distMap.schedule();
tmp<scalarField> intFld = patchInternalField();
if (interfaceOwner(nbrMesh))
{
// Note: other side information could be cached - it only needs
// to be updated the first time round the iteration (i.e. when
// switching regions) but unfortunately we don't have this information.
const fvPatch& nbrPatch = refCast<const fvMesh>
(
nbrMesh
).boundary()[mpp.samplePolyPatch().index()];
// Calculate the temperature by harmonic averaging
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const solidWallMixedTemperatureCoupledFvPatchScalarField& nbrField =
refCast<const solidWallMixedTemperatureCoupledFvPatchScalarField>
(
nbrPatch.lookupPatchField<volScalarField, scalar>
(
neighbourFieldName_
)
);
// Swap to obtain full local values of neighbour internal field
scalarField nbrIntFld = nbrField.patchInternalField();
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(), // what to send
distMap.constructMap(), // what to receive
nbrIntFld
);
// Swap to obtain full local values of neighbour K*delta
scalarField nbrKDelta = nbrField.K()*nbrPatch.deltaCoeffs();
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(), // what to send
distMap.constructMap(), // what to receive
nbrKDelta
);
tmp<scalarField> myKDelta = K()*patch().deltaCoeffs();
// Calculate common wall temperature. Reuse *this to store common value.
scalarField Twall
(
(myKDelta()*intFld() + nbrKDelta*nbrIntFld)
/ (myKDelta() + nbrKDelta)
);
// Assign to me
fvPatchScalarField::operator=(Twall);
// Distribute back and assign to neighbour
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
nbrField.size(),
distMap.constructMap(), // reverse : what to send
distMap.subMap(),
Twall
);
const_cast<solidWallMixedTemperatureCoupledFvPatchScalarField&>
(
nbrField
).fvPatchScalarField::operator=(Twall);
}
// Switch between fixed value (of harmonic avg) or gradient
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
label nFixed = 0;
// Like snGrad but bypass switching on refValue/refGrad.
tmp<scalarField> normalGradient = (*this-intFld())*patch().deltaCoeffs();
if (debug)
{
scalar Q = gSum(K()*patch().magSf()*normalGradient());
Info<< "solidWallMixedTemperatureCoupledFvPatchScalarField::"
<< "updateCoeffs() :"
<< " patch:" << patch().name()
<< " heatFlux:" << Q
<< " walltemperature "
<< " min:" << gMin(*this)
<< " max:" << gMax(*this)
<< " avg:" << gAverage(*this)
<< endl;
}
forAll(*this, i)
{
// if outgoing flux use fixed value.
if (normalGradient()[i] < 0.0)
{
this->refValue()[i] = operator[](i);
this->refGrad()[i] = 0.0; // not used by me
this->valueFraction()[i] = 1.0;
nFixed++;
}
else
{
// Fixed gradient. Make sure to have valid refValue (even though
// I am not using it - other boundary conditions might)
this->refValue()[i] = operator[](i);
this->refGrad()[i] = normalGradient()[i];
this->valueFraction()[i] = 0.0;
}
}
reduce(nFixed, sumOp<label>());
fixesValue_ = (nFixed > 0);
if (debug)
{
label nTotSize = returnReduce(this->size(), sumOp<label>());
Info<< "solidWallMixedTemperatureCoupledFvPatchScalarField::"
<< "updateCoeffs() :"
<< " patch:" << patch().name()
<< " out of:" << nTotSize
<< " fixedBC:" << nFixed
<< " gradient:" << nTotSize-nFixed << endl;
}
mixedFvPatchScalarField::updateCoeffs();
}
void Foam::solidWallMixedTemperatureCoupledFvPatchScalarField::write
(
Ostream& os
) const
{
mixedFvPatchScalarField::write(os);
os.writeKeyword("neighbourFieldName")<< neighbourFieldName_
<< token::END_STATEMENT << nl;
os.writeKeyword("K") << KName_ << token::END_STATEMENT << nl;
os.writeKeyword("fixesValue") << fixesValue_ << token::END_STATEMENT << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchScalarField,
solidWallMixedTemperatureCoupledFvPatchScalarField
);
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,193 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
solidWallMixedTemperatureCoupledFvPatchScalarField
Description
Mixed boundary condition for temperature, to be used by the
conjugate heat transfer solver.
If my temperature is T1, neighbour is T2:
T1 > T2: my side becomes fixedValue T2 bc, other side becomes fixedGradient.
Example usage:
myInterfacePatchName
{
type solidWallMixedTemperatureCoupled;
neighbourFieldName T;
K K;
value uniform 300;
}
Needs to be on underlying directMapped(Wall)FvPatch.
Note: runs in parallel with arbitrary decomposition. Uses directMapped
functionality to calculate exchange.
Note: lags interface data so both sides use same data.
- problem: schedule to calculate average would interfere
with standard processor swaps.
- so: updateCoeffs sets both to same Twall. Only need to do
this for last outer iteration but don't have access to this.
SourceFiles
solidWallMixedTemperatureCoupledFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef solidWallMixedTemperatureCoupledFvPatchScalarField_H
#define solidWallMixedTemperatureCoupledFvPatchScalarField_H
#include "fvPatchFields.H"
#include "mixedFvPatchFields.H"
#include "fvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class solidWallMixedTemperatureCoupledFvPatchScalarField Declaration
\*---------------------------------------------------------------------------*/
class solidWallMixedTemperatureCoupledFvPatchScalarField
:
public mixedFvPatchScalarField
{
// Private data
//- Name of field on the neighbour region
const word neighbourFieldName_;
//- Name of thermal conductivity field
const word KName_;
bool fixesValue_;
// Private Member Functions
//- Am I or neighbour owner of interface
bool interfaceOwner(const polyMesh& nbrRegion) const;
public:
//- Runtime type information
TypeName("solidWallMixedTemperatureCoupled");
// Constructors
//- Construct from patch and internal field
solidWallMixedTemperatureCoupledFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
solidWallMixedTemperatureCoupledFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// solidWallMixedTemperatureCoupledFvPatchScalarField onto a new patch
solidWallMixedTemperatureCoupledFvPatchScalarField
(
const solidWallMixedTemperatureCoupledFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new solidWallMixedTemperatureCoupledFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
solidWallMixedTemperatureCoupledFvPatchScalarField
(
const solidWallMixedTemperatureCoupledFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new solidWallMixedTemperatureCoupledFvPatchScalarField
(
*this,
iF
)
);
}
// Member functions
//- Get corresponding K field
const fvPatchScalarField& K() const;
//- Return true if this patch field fixes a value.
// Needed to check if a level has to be specified while solving
// Poissons equations.
virtual bool fixesValue() const
{
return fixesValue_;
}
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -47,10 +47,10 @@ Foam::scalar Foam::compressibleCourantNo
/ fvc::interpolate(rho);
CoNum = max(SfUfbyDelta/mesh.magSf())
.value()*runTime.deltaTValue();
.value()*runTime.deltaT().value();
meanCoNum = (sum(SfUfbyDelta)/sum(mesh.magSf()))
.value()*runTime.deltaTValue();
.value()*runTime.deltaT().value();
}
Info<< "Region: " << mesh.name() << " Courant Number mean: " << meanCoNum

View File

@ -1,15 +1,18 @@
scalar CoNum = -GREAT;
forAll(fluidRegions, regionI)
if (fluidRegions.size())
{
CoNum = max
(
compressibleCourantNo
forAll(fluidRegions, regionI)
{
CoNum = max
(
fluidRegions[regionI],
runTime,
rhoFluid[regionI],
phiFluid[regionI]
),
CoNum
);
compressibleCourantNo
(
fluidRegions[regionI],
runTime,
rhoFluid[regionI],
phiFluid[regionI]
),
CoNum
);
}
}

View File

@ -41,6 +41,24 @@
)
);
Info<< " Adding to KFluid\n" << endl;
KFluid.set
(
i,
new volScalarField
(
IOobject
(
"K",
runTime.timeName(),
fluidRegions[i],
IOobject::NO_READ,
IOobject::NO_WRITE
),
thermoFluid[i].Cp()*thermoFluid[i].alpha()
)
);
Info<< " Adding to UFluid\n" << endl;
UFluid.set
(
@ -111,24 +129,6 @@
).ptr()
);
Info<< " Adding to KFluid\n" << endl;
KFluid.set
(
i,
new volScalarField
(
IOobject
(
"K",
runTime.timeName(),
fluidRegions[i],
IOobject::NO_READ,
IOobject::NO_WRITE
),
thermoFluid[i].Cp()*turbulence[i].alphaEff()
)
);
Info<< " Adding to DpDtFluid\n" << endl;
DpDtFluid.set
(

View File

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Global
setInitialDeltaT
Description
Set the initial timestep for the CHT MultiRegion solver.
\*---------------------------------------------------------------------------*/
if (adjustTimeStep)
{
if ((runTime.timeIndex() == 0) && ((CoNum > SMALL) || (DiNum > SMALL)))
{
if (CoNum == -GREAT)
{
CoNum = SMALL;
}
if (DiNum == -GREAT)
{
DiNum = SMALL;
}
runTime.setDeltaT
(
min
(
min(maxCo/CoNum, maxDi/DiNum)*runTime.deltaT().value(),
maxDeltaT
)
);
Info<< "deltaT = " << runTime.deltaT().value() << endl;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,69 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Global
setMultiRegionDeltaT
Description
Reset the timestep to maintain a constant maximum courant and diffusion
Numbers. Reduction of time-step is immediate, but increase is damped to avoid
unstable oscillations.
\*---------------------------------------------------------------------------*/
if (adjustTimeStep)
{
if (CoNum == -GREAT)
{
CoNum = SMALL;
}
if (DiNum == -GREAT)
{
DiNum = SMALL;
}
scalar maxDeltaTFluid = maxCo/(CoNum + SMALL);
scalar maxDeltaTSolid = maxDi/(DiNum + SMALL);
scalar deltaTFluid =
min
(
min(maxDeltaTFluid, 1.0 + 0.1*maxDeltaTFluid),
1.2
);
runTime.setDeltaT
(
min
(
min(deltaTFluid, maxDeltaTSolid)*runTime.deltaT().value(),
maxDeltaT
)
);
Info<< "deltaT = " << runTime.deltaT().value() << endl;
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -24,68 +24,45 @@ License
\*---------------------------------------------------------------------------*/
#include "calcEntry.H"
#include "dictionary.H"
#include "addToMemberFunctionSelectionTable.H"
#include "regionProperties.H"
#include "ISstream.H"
#include "CocoParserErrors.H"
#include "calcEntryParser.h"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionEntries
{
defineTypeNameAndDebug(calcEntry, 0);
addToMemberFunctionSelectionTable
Foam::regionProperties::regionProperties(const Time& runTime)
:
IOdictionary
(
functionEntry,
calcEntry,
execute,
primitiveEntryIstream
);
IOobject
(
"regionProperties",
runTime.time().constant(),
runTime.db(),
IOobject::MUST_READ,
IOobject::NO_WRITE
)
),
fluidRegionNames_(lookup("fluidRegionNames")),
solidRegionNames_(lookup("solidRegionNames"))
{}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::regionProperties::~regionProperties()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionEntries::calcEntry::execute
(
const dictionary& parentDict,
primitiveEntry& entry,
Istream& is
)
const Foam::List<Foam::word>& Foam::regionProperties::fluidRegionNames() const
{
std::istream& iss = dynamicCast<ISstream>(is).stdStream();
return fluidRegionNames_;
}
// define parser error handler
CocoParserErrors<calcEntryInternal::Errors>
myErrorHandler("calcEntryInternal::Parser");
calcEntryInternal::Scanner scanner(iss);
calcEntryInternal::Parser parser(&scanner, &myErrorHandler);
// Attach dictionary context
parser.dict(parentDict);
// Attach scalar functions
// parser.functions(parentDict);
parser.Parse();
// make a small input list to contain the answer
tokenList tokens(2);
tokens[0] = parser.Result();
tokens[1] = token::END_STATEMENT;
entry.read(parentDict, ITstream("ParserResult", tokens)());
return true;
const Foam::List<Foam::word>& Foam::regionProperties::solidRegionNames() const
{
return solidRegionNames_;
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,67 +23,80 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::functionEntries::calcEntry
regionProperties
Description
This dictionary function entry may or may not do anything particularly
useful - depending upon what is currently being used to test.
Simple class to hold region information for coupled region simulations
SourceFiles
calcEntry.C
regionProperties.C
\*---------------------------------------------------------------------------*/
#ifndef calcEntry_H
#define calcEntry_H
#ifndef regionProperties_H
#define regionProperties_H
#include "functionEntry.H"
#include "IOdictionary.H"
#include "Time.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace functionEntries
{
/*---------------------------------------------------------------------------*\
Class calcEntry Declaration
Class regionProperties Declaration
\*---------------------------------------------------------------------------*/
class calcEntry
class regionProperties
:
public functionEntry
public IOdictionary
{
// Private data
//- List of the fluid region names
List<word> fluidRegionNames_;
//- List of the solid region names
List<word> solidRegionNames_;
// Private Member Functions
//- Disallow default bitwise copy construct
calcEntry(const calcEntry&);
regionProperties(const regionProperties&);
//- Disallow default bitwise assignment
void operator=(const calcEntry&);
void operator=(const regionProperties&);
public:
//- Runtime type information
ClassName("calc");
// Constructors
//- Construct from components
regionProperties(const Time& runTime);
// Destructor
~regionProperties();
// Member Functions
static bool execute
(
const dictionary& parentDict,
primitiveEntry& entry,
Istream& is
);
// Access
//- Return const reference to the list of fluid region names
const List<word>& fluidRegionNames() const;
//- Return const reference to the list of solid region names
const List<word>& solidRegionNames() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionEntries
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,35 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Global
readSolidTimeControls
Description
Read the control parameters used in the solid
\*---------------------------------------------------------------------------*/
scalar maxDi = runTime.controlDict().lookupOrDefault<scalar>("maxDi", 10.0);
// ************************************************************************* //

View File

@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "solidRegionDiffNo.H"
#include "fvc.H"
Foam::scalar Foam::solidRegionDiffNo
(
const fvMesh& mesh,
const Time& runTime,
const volScalarField& Cprho,
const volScalarField& K
)
{
scalar DiNum = 0.0;
scalar meanDiNum = 0.0;
//- Can have fluid domains with 0 cells so do not test.
if (mesh.nInternalFaces())
{
surfaceScalarField KrhoCpbyDelta =
mesh.surfaceInterpolation::deltaCoeffs()
* fvc::interpolate(K)
/ fvc::interpolate(Cprho);
DiNum = max(KrhoCpbyDelta.internalField())*runTime.deltaT().value();
meanDiNum = (average(KrhoCpbyDelta)).value()*runTime.deltaT().value();
}
Info<< "Region: " << mesh.name() << " Diffusion Number mean: " << meanDiNum
<< " max: " << DiNum << endl;
return DiNum;
}
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Calculates and outputs the mean and maximum Diffusion Numbers for the solid
regions
\*---------------------------------------------------------------------------*/
#ifndef solidRegionDiff_H
#define solidRegionDiff_H
#include "fvMesh.H"
namespace Foam
{
scalar solidRegionDiffNo
(
const fvMesh& mesh,
const Time& runTime,
const volScalarField& Cprho,
const volScalarField& K
);
}
#endif
// ************************************************************************* //

View File

@ -0,0 +1,18 @@
scalar DiNum = -GREAT;
if (solidRegions.size())
{
forAll(solidRegions, regionI)
{
DiNum = max
(
solidRegionDiffNo
(
solidRegions[regionI],
runTime,
rhosCps[regionI],
Ks[regionI]
),
DiNum
);
}
}

View File

@ -55,7 +55,7 @@ int main(int argc, char *argv[])
#include "initContinuityErrs.H"
while (runTime.run())
while (runTime.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
@ -81,8 +81,6 @@ int main(int argc, char *argv[])
#include "convergenceCheck.H"
}
runTime++;
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"

View File

@ -40,4 +40,3 @@
// Momentum corrector
U -= fvc::grad(p)/AU;
U.correctBoundaryConditions();

View File

@ -26,8 +26,13 @@ Application
coalChemistryFoam
Description
Transient solver for compressible, turbulent flow with coal and
limestone parcel injections, and combustion.
Transient solver for:
- compressible,
- turbulent flow,
with
- coal and limestone parcel injections,
- energy source, and
- combustion.
\*---------------------------------------------------------------------------*/
@ -38,7 +43,7 @@ Description
#include "CoalCloud.H"
#include "psiChemistryModel.H"
#include "chemistrySolver.H"
#include "timeActivatedExplicitCellSource.H"
#include "timeActivatedExplicitSource.H"
#include "radiationModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -127,10 +127,11 @@
fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p)
);
Info<< "\nConstructing explicit enthalpy cell source" << endl;
timeActivatedExplicitCellSource enthalpySource
Info<< "\nConstructing explicit enthalpy source" << endl;
scalarTimeActivatedExplicitSourceList enthalpySource
(
"enthalpySource",
"energy",
mesh,
h.dimensions()*phi.dimensions()/mesh.V().dimensions()
dimEnergy/dimTime/dimVolume,
"h"
);

View File

@ -7,6 +7,7 @@
==
rho.dimensionedInternalField()*g
+ parcels.SU()
+ momentumSource.Su()
);
pZones.addResistance(UEqn);

View File

@ -28,7 +28,7 @@ tmp<fv::convectionScheme<scalar> > mvConvection
==
parcels.Srho(i)
+ kappa*chemistry.RR(i)().dimensionedInternalField()
+ pointMassSources.Su(i),
+ massSource.Su(i),
mesh.solver("Yi")
);

View File

@ -1,5 +1,5 @@
Info<< "\nConstructing reacting cloud" << endl;
icoPoly8ThermoReactingCloud parcels
icoPoly8ThermoReactingMultiphaseCloud parcels
(
"reactingCloud1",
rho,

View File

@ -0,0 +1,27 @@
Info<< "Creating mass source\n" << endl;
scalarTimeActivatedExplicitSourceList massSource
(
"mass",
mesh,
dimMass/dimTime/dimVolume,
composition.species()
);
Info<< "Creating momentum source\n" << endl;
vectorTimeActivatedExplicitSourceList momentumSource
(
"momentum",
mesh,
dimMass*dimVelocity/dimTime/dimVolume,
"U"
);
Info<< "Creating energy source\n" << endl;
scalarTimeActivatedExplicitSourceList energySource
(
"energy",
mesh,
dimEnergy/dimTime/dimVolume,
"h"
);

View File

@ -1,8 +0,0 @@
Info<< "\nConstructing multi-component mass flow rate point sources" << endl;
timeActivatedExplicitMulticomponentPointSource pointMassSources
(
"pointMassSources",
mesh,
Y,
dimMass/dimVolume/dimTime
);

View File

@ -39,6 +39,7 @@
pWork()
+ parcels.Sh()
+ radiation->Sh(thermo)
+ energySource.Su()
);
thermo.correct();

View File

@ -32,7 +32,7 @@
- fvm::laplacian(rho*rAU, p)
==
parcels.Srho()
+ pointMassSources.Su()
+ massSource.SuTot()
);
if (corr == nCorr-1 && nonOrth == nNonOrthCorr)

View File

@ -27,10 +27,11 @@ Application
Description
Transient PISO solver for compressible, laminar or turbulent flow with
reacting Lagrangian parcels for porous media, including explicit sources
reacting multiphase Lagrangian parcels for porous media, including explicit
sources for mass, momentum and energy
The solver includes:
- reacting parcel cloud
- reacting multiphase parcel cloud
- porous media
- point mass sources
- polynomial based, incompressible thermodynamics (f(T))
@ -43,12 +44,12 @@ Description
#include "fvCFD.H"
#include "hReactionThermo.H"
#include "turbulenceModel.H"
#include "BasicReactingCloud.H"
#include "BasicReactingMultiphaseCloud.H"
#include "rhoChemistryModel.H"
#include "chemistrySolver.H"
#include "radiationModel.H"
#include "porousZones.H"
#include "timeActivatedExplicitMulticomponentPointSource.H"
#include "timeActivatedExplicitSource.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -63,7 +64,7 @@ int main(int argc, char *argv[])
#include "createFields.H"
#include "createRadiationModel.H"
#include "createClouds.H"
#include "createMulticomponentPointSources.H"
#include "createExplicitSources.H"
#include "createPorousZones.H"
#include "initContinuityErrs.H"
#include "readTimeControls.H"

View File

@ -37,7 +37,7 @@ Description
+ fvc::div(phi)
==
parcels.Srho()
+ pointMassSources.Su()
+ massSource.SuTot()
);
rhoEqn.relax();

View File

@ -22,8 +22,7 @@
==
fvc::reconstruct
(
fvc::interpolate(rho)*(g & mesh.Sf())
- fvc::snGrad(p)*mesh.magSf()
(- ghf*fvc::snGrad(rho) - fvc::snGrad(pmh))*mesh.magSf()
)
);
}

View File

@ -1,9 +1,9 @@
Info<< "Reading field p\n" << endl;
volScalarField p
Info<< "Reading field pmh\n" << endl;
volScalarField pmh
(
IOobject
(
"p",
"pmh",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
@ -119,11 +119,6 @@
#include "compressibleCreatePhi.H"
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell(p, mesh.solutionDict().subDict("PISO"), pRefCell, pRefValue);
Info<< "Calculating field mul\n" << endl;
volScalarField mul
(
@ -346,3 +341,48 @@
),
mut + mul
);
Info<< "Calculating field (g.h)f\n" << endl;
volScalarField gh("gh", g & mesh.C());
surfaceScalarField ghf = surfaceScalarField("gh", g & mesh.Cf());
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
pmh + rho*gh
);
label pmhRefCell = 0;
scalar pmhRefValue = 0.0;
setRefCell
(
pmh,
mesh.solutionDict().subDict("PISO"),
pmhRefCell,
pmhRefValue
);
scalar pRefValue = 0.0;
if (pmh.needReference())
{
pRefValue = readScalar
(
mesh.solutionDict().subDict("PISO").lookup("pRefValue")
);
p += dimensionedScalar
(
"p",
p.dimensions(),
pRefValue - getRefCellValue(p, pmhRefCell)
);
}

View File

@ -0,0 +1,52 @@
volScalarField rUA = 1.0/UEqn.A();
surfaceScalarField rUAf
(
"(rho*(1|A(U)))",
fvc::interpolate(rho)*fvc::interpolate(rUA)
);
U = rUA*UEqn.H();
phi =
fvc::interpolate(rho)
*(
(fvc::interpolate(U) & mesh.Sf())
+ fvc::ddtPhiCorr(rUA, rho, U, phi)
);
surfaceScalarField phiU("phiU", phi);
phi -= ghf*fvc::snGrad(rho)*rUAf*mesh.magSf();
for(int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix pmhEqn
(
fvm::laplacian(rUAf, pmh) == fvc::ddt(rho) + fvc::div(phi)
);
pmhEqn.setReference(pmhRefCell, pmhRefValue);
pmhEqn.solve();
if (nonOrth == nNonOrthCorr)
{
phi -= pmhEqn.flux();
}
}
p == pmh + rho*gh;
if (pmh.needReference())
{
p += dimensionedScalar
(
"p",
p.dimensions(),
pRefValue - getRefCellValue(p, pmhRefCell)
);
}
#include "rhoEqn.H"
#include "compressibleContinuityErrs.H"
U += rUA*fvc::reconstruct((phi - phiU)/rUAf);
U.correctBoundaryConditions();

View File

@ -64,22 +64,24 @@ int main(int argc, char *argv[])
#include "rhoEqn.H"
#include "calcVdj.H"
#include "UEqn.H"
#include "alphaEqn.H"
#include "correctViscosity.H"
// --- PISO loop
for (int corr=0; corr<nCorr; corr++)
for (int oCorr=0; oCorr<nOuterCorr; oCorr++)
{
#include "pEqn.H"
}
#include "calcVdj.H"
#include "kEpsilon.H"
#include "UEqn.H"
#include "alphaEqn.H"
#include "correctViscosity.H"
// --- PISO loop
for (int corr=0; corr<nCorr; corr++)
{
#include "pmhEqn.H"
}
#include "kEpsilon.H"
}
runTime.write();

View File

@ -1,15 +0,0 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# this will have to do until we have a makefile rule
if type Coco > /dev/null 2>&1
then
Coco \
-frames $WM_THIRD_PARTY_DIR/coco-r \
calcEntry/calcEntry.atg
else
echo "Coco not installed"
fi
wmake

View File

@ -1,7 +1,3 @@
dictionaryTest.C
calcEntry/calcEntry.C
calcEntry/calcEntryParser.cpp
calcEntry/calcEntryScanner.cpp
EXE = $(FOAM_USER_APPBIN)/dictionaryTest

View File

@ -0,0 +1 @@
EXE_INC =

View File

@ -1,252 +0,0 @@
/*-------------------------------------------------------------------------
compile with:
Coco \
-frames $WM_THIRD_PARTY_DIR/coco-r \
calcEntry.atg
-------------------------------------------------------------------------*/
#include "dictionary.H"
#include "scalar.H"
#include "error.H"
#include "wchar.H"
COMPILER calcEntry
$prefix=calcEntry
$namespace=Foam::functionEntries::calcEntryInternal
$eof=true // grammar handles eof itself
// Simple four function calculator for OpenFOAM dictionaries
//! with debug
static const int debug = 0;
//! The parent dictionary
mutable dictionary* dict_;
//! Track that parent dictionary was set
bool hasDict_;
//! The calculation result
scalar val;
//! token -> scalar
scalar getScalar() const
{
return coco_string_toDouble(t->val);
}
//! token -> string
std::string getString() const
{
char* str = coco_string_create_char(t->val);
std::string s(str);
coco_string_delete(str);
return s;
}
//! attach a dictionary
void dict(const dictionary& dict)
{
dict_ = const_cast<dictionary*>(&dict);
hasDict_ = true;
}
//! lookup dictionary entry
scalar getDictLookup() const
{
scalar dictValue = 0;
if (!hasDict_)
{
FatalErrorIn
(
"calcEntry::getDictEntry() const"
) << "No dictionary attached!"
<< exit(FatalError);
return 0;
}
char* chars = coco_string_create_char
(
t->val,
1,
(coco_string_length(t->val) - 1)
);
word keyword(chars);
coco_string_delete(chars);
if (debug)
{
Info<<"lookup: " << keyword << nl;
}
entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false);
if (entryPtr && !entryPtr->isDict())
{
if (entryPtr->stream().size() != 1)
{
FatalErrorIn
(
"calcEntry::getDictEntry() const"
) << "keyword " << keyword << " has "
<< entryPtr->stream().size() << " values in dictionary "
<< exit(FatalError);
}
entryPtr->stream() >> dictValue;
}
else
{
FatalErrorIn
(
"calcEntry::getDictEntry() const"
) << "keyword " << keyword << " is undefined in dictionary "
<< exit(FatalError);
}
return dictValue;
}
scalar Result() const
{
return val;
}
/*---------------------------------------------------------------------------*/
CHARACTERS
letter = 'A'..'Z' + 'a'..'z'.
qualifier = '_' + ':'.
dollar = '$'.
digit = "0123456789".
sign = '+' + '-'.
cr = '\r'.
lf = '\n'.
tab = '\t'.
stringCh = ANY - '"' - '\\' - cr - lf.
printable = '\u0020' .. '\u007e'.
// * * * * * * * * * * * * * * * * TOKENS * * * * * * * * * * * * * * * * * //
TOKENS
// identifier
ident =
letter { letter | digit | qualifier }.
// string
string =
'"' { stringCh | '\\' printable } '"'.
// dictionary lookup identifier
// starts with '$' and otherwise limited to a normal indentifier
variable =
dollar letter { letter | digit | qualifier }.
// floating point and integer numbers
number =
[sign] ('.' digit { digit } ) | ( digit { digit } [ '.' { digit } ])
[ ('E' | 'e') [sign] digit { digit } ].
// * * * * * * * * * * * PRAGMAS / COMMENTS / IGNORE * * * * * * * * * * * //
COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf
IGNORE cr + lf + tab
// * * * * * * * * * * * * * * * PRODUCTIONS * * * * * * * * * * * * * * * //
PRODUCTIONS
calcEntry (. val = 0;
if (debug){Info<<"start val pos:"<< t->pos << nl;}
.)
=
'{' Expr<val> '}' (.
if (debug){
Info<<"end {} at pos:"<< t->pos
<<" val:"<< t->val
<<" len:"<< coco_string_length(t->val)
<<" la pos:"<< la->pos << nl;
}
// reposition to immediately after the closing '}'
scanner->buffer->SetPos
(
t->pos + coco_string_length(t->val)
);
.)
| ( Expr<val> EOF )
.
/*---------------------------------------------------------------------------*/
Expr<scalar& val> (. scalar val2 = 0;
if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;}
.)
=
Term<val>
{
"+" Term<val2> (. if (debug) {Info<<"+Term:"<<val2 << " pos:"<< t->pos << nl;}
val += val2;
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.)
| "-" Term<val2> (. if (debug) {Info<<"-Term:"<<val2<< " pos:"<< t->pos << nl;}
val -= val2;
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.)
}
.
/*---------------------------------------------------------------------------*/
Term<scalar& val> (. scalar val2 = 0;
if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;}
.)
=
Factor<val>
{
"*" Factor<val2> (. if (debug) {Info<<"*Factor:"<<val2<< " pos:"<< t->pos << nl;}
val *= val2;
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.)
| "/" Factor<val2> (. if (debug) {Info<<"/Factor:"<<val2<< " pos:"<< t->pos << nl;}
val /= val2;
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.)
}
.
/*---------------------------------------------------------------------------*/
Factor<scalar& val>
=
variable (. val = getDictLookup();
if (debug) {Info<<"lookup:"<<val<< " pos:"<< t->pos << nl;}
.)
| number (. val = getScalar();
if (debug) {Info<<"got num:"<<val<< " pos:"<< t->pos << nl;}
.)
| '-' '(' Expr<val> ')' (. val = -val;
if (debug) {Info<<"inv:"<<val<< " pos:"<< t->pos << nl;}
.)
| '(' Expr<val> ')' (. if (debug){Info<<"got Expr:"<<val<< " pos:"<< t->pos << nl;}
.)
.
/*---------------------------------------------------------------------------*/
END calcEntry.
// ************************************************************************* //

View File

@ -1,339 +0,0 @@
#include <wchar.h>
#include "calcEntryParser.h"
namespace Foam {
namespace functionEntries {
namespace calcEntryInternal {
// ----------------------------------------------------------------------------
// Parser Implementation
// ----------------------------------------------------------------------------
void Parser::SynErr(int n) {
if (errDist >= minErrDist) errors->SynErr(la->line, la->col, n);
errDist = 0;
}
void Parser::SemErr(const wchar_t* msg) {
if (errDist >= minErrDist) errors->Error(t->line, t->col, msg);
errDist = 0;
}
void Parser::Get() {
for (;;) {
t = la;
la = scanner->Scan();
if (la->kind <= maxT) {
++errDist;
break;
}
if (dummyToken != t) {
dummyToken->kind = t->kind;
dummyToken->pos = t->pos;
dummyToken->col = t->col;
dummyToken->line = t->line;
dummyToken->next = NULL;
coco_string_delete(dummyToken->val);
dummyToken->val = coco_string_create(t->val);
t = dummyToken;
}
la = t;
}
}
void Parser::Expect(int n) {
if (la->kind == n) {
Get();
}
else {
SynErr(n);
}
}
void Parser::ExpectWeak(int n, int follow) {
if (la->kind == n) {
Get();
}
else {
SynErr(n);
while (!StartOf(follow)) {
Get();
}
}
}
bool Parser::WeakSeparator(int n, int syFol, int repFol) {
if (la->kind == n) {
Get();
return true;
}
else if (StartOf(repFol)) {
return false;
}
else {
SynErr(n);
while (!(StartOf(syFol) || StartOf(repFol) || StartOf(0))) {
Get();
}
return StartOf(syFol);
}
}
void Parser::calcEntry() {
val = 0;
if (debug){Info<<"start val pos:"<< t->pos << nl;}
if (la->kind == 5) {
Get();
Expr(val);
Expect(6);
if (debug){
Info<<"end {} at pos:"<< t->pos
<<" val:"<< t->val
<<" len:"<< coco_string_length(t->val)
<<" la pos:"<< la->pos << nl;
}
// reposition to immediately after the closing '}'
scanner->buffer->SetPos
(
t->pos + coco_string_length(t->val)
);
} else if (StartOf(1)) {
Expr(val);
Expect(0);
} else SynErr(14);
}
void Parser::Expr(scalar& val) {
scalar val2 = 0;
if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;}
Term(val);
while (la->kind == 7 || la->kind == 8) {
if (la->kind == 7) {
Get();
Term(val2);
if (debug) {Info<<"+Term:"<<val2 << " pos:"<< t->pos << nl;}
val += val2;
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
} else {
Get();
Term(val2);
if (debug) {Info<<"-Term:"<<val2<< " pos:"<< t->pos << nl;}
val -= val2;
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
}
}
}
void Parser::Term(scalar& val) {
scalar val2 = 0;
if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;}
Factor(val);
while (la->kind == 9 || la->kind == 10) {
if (la->kind == 9) {
Get();
Factor(val2);
if (debug) {Info<<"*Factor:"<<val2<< " pos:"<< t->pos << nl;}
val *= val2;
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
} else {
Get();
Factor(val2);
if (debug) {Info<<"/Factor:"<<val2<< " pos:"<< t->pos << nl;}
val /= val2;
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
}
}
}
void Parser::Factor(scalar& val) {
if (la->kind == 3) {
Get();
val = getDictLookup();
if (debug) {Info<<"lookup:"<<val<< " pos:"<< t->pos << nl;}
} else if (la->kind == 4) {
Get();
val = getScalar();
if (debug) {Info<<"got num:"<<val<< " pos:"<< t->pos << nl;}
} else if (la->kind == 8) {
Get();
Expect(11);
Expr(val);
Expect(12);
val = -val;
if (debug) {Info<<"inv:"<<val<< " pos:"<< t->pos << nl;}
} else if (la->kind == 11) {
Get();
Expr(val);
Expect(12);
if (debug){Info<<"got Expr:"<<val<< " pos:"<< t->pos << nl;}
} else SynErr(15);
}
void Parser::Parse() {
t = NULL;
if (dummyToken) { // safety: someone might call Parse() twice
delete dummyToken;
}
la = dummyToken = new Token();
la->val = coco_string_create(L"Dummy Token");
Get();
calcEntry();
// let grammar deal with end-of-file expectations
}
Parser::Parser(Scanner* scan, Errors* err)
:
dummyToken(NULL),
deleteErrorsDestruct_(!err),
errDist(minErrDist),
scanner(scan),
errors(err),
t(NULL),
la(NULL)
{
if (!errors) { // add in default error handling
errors = new Errors();
}
}
bool Parser::StartOf(int s) {
const bool T = true;
const bool x = false;
static bool set[2][15] = {
{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x},
{x,x,x,T, T,x,x,x, T,x,x,T, x,x,x}
};
return set[s][la->kind];
}
Parser::~Parser() {
if (deleteErrorsDestruct_) { // delete default error handling
delete errors;
}
delete dummyToken;
}
// ----------------------------------------------------------------------------
// Errors Implementation
// ----------------------------------------------------------------------------
Errors::Errors()
:
count(0)
{}
Errors::~Errors()
{}
void Errors::clear() {
count = 0;
}
wchar_t* Errors::strerror(int n)
{
wchar_t* s;
switch (n) {
case 0: s = coco_string_create(L"EOF expected"); break;
case 1: s = coco_string_create(L"ident expected"); break;
case 2: s = coco_string_create(L"string expected"); break;
case 3: s = coco_string_create(L"variable expected"); break;
case 4: s = coco_string_create(L"number expected"); break;
case 5: s = coco_string_create(L"\"{\" expected"); break;
case 6: s = coco_string_create(L"\"}\" expected"); break;
case 7: s = coco_string_create(L"\"+\" expected"); break;
case 8: s = coco_string_create(L"\"-\" expected"); break;
case 9: s = coco_string_create(L"\"*\" expected"); break;
case 10: s = coco_string_create(L"\"/\" expected"); break;
case 11: s = coco_string_create(L"\"(\" expected"); break;
case 12: s = coco_string_create(L"\")\" expected"); break;
case 13: s = coco_string_create(L"??? expected"); break;
case 14: s = coco_string_create(L"invalid calcEntry"); break;
case 15: s = coco_string_create(L"invalid Factor"); break;
default:
{
wchar_t format[20];
coco_swprintf(format, 20, L"error %d", n);
s = coco_string_create(format);
}
break;
}
return s;
}
void Errors::Warning(const wchar_t* msg) {
wprintf(L"%ls\n", msg);
}
void Errors::Warning(int line, int col, const wchar_t* msg) {
wprintf(L"-- line %d col %d: %ls\n", line, col, msg);
}
void Errors::Error(int line, int col, const wchar_t* msg) {
wprintf(L"-- line %d col %d: %ls\n", line, col, msg);
count++;
}
void Errors::SynErr(int line, int col, int n) {
wchar_t* msg = this->strerror(n);
this->Error(line, col, msg);
coco_string_delete(msg);
}
void Errors::Exception(const wchar_t* msg) {
wprintf(L"%ls", msg);
::exit(1);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // namespace
} // namespace
} // namespace
// ************************************************************************* //

View File

@ -1,206 +0,0 @@
#ifndef COCO_calcEntryPARSER_H__
#define COCO_calcEntryPARSER_H__
#include "dictionary.H"
#include "scalar.H"
#include "error.H"
#include "wchar.H"
#include "calcEntryScanner.h"
namespace Foam {
namespace functionEntries {
namespace calcEntryInternal {
//! Parser error handing
class Errors {
public:
int count; //!< The number of errors detected
//! Allocate and return a string describing the given error code.
/** It is the responsibility of the caller to free this string,
* eg, with coco_string_delete()
*/
static wchar_t* strerror(int n);
Errors(); //!< Construct null - start with no errors
virtual ~Errors(); //!< Destructor
virtual void clear(); //!< Clear the error count
//! Handle a general warning 'msg'
virtual void Warning(const wchar_t* msg);
//! Handle a general warning 'msg'
virtual void Warning(int line, int col, const wchar_t* msg);
//! Handle general error 'msg' (eg, a semantic error)
virtual void Error(int line, int col, const wchar_t* msg);
//! Handle syntax error 'n', uses strerror for the message, calls Error()
virtual void SynErr(int line, int col, int n);
//! Handle a general exception 'msg'
virtual void Exception(const wchar_t* msg);
}; // Errors
//! A Coco/R Parser
class Parser {
private:
enum {
_EOF=0,
_ident=1,
_string=2,
_variable=3,
_number=4,
};
static const int maxT = 13;
static const int minErrDist = 2; //!< min. distance before reporting errors
Token *dummyToken;
bool deleteErrorsDestruct_; //!< delete the 'errors' member in destructor
int errDist;
void SynErr(int n); //!< Handle syntax error 'n'
void Get();
void Expect(int n);
bool StartOf(int s);
void ExpectWeak(int n, int follow);
bool WeakSeparator(int n, int syFol, int repFol);
public:
Scanner *scanner;
Errors *errors;
Token *t; //!< last recognized token
Token *la; //!< lookahead token
static const int debug = 0;
//! The parent dictionary
mutable dictionary* dict_;
//! Track that parent dictionary was set
bool hasDict_;
//! The calculation result
scalar val;
//! token -> scalar
scalar getScalar() const
{
return coco_string_toDouble(t->val);
}
//! token -> string
std::string getString() const
{
char* str = coco_string_create_char(t->val);
std::string s(str);
coco_string_delete(str);
return s;
}
//! attach a dictionary
void dict(const dictionary& dict)
{
dict_ = const_cast<dictionary*>(&dict);
hasDict_ = true;
}
//! lookup dictionary entry
scalar getDictLookup() const
{
scalar dictValue = 0;
if (!hasDict_)
{
FatalErrorIn
(
"calcEntry::getDictEntry() const"
) << "No dictionary attached!"
<< exit(FatalError);
return 0;
}
char* chars = coco_string_create_char
(
t->val,
1,
(coco_string_length(t->val) - 1)
);
word keyword(chars);
coco_string_delete(chars);
if (debug)
{
Info<<"lookup: " << keyword << nl;
}
entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false);
if (entryPtr && !entryPtr->isDict())
{
if (entryPtr->stream().size() != 1)
{
FatalErrorIn
(
"calcEntry::getDictEntry() const"
) << "keyword " << keyword << " has "
<< entryPtr->stream().size() << " values in dictionary "
<< exit(FatalError);
}
entryPtr->stream() >> dictValue;
}
else
{
FatalErrorIn
(
"calcEntry::getDictEntry() const"
) << "keyword " << keyword << " is undefined in dictionary "
<< exit(FatalError);
}
return dictValue;
}
scalar Result() const
{
return val;
}
/*---------------------------------------------------------------------------*/
//! Construct for the specified scanner
/**
* Use the default error handling, or optionally provide an error
* handler, which will not be deleted upon destruction.
*/
Parser(Scanner* scan, Errors* err = 0);
~Parser(); //!< Destructor - cleanup errors and dummyToken
void SemErr(const wchar_t* msg); //!< Handle semantic error
void calcEntry();
void Expr(scalar& val);
void Term(scalar& val);
void Factor(scalar& val);
void Parse(); //!< Execute the parse operation
}; // end Parser
} // namespace
} // namespace
} // namespace
#endif // COCO_calcEntryPARSER_H__

View File

@ -1,932 +0,0 @@
#include <sstream>
#include "calcEntryScanner.h"
// values for the file stream buffering
#define MIN_BUFFER_LENGTH 1024 // 1KB
#define MAX_BUFFER_LENGTH (64*MIN_BUFFER_LENGTH) // 64KB
// value for the heap management
#define HEAP_BLOCK_SIZE (64*1024) // 64KB
namespace Foam {
namespace functionEntries {
namespace calcEntryInternal {
// * * * * * * * * * * Wide Character String Routines * * * * * * * * * * * //
// string handling, wide character
wchar_t* coco_string_create(const wchar_t* str) {
int len = coco_string_length(str);
wchar_t* dest = new wchar_t[len + 1];
if (len) {
wcsncpy(dest, str, len);
}
dest[len] = 0;
return dest;
}
wchar_t* coco_string_create(const wchar_t* str, int index, int length) {
int len = coco_string_length(str);
if (len) {
len = length;
}
wchar_t* dest = new wchar_t[len + 1];
if (len) {
wcsncpy(dest, &(str[index]), len);
}
dest[len] = 0;
return dest;
}
wchar_t* coco_string_create_lower(const wchar_t* str) {
if (!str) { return NULL; }
return coco_string_create_lower(str, 0, wcslen(str));
}
wchar_t* coco_string_create_lower(const wchar_t* str, int index, int len) {
if (!str) { return NULL; }
wchar_t* dest = new wchar_t[len + 1];
for (int i = 0; i < len; i++) {
const wchar_t ch = str[index + i];
if ((L'A' <= ch) && (ch <= L'Z')) {
dest[i] = ch - (L'A' - L'a');
}
else {
dest[i] = ch;
}
}
dest[len] = L'\0';
return dest;
}
wchar_t* coco_string_create_append(const wchar_t* str1, const wchar_t* str2) {
int str1Len = coco_string_length(str1);
int str2Len = coco_string_length(str2);
wchar_t* dest = new wchar_t[str1Len + str2Len + 1];
if (str1Len) { wcscpy(dest, str1); }
if (str2Len) { wcscpy(dest + str1Len, str2); }
dest[str1Len + str2Len] = 0;
return dest;
}
wchar_t* coco_string_create_append(const wchar_t* str1, const wchar_t ch) {
int len = coco_string_length(str1);
wchar_t* dest = new wchar_t[len + 2];
wcsncpy(dest, str1, len); // or use if (len) { wcscpy(dest, str1); }
dest[len] = ch;
dest[len + 1] = 0;
return dest;
}
void coco_string_delete(wchar_t* &str) {
delete [] str;
str = NULL;
}
int coco_string_length(const wchar_t* str) {
return str ? wcslen(str) : 0;
}
bool coco_string_endswith(const wchar_t* str, const wchar_t* endstr) {
int strLen = wcslen(str);
int endLen = wcslen(endstr);
return (endLen <= strLen) && (wcscmp(str + strLen - endLen, endstr) == 0);
}
int coco_string_indexof(const wchar_t* str, const wchar_t ch) {
const wchar_t* fnd = wcschr(str, ch);
return fnd ? (fnd - str) : -1;
}
int coco_string_lastindexof(const wchar_t* str, const wchar_t ch) {
const wchar_t* fnd = wcsrchr(str, ch);
return fnd ? (fnd - str) : -1;
}
void coco_string_merge(wchar_t* &dest, const wchar_t* str) {
if (!str) { return; }
wchar_t* newstr = coco_string_create_append(dest, str);
delete [] dest;
dest = newstr;
}
bool coco_string_equal(const wchar_t* str1, const wchar_t* str2) {
return wcscmp(str1, str2) == 0;
}
int coco_string_compareto(const wchar_t* str1, const wchar_t* str2) {
return wcscmp(str1, str2);
}
int coco_string_hash(const wchar_t* str) {
int h = 0;
if (!str) { return 0; }
while (*str != 0) {
h = (h * 7) ^ *str;
++str;
}
if (h < 0) { h = -h; }
return h;
}
double coco_string_toDouble(const wchar_t* str)
{
return str ? wcstod(str, NULL) : 0;
}
float coco_string_toFloat(const wchar_t* str)
{
return str ? wcstof(str, NULL) : 0;
}
//
// string handling, byte character
//
wchar_t* coco_string_create(const char* str) {
int len = str ? strlen(str) : 0;
wchar_t* dest = new wchar_t[len + 1];
for (int i = 0; i < len; ++i) {
dest[i] = wchar_t(str[i]);
}
dest[len] = 0;
return dest;
}
wchar_t* coco_string_create(const char* str, int index, int length) {
int len = str ? length : 0;
wchar_t* dest = new wchar_t[len + 1];
for (int i = 0; i < len; ++i) {
dest[i] = wchar_t(str[index + i]);
}
dest[len] = 0;
return dest;
}
char* coco_string_create_char(const wchar_t* str) {
int len = coco_string_length(str);
char *dest = new char[len + 1];
for (int i = 0; i < len; ++i)
{
dest[i] = char(str[i]);
}
dest[len] = 0;
return dest;
}
char* coco_string_create_char(const wchar_t* str, int index, int length) {
int len = coco_string_length(str);
if (len) {
len = length;
}
char *dest = new char[len + 1];
for (int i = 0; i < len; ++i) {
dest[i] = char(str[index + i]);
}
dest[len] = 0;
return dest;
}
void coco_string_delete(char* &str) {
delete [] str;
str = NULL;
}
double coco_string_toDouble(const char* str)
{
return str ? strtod(str, NULL) : 0;
}
float coco_string_toFloat(const char* str)
{
return str ? strtof(str, NULL) : 0;
}
// * * * * * * * * * End of Wide Character String Routines * * * * * * * * * //
Token::Token()
:
kind(0),
pos(0),
col(0),
line(0),
val(NULL),
next(NULL)
{}
// Note: this delete may not be correct if the token was actually
// allocated by the internal heap mechanism
Token::~Token() {
coco_string_delete(val);
}
// ----------------------------------------------------------------------------
// Buffer Implementation
// ----------------------------------------------------------------------------
Buffer::Buffer(Buffer* b)
:
buf(b->buf),
bufCapacity(b->bufCapacity),
bufLen(b->bufLen),
bufPos(b->bufPos),
bufStart(b->bufStart),
fileLen(b->fileLen),
cStream(b->cStream),
stdStream(b->stdStream),
isUserStream_(b->isUserStream_)
{
// avoid accidental deletion on any of these members
b->buf = NULL;
b->cStream = NULL;
b->stdStream = NULL;
}
Buffer::Buffer(FILE* istr, bool isUserStream)
:
buf(NULL),
bufCapacity(0),
bufLen(0),
bufPos(0),
bufStart(0),
fileLen(0),
cStream(istr),
stdStream(NULL),
isUserStream_(isUserStream)
{
// ensure binary read on windows
#if _MSC_VER >= 1300
_setmode(_fileno(cStream), _O_BINARY);
#endif
if (CanSeek()) {
fseek(cStream, 0, SEEK_END);
fileLen = ftell(cStream);
fseek(cStream, 0, SEEK_SET);
bufLen = (fileLen < MAX_BUFFER_LENGTH) ? fileLen : MAX_BUFFER_LENGTH;
bufStart = INT_MAX; // nothing in the buffer so far
}
bufCapacity = (bufLen > 0) ? bufLen : MIN_BUFFER_LENGTH;
buf = new unsigned char[bufCapacity];
if (fileLen > 0) SetPos(0); // setup buffer to position 0 (start)
else bufPos = 0; // index 0 is already after the file, thus Pos = 0 is invalid
if (bufLen == fileLen && CanSeek()) Close();
}
Buffer::Buffer(std::istream* istr, bool isUserStream)
:
buf(NULL),
bufCapacity(0),
bufLen(0),
bufPos(0),
bufStart(0),
fileLen(0),
cStream(NULL),
stdStream(istr),
isUserStream_(isUserStream)
{
// ensure binary read on windows
#if _MSC_VER >= 1300
// TODO
#endif
}
Buffer::Buffer(std::string& str)
:
buf(NULL),
bufCapacity(0),
bufLen(0),
bufPos(0),
bufStart(0),
fileLen(0),
cStream(NULL),
stdStream(new std::istringstream(str)),
isUserStream_(false)
{}
Buffer::Buffer(const unsigned char* chars, int len)
:
buf(new unsigned char[len]),
bufCapacity(len),
bufLen(len),
bufPos(0),
bufStart(0),
fileLen(len),
cStream(NULL),
stdStream(NULL),
isUserStream_(false)
{
memcpy(this->buf, chars, len*sizeof(char));
}
Buffer::Buffer(const char* chars, int len)
:
buf(new unsigned char[len]),
bufCapacity(len),
bufLen(len),
bufPos(0),
bufStart(0),
fileLen(len),
cStream(NULL),
stdStream(NULL),
isUserStream_(false)
{
memcpy(this->buf, chars, len*sizeof(char));
}
Buffer::~Buffer() {
Close();
if (buf) {
delete [] buf;
buf = NULL;
}
}
void Buffer::Close() {
if (!isUserStream_) {
if (cStream) {
fclose(cStream);
cStream = NULL;
}
else if (stdStream) {
delete stdStream;
stdStream = 0;
}
}
}
int Buffer::Read() {
if (stdStream)
{
int ch = stdStream->get();
if (stdStream->eof())
{
return EoF;
}
return ch;
}
if (bufPos < bufLen) {
return buf[bufPos++];
} else if (GetPos() < fileLen) {
SetPos(GetPos()); // shift buffer start to Pos
return buf[bufPos++];
} else if (cStream && !CanSeek() && (ReadNextStreamChunk() > 0)) {
return buf[bufPos++];
} else {
return EoF;
}
}
int UTF8Buffer::Read() {
int ch;
do {
ch = Buffer::Read();
// until we find a utf8 start (0xxxxxxx or 11xxxxxx)
} while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EoF));
if (ch < 128 || ch == EoF) {
// nothing to do, first 127 chars are the same in ascii and utf8
// 0xxxxxxx or end of file character
} else if ((ch & 0xF0) == 0xF0) {
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
int c1 = ch & 0x07; ch = Buffer::Read();
int c2 = ch & 0x3F; ch = Buffer::Read();
int c3 = ch & 0x3F; ch = Buffer::Read();
int c4 = ch & 0x3F;
ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
} else if ((ch & 0xE0) == 0xE0) {
// 1110xxxx 10xxxxxx 10xxxxxx
int c1 = ch & 0x0F; ch = Buffer::Read();
int c2 = ch & 0x3F; ch = Buffer::Read();
int c3 = ch & 0x3F;
ch = (((c1 << 6) | c2) << 6) | c3;
} else if ((ch & 0xC0) == 0xC0) {
// 110xxxxx 10xxxxxx
int c1 = ch & 0x1F; ch = Buffer::Read();
int c2 = ch & 0x3F;
ch = (c1 << 6) | c2;
}
return ch;
}
int Buffer::Peek() {
int curPos = GetPos();
int ch = Read();
SetPos(curPos);
return ch;
}
int Buffer::GetPos() const {
if (stdStream)
{
return stdStream->tellg();
}
return bufPos + bufStart;
}
void Buffer::SetPos(int value) {
if (stdStream)
{
stdStream->seekg(value, std::ios::beg);
return;
}
if ((value >= fileLen) && cStream && !CanSeek()) {
// Wanted position is after buffer and the stream
// is not seek-able e.g. network or console,
// thus we have to read the stream manually till
// the wanted position is in sight.
while ((value >= fileLen) && (ReadNextStreamChunk() > 0))
{}
}
if ((value < 0) || (value > fileLen)) {
wprintf(L"--- buffer out of bounds access, position: %d\n", value);
::exit(1);
}
if ((value >= bufStart) && (value < (bufStart + bufLen))) { // already in buffer
bufPos = value - bufStart;
} else if (cStream) { // must be swapped in
fseek(cStream, value, SEEK_SET);
bufLen = fread(buf, sizeof(char), bufCapacity, cStream);
bufStart = value; bufPos = 0;
} else {
bufPos = fileLen - bufStart; // make Pos return fileLen
}
}
// Read the next chunk of bytes from the stream, increases the buffer
// if needed and updates the fields fileLen and bufLen.
// Returns the number of bytes read.
int Buffer::ReadNextStreamChunk() {
int freeLen = bufCapacity - bufLen;
if (freeLen == 0) {
// in the case of a growing input stream
// we can neither seek in the stream, nor can we
// foresee the maximum length, thus we must adapt
// the buffer size on demand.
bufCapacity = bufLen * 2;
unsigned char *newBuf = new unsigned char[bufCapacity];
memcpy(newBuf, buf, bufLen*sizeof(char));
delete [] buf;
buf = newBuf;
freeLen = bufLen;
}
int read = fread(buf + bufLen, sizeof(char), freeLen, cStream);
if (read > 0) {
fileLen = bufLen = (bufLen + read);
return read;
}
// end of stream reached
return 0;
}
bool Buffer::CanSeek() const {
return cStream && (ftell(cStream) != -1);
}
// ----------------------------------------------------------------------------
// Scanner Implementation
// ----------------------------------------------------------------------------
Scanner::Scanner(FILE* istr)
:
buffer(new Buffer(istr, true))
{
Init();
}
Scanner::Scanner(std::istream& istr)
:
buffer(new Buffer(&istr, true))
{
Init();
}
Scanner::Scanner(const wchar_t* fileName) {
char *chFileName = coco_string_create_char(fileName);
FILE* istr;
if ((istr = fopen(chFileName, "rb")) == NULL) {
wprintf(L"--- Cannot open file %ls\n", fileName);
::exit(1);
}
coco_string_delete(chFileName);
buffer = new Buffer(istr, false);
Init();
}
Scanner::Scanner(const unsigned char* buf, int len)
:
buffer(new Buffer(buf, len))
{
Init();
}
Scanner::Scanner(const char* buf, int len)
:
buffer(new Buffer(buf, len))
{
Init();
}
Scanner::~Scanner() {
char* cur = reinterpret_cast<char*>(firstHeap);
while (cur) {
cur = *(reinterpret_cast<char**>(cur + HEAP_BLOCK_SIZE));
free(firstHeap);
firstHeap = cur;
}
delete [] tval;
delete buffer;
}
void Scanner::Init() {
for (int i = 65; i <= 90; ++i) start.set(i, 1);
for (int i = 97; i <= 122; ++i) start.set(i, 1);
for (int i = 36; i <= 36; ++i) start.set(i, 5);
start.set(45, 20);
for (int i = 48; i <= 57; ++i) start.set(i, 9);
start.set(34, 2);
start.set(46, 7);
start.set(123, 14);
start.set(125, 15);
start.set(43, 21);
start.set(42, 16);
start.set(47, 17);
start.set(40, 18);
start.set(41, 19);
start.set(Buffer::EoF, -1);
tvalLength = 128;
tval = new wchar_t[tvalLength]; // text of current token
// HEAP_BLOCK_SIZE byte heap + pointer to next heap block
heap = malloc(HEAP_BLOCK_SIZE + sizeof(void*));
firstHeap = heap;
heapEnd =
reinterpret_cast<void**>
(reinterpret_cast<char*>(heap) + HEAP_BLOCK_SIZE);
*heapEnd = 0;
heapTop = heap;
if (sizeof(Token) > HEAP_BLOCK_SIZE) {
wprintf(L"--- Too small HEAP_BLOCK_SIZE\n");
::exit(1);
}
pos = -1; line = 1; col = 0;
oldEols = 0;
NextCh();
if (ch == 0xEF) { // check optional byte order mark for UTF-8
NextCh(); int ch1 = ch;
NextCh(); int ch2 = ch;
if (ch1 != 0xBB || ch2 != 0xBF) {
wprintf(L"Illegal byte order mark at start of file");
::exit(1);
}
Buffer *oldBuf = buffer;
buffer = new UTF8Buffer(buffer); col = 0;
delete oldBuf; oldBuf = NULL;
NextCh();
}
pt = tokens = CreateToken(); // first token is a dummy
}
void Scanner::NextCh() {
if (oldEols > 0) {
ch = EOL;
oldEols--;
}
else {
pos = buffer->GetPos();
ch = buffer->Read(); col++;
// replace isolated '\r' by '\n' in order to make
// eol handling uniform across Windows, Unix and Mac
if (ch == L'\r' && buffer->Peek() != L'\n') ch = EOL;
if (ch == EOL) { line++; col = 0; }
}
}
void Scanner::AddCh() {
if (tlen >= tvalLength) {
tvalLength *= 2;
wchar_t *newBuf = new wchar_t[tvalLength];
memcpy(newBuf, tval, tlen*sizeof(wchar_t));
delete [] tval;
tval = newBuf;
}
if (ch != Buffer::EoF) {
tval[tlen++] = ch;
NextCh();
}
}
bool Scanner::Comment0() {
int level = 1, pos0 = pos, line0 = line, col0 = col;
NextCh();
if (ch == L'/') {
NextCh();
for(;;) {
if (ch == 10) {
level--;
if (level == 0) { oldEols = line - line0; NextCh(); return true; }
NextCh();
} else if (ch == buffer->EoF) return false;
else NextCh();
}
} else {
buffer->SetPos(pos0); NextCh(); line = line0; col = col0;
}
return false;
}
bool Scanner::Comment1() {
int level = 1, pos0 = pos, line0 = line, col0 = col;
NextCh();
if (ch == L'*') {
NextCh();
for(;;) {
if (ch == L'*') {
NextCh();
if (ch == L'/') {
level--;
if (level == 0) { oldEols = line - line0; NextCh(); return true; }
NextCh();
}
} else if (ch == L'/') {
NextCh();
if (ch == L'*') {
level++; NextCh();
}
} else if (ch == buffer->EoF) return false;
else NextCh();
}
} else {
buffer->SetPos(pos0); NextCh(); line = line0; col = col0;
}
return false;
}
void Scanner::CreateHeapBlock() {
char* cur = reinterpret_cast<char*>(firstHeap);
// release unused blocks
while
(
(reinterpret_cast<char*>(tokens) < cur)
|| (reinterpret_cast<char*>(tokens) > (cur + HEAP_BLOCK_SIZE))
) {
cur = *(reinterpret_cast<char**>(cur + HEAP_BLOCK_SIZE));
free(firstHeap);
firstHeap = cur;
}
// HEAP_BLOCK_SIZE byte heap + pointer to next heap block
void* newHeap = malloc(HEAP_BLOCK_SIZE + sizeof(void*));
*heapEnd = newHeap;
heapEnd =
reinterpret_cast<void**>
(reinterpret_cast<char*>(newHeap) + HEAP_BLOCK_SIZE);
*heapEnd = 0;
heap = newHeap;
heapTop = heap;
}
Token* Scanner::CreateToken() {
const int reqMem = sizeof(Token);
if
(
(reinterpret_cast<char*>(heapTop) + reqMem)
>= reinterpret_cast<char*>(heapEnd)
) {
CreateHeapBlock();
}
// token 'occupies' heap starting at heapTop
Token* tok = reinterpret_cast<Token*>(heapTop);
// increment past this part of the heap, which is now used
heapTop =
reinterpret_cast<void*>
(reinterpret_cast<char*>(heapTop) + reqMem);
tok->val = NULL;
tok->next = NULL;
return tok;
}
void Scanner::AppendVal(Token* tok) {
const int reqMem = (tlen + 1) * sizeof(wchar_t);
if
(
(reinterpret_cast<char*>(heapTop) + reqMem)
>= reinterpret_cast<char*>(heapEnd)
) {
if (reqMem > HEAP_BLOCK_SIZE) {
wprintf(L"--- Too long token value\n");
::exit(1);
}
CreateHeapBlock();
}
// add text value from heap
tok->val = reinterpret_cast<wchar_t*>(heapTop);
// increment past this part of the heap, which is now used
heapTop =
reinterpret_cast<void*>
(reinterpret_cast<char*>(heapTop) + reqMem);
// copy the currently parsed tval into the token
wcsncpy(tok->val, tval, tlen);
tok->val[tlen] = L'\0';
}
Token* Scanner::NextToken() {
while (ch == ' ' ||
(ch >= 9 && ch <= 10) || ch == 13
) NextCh();
if ((ch == L'/' && Comment0()) || (ch == L'/' && Comment1())) return NextToken();
t = CreateToken();
t->pos = pos; t->col = col; t->line = line;
int state = start.state(ch);
tlen = 0; AddCh();
switch (state) {
case -1: { t->kind = eofSym; break; } // NextCh already done
case 0: { t->kind = noSym; break; } // NextCh already done
case 1:
case_1:
if ((ch >= L'0' && ch <= L':') || (ch >= L'A' && ch <= L'Z') || ch == L'_' || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_1;}
else {t->kind = 1; break;}
case 2:
case_2:
if (ch <= 9 || (ch >= 11 && ch <= 12) || (ch >= 14 && ch <= L'!') || (ch >= L'#' && ch <= L'[') || (ch >= L']' && ch <= 65535)) {AddCh(); goto case_2;}
else if (ch == L'"') {AddCh(); goto case_4;}
else if (ch == 92) {AddCh(); goto case_3;}
else {t->kind = noSym; break;}
case 3:
case_3:
if ((ch >= L' ' && ch <= L'~')) {AddCh(); goto case_2;}
else {t->kind = noSym; break;}
case 4:
case_4:
{t->kind = 2; break;}
case 5:
if ((ch >= L'A' && ch <= L'Z') || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_6;}
else {t->kind = noSym; break;}
case 6:
case_6:
if ((ch >= L'0' && ch <= L':') || (ch >= L'A' && ch <= L'Z') || ch == L'_' || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_6;}
else {t->kind = 3; break;}
case 7:
case_7:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_8;}
else {t->kind = noSym; break;}
case 8:
case_8:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_8;}
else {t->kind = 4; break;}
case 9:
case_9:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_9;}
else if (ch == L'E' || ch == L'e') {AddCh(); goto case_10;}
else if (ch == L'.') {AddCh(); goto case_13;}
else {t->kind = 4; break;}
case 10:
case_10:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_12;}
else if (ch == L'+' || ch == L'-') {AddCh(); goto case_11;}
else {t->kind = noSym; break;}
case 11:
case_11:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_12;}
else {t->kind = noSym; break;}
case 12:
case_12:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_12;}
else {t->kind = 4; break;}
case 13:
case_13:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_13;}
else if (ch == L'E' || ch == L'e') {AddCh(); goto case_10;}
else {t->kind = 4; break;}
case 14:
{t->kind = 5; break;}
case 15:
{t->kind = 6; break;}
case 16:
{t->kind = 9; break;}
case 17:
{t->kind = 10; break;}
case 18:
{t->kind = 11; break;}
case 19:
{t->kind = 12; break;}
case 20:
if (ch == L'.') {AddCh(); goto case_7;}
else {t->kind = 8; break;}
case 21:
if (ch == L'.') {AddCh(); goto case_7;}
else {t->kind = 7; break;}
}
AppendVal(t);
return t;
}
// get the next token (possibly a token already seen during peeking)
Token* Scanner::Scan() {
if (tokens->next == NULL) {
return pt = tokens = NextToken();
} else {
pt = tokens = tokens->next;
return tokens;
}
}
// peek for the next token, ignore pragmas
Token* Scanner::Peek() {
do {
if (pt->next == NULL) {
pt->next = NextToken();
}
pt = pt->next;
} while (pt->kind > maxT); // skip pragmas
return pt;
}
// make sure that peeking starts at the current scan position
void Scanner::ResetPeek() {
pt = tokens;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // namespace
} // namespace
} // namespace
// ************************************************************************* //

View File

@ -1,398 +0,0 @@
#ifndef COCO_calcEntrySCANNER_H__
#define COCO_calcEntrySCANNER_H__
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cwchar>
#include <string>
#include <fstream>
#include <iostream>
// io.h and fcntl are used to ensure binary read from streams on windows
#if _MSC_VER >= 1300
#include <io.h>
#include <fcntl.h>
#endif
#if _MSC_VER >= 1400
#define coco_swprintf swprintf_s
#elif _MSC_VER >= 1300
#define coco_swprintf _snwprintf
#else
// assume every other compiler knows swprintf
#define coco_swprintf swprintf
#endif
#define COCO_WCHAR_MAX 65535
namespace Foam {
namespace functionEntries {
namespace calcEntryInternal {
// * * * * * * * * * * Wide Character String Routines * * * * * * * * * * * //
//
// string handling, wide character
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//! Create by copying str
wchar_t* coco_string_create(const wchar_t* str);
//! Create a substring of str starting at index and length characters long
wchar_t* coco_string_create(const wchar_t* str, int index, int length);
//! Create a lowercase string from str
wchar_t* coco_string_create_lower(const wchar_t* str);
//! Create a lowercase substring from str starting at index and length characters long
wchar_t* coco_string_create_lower(const wchar_t* str, int index, int length);
//! Create a string by concatenating str1 and str2
wchar_t* coco_string_create_append(const wchar_t* str1, const wchar_t* str2);
//! Create a string by concatenating a character to the end of str
wchar_t* coco_string_create_append(const wchar_t* str, const wchar_t ch);
//! Free storage and nullify the argument
void coco_string_delete(wchar_t* &str);
//! The length of the str, or 0 if the str is NULL
int coco_string_length(const wchar_t* str);
//! Return true if the str ends with the endstr
bool coco_string_endswith(const wchar_t* str, const wchar_t* endstr);
//! Return the index of the first occurrence of ch.
// Return -1 if nothing is found.
int coco_string_indexof(const wchar_t* str, const wchar_t ch);
//! Return the index of the last occurrence of ch.
// Return -1 if nothing is found.
int coco_string_lastindexof(const wchar_t* str, const wchar_t ch);
//! Append str to dest
void coco_string_merge(wchar_t* &dest, const wchar_t* str);
//! Compare strings, return true if they are equal
bool coco_string_equal(const wchar_t* str1, const wchar_t* str2);
//! Compare strings, return 0 if they are equal
int coco_string_compareto(const wchar_t* str1, const wchar_t* str2);
//! Simple string hashing function
int coco_string_hash(const wchar_t* str);
//
// String conversions
// ~~~~~~~~~~~~~~~~~~
//! Convert wide string to double
double coco_string_toDouble(const wchar_t* str);
//! Convert wide string to float
float coco_string_toFloat(const wchar_t* str);
//
// String handling, byte character
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//! Create by copying byte str
wchar_t* coco_string_create(const char* str);
//! Create a substring of byte str starting at index and length characters long
wchar_t* coco_string_create(const char* str, int index, int length);
//! Create a byte string by copying str
char* coco_string_create_char(const wchar_t* str);
//! Create a byte substring of str starting at index and length characters long
char* coco_string_create_char(const wchar_t* str, int index, int length);
//! Free storage and nullify the argument
void coco_string_delete(char* &str);
//
// String conversions, byte character
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//! Convert byte string to double
double coco_string_toDouble(const char* str);
//! Convert byte string to float
float coco_string_toFloat(const char* str);
// * * * * * * * * * End of Wide Character String Routines * * * * * * * * * //
//! Scanner Token
class Token
{
public:
int kind; //!< token kind
int pos; //!< token position in the source text (starting at 0)
int col; //!< token column (starting at 1)
int line; //!< token line (starting at 1)
wchar_t* val; //!< token value
Token *next; //!< Peek tokens are kept in linked list
Token(); //!< Construct null
~Token(); //!< Destructor - cleanup allocated val??
};
//! Scanner Buffer
//
//! This Buffer supports the following cases:
//! -# seekable stream (file)
//! -# whole stream in buffer
//! -# part of stream in buffer
//! -# non seekable stream (network, console)
class Buffer {
private:
unsigned char *buf; //!< input buffer
int bufCapacity; //!< capacity of buf
int bufLen; //!< length of buffer
int bufPos; //!< current position in buffer
int bufStart; //!< position of first byte in buffer relative to input stream
int fileLen; //!< length of input stream (may change if the stream is no file)
FILE* cStream; //!< input stdio stream (normally seekable)
std::istream* stdStream; //!< STL std stream (seekable)
bool isUserStream_; //!< was the stream opened by the user?
int ReadNextStreamChunk();
bool CanSeek() const; //!< true if stream can be seeked otherwise false
protected:
Buffer(Buffer*); //!< for the UTF8Buffer
public:
static const int EoF = COCO_WCHAR_MAX + 1;
//! Attach buffer to a stdio stream.
//! User streams are not closed in the destructor
Buffer(FILE*, bool isUserStream = true);
//! Attach buffer to an STL std stream
//! User streams are not closed in the destructor
explicit Buffer(std::istream*, bool isUserStream = true);
//! Copy buffer contents from constant string
//! Handled internally as an istringstream
explicit Buffer(std::string&);
//! Copy buffer contents from constant character string
Buffer(const unsigned char* chars, int len);
//! Copy buffer contents from constant character string
Buffer(const char* chars, int len);
//! Close stream (but not user streams) and free buf (if any)
virtual ~Buffer();
virtual void Close(); //!< Close stream (but not user streams)
virtual int Read(); //!< Get character from stream or buffer
virtual int Peek(); //!< Peek character from stream or buffer
virtual int GetPos() const;
virtual void SetPos(int value);
};
//! A Scanner buffer that handles UTF-8 characters
class UTF8Buffer : public Buffer {
public:
UTF8Buffer(Buffer* b) : Buffer(b) {}
virtual int Read();
};
//------------------------------------------------------------------------------
// StartStates
//------------------------------------------------------------------------------
//! maps characters (integers) to start states of tokens
class StartStates {
private:
class Elem {
public:
int key, val;
Elem *next;
Elem(int k, int v) :
key(k), val(v), next(0)
{}
};
Elem **tab;
public:
StartStates() :
tab(new Elem*[128])
{
memset(tab, 0, 128 * sizeof(Elem*));
}
virtual ~StartStates() {
for (int i = 0; i < 128; ++i) {
Elem *e = tab[i];
while (e) {
Elem *next = e->next;
delete e;
e = next;
}
}
delete [] tab;
}
void set(int key, int val) {
Elem *e = new Elem(key, val);
int k = unsigned(key) % 128;
e->next = tab[k];
tab[k] = e;
}
int state(int key) {
Elem *e = tab[unsigned(key) % 128];
while (e && e->key != key) e = e->next;
return e ? e->val : 0;
}
};
//------------------------------------------------------------------------------
// KeywordMap
//------------------------------------------------------------------------------
//! maps strings to integers (identifiers to keyword kinds)
class KeywordMap {
private:
class Elem {
public:
wchar_t *key;
int val;
Elem *next;
Elem(const wchar_t *k, int v) :
key(coco_string_create(k)), val(v), next(0)
{}
virtual ~Elem() {
coco_string_delete(key);
}
};
Elem **tab;
public:
KeywordMap() :
tab(new Elem*[128])
{
memset(tab, 0, 128 * sizeof(Elem*));
}
virtual ~KeywordMap() {
for (int i = 0; i < 128; ++i) {
Elem *e = tab[i];
while (e) {
Elem *next = e->next;
delete e;
e = next;
}
}
delete [] tab;
}
void set(const wchar_t *key, int val) {
Elem *e = new Elem(key, val);
const int k = coco_string_hash(key) % 128;
e->next = tab[k];
tab[k] = e;
}
int get(const wchar_t *key, int defaultVal) {
Elem *e = tab[coco_string_hash(key) % 128];
while (e && !coco_string_equal(e->key, key)) e = e->next;
return e ? e->val : defaultVal;
}
};
//! A Coco/R Scanner
class Scanner {
private:
static const int maxT = 13;
static const int noSym = 13;
static const int eofSym = 0; //!< end-of-file token id
static const char EOL = '\n'; //!< end-of-line character
void *firstHeap; //!< the start of the heap management
void *heap; //!< the currently active block
void *heapTop; //!< the top of the heap
void **heapEnd; //!< the end of the last heap block
StartStates start; //!< A map of start states for particular characters
KeywordMap keywords; //!< A hash of keyword literals to token kind
Token *t; //!< current token
wchar_t *tval; //!< text of current token
int tvalLength; //!< maximum capacity (length) for tval
int tlen; //!< length of tval
Token *tokens; //!< list of tokens already peeked (first token is a dummy)
Token *pt; //!< current peek token
int ch; //!< current input character
int pos; //!< byte position of current character
int line; //!< line number of current character
int col; //!< column number of current character
int oldEols; //!< the number of EOLs that appeared in a comment
void CreateHeapBlock(); //!< add a heap block, freeing unused ones
Token* CreateToken(); //!< fit token on the heap
void AppendVal(Token* tok); //!< adjust tok->val to point to the heap and copy tval into it
void Init(); //!< complete the initialization for the constructors
void NextCh(); //!< get the next input character into ch
void AddCh(); //!< append the character ch to tval
bool Comment0();
bool Comment1();
Token* NextToken(); //!< get the next token
public:
//! The scanner buffer
Buffer *buffer;
//! Using an existing open file handle for the scanner
Scanner(FILE*);
//! Using an existing open STL std stream
explicit Scanner(std::istream&);
//! Open a file for reading and attach scanner
explicit Scanner(const wchar_t* fileName);
//! Attach scanner to an existing character buffer
Scanner(const unsigned char* chars, int len);
//! Attach scanner to an existing character buffer
Scanner(const char* chars, int len);
~Scanner(); //!< free heap and allocated memory
Token* Scan(); //!< get the next token (possibly a token already seen during peeking)
Token* Peek(); //!< peek for the next token, ignore pragmas
void ResetPeek(); //!< ensure that peeking starts at the current scan position
}; // end Scanner
} // namespace
} // namespace
} // namespace
#endif // COCO_calcEntrySCANNER_H__

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDictTest;
object testDictCalc;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -19,28 +19,13 @@ flowRatePerHour 720;
x 10;
y 20;
z t s v;
// z #test{ // this
// 123 - 456
// // comments // are
// /* stripped
// * 10
// * {}
// */
// + 1 /*100 */ 10
// };
p #calc{ 1 + 2 + 10 * 15 + $x - $y };
p this calculation #calc{
1 + 2 + 10 * 15 +
$x - $y
// $x + $y
}
is done inplace;
// this calculation is in-place, but does not work inside a string:
flowRate "The flow rate " #calc{ $flowRatePerHour / 3600 } "kg/s";
// this is also okay
x #calc{ $x * 1E-3 };
flowRate #calc{ $flowRatePerHour / 3600};
xxx yyy;
foo 30;
bar 15;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,46 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: Any |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object testDictCalcError;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
flowRatePerHour 720;
x 10;
y 20;
z t s v;
// z #test{ // this
// 123 - 456
// // comments // are
// /* stripped
// * 10
// * {}
// */
// + 1 /*100 */ 10
// };
p this calculation #calc{
1xxx1 + 2 + 10 * 15 +
$x - $y
// $x + $y
}
is done inplace;
flowRate #calc{ $flowRatePerHour / 3600};
xxx yyy;
foo 30;
bar 15;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -53,7 +53,7 @@ int main(int argc, char *argv[])
const indirectPrimitivePatch& coupledPatch = globalData.coupledPatch();
// Test:print shared points
// Test:print (collocated) shared points
{
const labelListList& globalPointSlaves =
globalData.globalPointSlaves();
@ -90,7 +90,7 @@ int main(int argc, char *argv[])
// Test: point to faces addressing
// Test: (collocated) point to faces addressing
{
const labelListList& globalPointBoundaryFaces =
globalData.globalPointBoundaryFaces();
@ -137,7 +137,7 @@ int main(int argc, char *argv[])
// Test:point to cells addressing
// Test:(collocated) point to cells addressing
{
const labelList& boundaryCells = globalData.boundaryCells();
const labelListList& globalPointBoundaryCells =
@ -172,7 +172,7 @@ int main(int argc, char *argv[])
// Test:print shared edges
// Test:print (collocated) shared edges
{
const labelListList& globalEdgeSlaves =
globalData.globalEdgeSlaves();

View File

@ -1,9 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude
EXE_LIBS = \
-ltriSurface \
-lmeshTools \
-ldynamicMesh

View File

@ -1,9 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude
EXE_LIBS = \
-ldynamicMesh \
-ltriSurface \
-lmeshTools

View File

@ -0,0 +1,3 @@
foamToSurface.C
EXE = $(FOAM_APPBIN)/foamToSurface

View File

@ -0,0 +1,5 @@
EXE_INC = \
-I$(LIB_SRC)/surfMesh/lnInclude
EXE_LIBS = \
-lsurfMesh

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
foamToSurface
Description
Reads an OpenFOAM mesh and writes the boundaries in a surface format.
Usage
- foamToSurface [OPTION] \n
Reads an OpenFOAM mesh and writes the boundaries in a surface format.
@param -scale \<factor\>\n
Specify an alternative geometry scaling factor.
Eg, use @b 1000 to scale @em [m] to @em [mm].
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "timeSelector.H"
#include "Time.H"
#include "polyMesh.H"
#include "MeshedSurfaces.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noParallel();
argList::validArgs.append("outputFile.ext");
timeSelector::addOptions();
argList::addOption
(
"scale",
"scale",
"specify geometry scaling factor"
);
# include "setRootCase.H"
const stringList& params = args.additionalArgs();
scalar scaleFactor = 0;
args.optionReadIfPresent<scalar>("scale", scaleFactor);
fileName exportName(params[0]);
fileName exportBase = exportName.lessExt();
word exportExt = exportName.ext();
if (!meshedSurface::canWriteType(exportExt, true))
{
return 1;
}
# include "createTime.H"
instantList timeDirs = timeSelector::select0(runTime, args);
# include "createPolyMesh.H"
forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
# include "getTimeIndex.H"
polyMesh::readUpdateState state = mesh.readUpdate();
if (timeI == 0 || state != polyMesh::UNCHANGED)
{
if (state == polyMesh::UNCHANGED)
{
exportName = exportBase + "." + exportExt;
}
else
{
exportName =
exportBase + '_' + runTime.timeName() + "." + exportExt;
}
meshedSurface surf(mesh.boundaryMesh());
surf.scalePoints(scaleFactor);
Info<< "writing " << exportName;
if (scaleFactor <= 0)
{
Info<< " without scaling" << endl;
}
else
{
Info<< " with scaling " << scaleFactor << endl;
}
surf.write(exportName);
}
Info<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
// Read time index from */uniform/time, but treat 0 and constant specially
word timeName = "0";
if
(
runTime.timeName() != "constant"
&& runTime.timeName() != "0"
)
{
IOobject io
(
"time",
runTime.timeName(),
"uniform",
runTime,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
false
);
if (io.headerOk())
{
IOdictionary timeObject
(
IOobject
(
"time",
runTime.timeName(),
"uniform",
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
);
label index;
timeObject.lookup("index") >> index;
timeName = Foam::name(index);
}
else
{
timeName = runTime.timeName();
// Info<< "skip ... missing entry " << io.objectPath() << endl;
// continue;
}
}
Info<< "\nTime [" << timeName << "] = " << runTime.timeName() << nl;

View File

@ -1,7 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude
-I$(LIB_SRC)/surfMesh/lnInclude
EXE_LIBS = \
-lmeshTools \
-ltriSurface
-lsurfMesh

View File

@ -41,7 +41,8 @@ Description
#include "cellSet.H"
#include "faceSet.H"
#include "DynamicList.H"
#include "triSurface.H"
#include "MeshedSurfaces.H"
using namespace Foam;
@ -268,9 +269,11 @@ void readCells
break;
}
IStringStream lineStr(line);
label cellI, feID, physProp, matProp, colour, nNodes;
lineStr >> cellI >> feID >> physProp >> matProp >> colour >> nNodes;
IStringStream lineStr(line);
lineStr
>> cellI >> feID >> physProp >> matProp >> colour >> nNodes;
if (foundFeType.insert(feID))
{
@ -297,7 +300,8 @@ void readCells
face cVerts(3);
IStringStream lineStr(line);
lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2];
lineStr
>> cVerts[0] >> cVerts[1] >> cVerts[2];
boundaryFaces.append(cVerts);
boundaryFaceIndices.append(cellI);
}
@ -308,7 +312,8 @@ void readCells
face cVerts(4);
IStringStream lineStr(line);
lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3];
lineStr
>> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3];
boundaryFaces.append(cVerts);
boundaryFaceIndices.append(cellI);
}
@ -319,14 +324,15 @@ void readCells
labelList cVerts(4);
IStringStream lineStr(line);
lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3];
lineStr
>> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3];
cellVerts.append(cellShape(tet, cVerts, true));
cellMaterial.append(physProp);
if (cellVerts.last().size() != cVerts.size())
{
Pout<< "Line:" << is.lineNumber()
Info<< "Line:" << is.lineNumber()
<< " element:" << cellI
<< " type:" << feID
<< " collapsed from " << cVerts << nl
@ -341,15 +347,16 @@ void readCells
labelList cVerts(6);
IStringStream lineStr(line);
lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3]
>> cVerts[4] >> cVerts[5];
lineStr
>> cVerts[0] >> cVerts[1] >> cVerts[2]
>> cVerts[3] >> cVerts[4] >> cVerts[5];
cellVerts.append(cellShape(prism, cVerts, true));
cellMaterial.append(physProp);
if (cellVerts.last().size() != cVerts.size())
{
Pout<< "Line:" << is.lineNumber()
Info<< "Line:" << is.lineNumber()
<< " element:" << cellI
<< " type:" << feID
<< " collapsed from " << cVerts << nl
@ -373,7 +380,7 @@ void readCells
if (cellVerts.last().size() != cVerts.size())
{
Pout<< "Line:" << is.lineNumber()
Info<< "Line:" << is.lineNumber()
<< " element:" << cellI
<< " type:" << feID
<< " collapsed from " << cVerts << nl
@ -388,7 +395,7 @@ void readCells
IOWarningIn("readCells(IFstream&, label&)", is)
<< "Cell type " << feID << " not supported" << endl;
}
is.getLine(line); //Do nothing
is.getLine(line); // Do nothing
}
}
@ -579,7 +586,11 @@ int main(int argc, char *argv[])
{
argList::noParallel();
argList::validArgs.append(".unv file");
argList::addBoolOption("dump");
argList::addBoolOption
(
"dump",
"dump boundary faces as boundaryFaces.obj (for debugging)"
);
# include "setRootCase.H"
# include "createTime.H"
@ -858,40 +869,25 @@ int main(int argc, char *argv[])
polyPoints /= lengthScale;
// For debugging: dump boundary faces as triSurface
// For debugging: dump boundary faces as OBJ surface mesh
if (args.optionFound("dump"))
{
DynamicList<labelledTri> triangles(boundaryFaces.size());
forAll(boundaryFaces, i)
{
const face& f = boundaryFaces[i];
faceList triFaces(f.nTriangles(polyPoints));
label nTri = 0;
f.triangles(polyPoints, nTri, triFaces);
forAll(triFaces, triFaceI)
{
const face& f = triFaces[triFaceI];
triangles.append(labelledTri(f[0], f[1], f[2], 0));
}
}
// Create globally numbered tri surface
triSurface rawSurface(triangles.shrink(), polyPoints);
// Create locally numbered tri surface
triSurface surface
(
rawSurface.localFaces(),
rawSurface.localPoints()
);
Info<< "Writing boundary faces to STL file boundaryFaces.stl"
Info<< "Writing boundary faces to OBJ file boundaryFaces.obj"
<< nl << endl;
surface.write(runTime.path()/"boundaryFaces.stl");
// Create globally numbered surface
meshedSurface rawSurface
(
xferCopy(polyPoints),
xferCopyTo< faceList >(boundaryFaces)
);
// Write locally numbered surface
meshedSurface
(
xferCopy(rawSurface.localPoints()),
xferCopy(rawSurface.localFaces())
).write(runTime.path()/"boundaryFaces.obj");
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -56,11 +56,6 @@ scalar getMergeDistance(const polyMesh& mesh, const scalar mergeTol)
{
const boundBox& meshBb = mesh.bounds();
scalar mergeDist = mergeTol * meshBb.mag();
scalar writeTol = std::pow
(
scalar(10.0),
-scalar(IOstream::defaultPrecision())
);
Info<< nl
<< "Overall mesh bounding box : " << meshBb << nl
@ -68,17 +63,27 @@ scalar getMergeDistance(const polyMesh& mesh, const scalar mergeTol)
<< "Absolute matching distance : " << mergeDist << nl
<< endl;
if (mesh.time().writeFormat() == IOstream::ASCII && mergeTol < writeTol)
// check writing tolerance
if (mesh.time().writeFormat() == IOstream::ASCII)
{
FatalErrorIn("getMergeDistance(const polyMesh&, const scalar)")
<< "Your current settings specify ASCII writing with "
<< IOstream::defaultPrecision() << " digits precision." << endl
<< "Your merging tolerance (" << mergeTol << ") is finer than this."
<< endl
<< "Please change your writeFormat to binary"
<< " or increase the writePrecision" << endl
<< "or adjust the merge tolerance (-mergeTol)."
<< exit(FatalError);
const scalar writeTol = std::pow
(
scalar(10.0),
-scalar(IOstream::defaultPrecision())
);
if (mergeTol < writeTol)
{
FatalErrorIn("getMergeDistance(const polyMesh&, const dictionary&)")
<< "Your current settings specify ASCII writing with "
<< IOstream::defaultPrecision() << " digits precision." << nl
<< "Your merging tolerance (" << mergeTol
<< ") is finer than this." << nl
<< "Change to binary writeFormat, "
<< "or increase the writePrecision" << endl
<< "or adjust the merge tolerance (mergeTol)."
<< exit(FatalError);
}
}
return mergeDist;
@ -107,7 +112,7 @@ void writeMesh
mesh.time().path()/meshRefiner.timeName()
);
}
Info<< "Written mesh in = "
Info<< "Wrote mesh in = "
<< mesh.time().cpuTimeIncrement() << " s." << endl;
}
@ -115,7 +120,11 @@ void writeMesh
int main(int argc, char *argv[])
{
argList::addBoolOption("overwrite");
argList::addBoolOption
(
"overwrite",
"overwrite existing mesh files"
);
# include "setRootCase.H"
# include "createTime.H"
runTime.functionObjects().off();
@ -126,7 +135,6 @@ int main(int argc, char *argv[])
const bool overwrite = args.optionFound("overwrite");
// Check patches and faceZones are synchronised
mesh.boundaryMesh().checkParallelSync(true);
meshRefinement::checkCoupledFaceZones(mesh);
@ -173,7 +181,7 @@ int main(int argc, char *argv[])
// layer addition parameters
const dictionary& layerDict = meshDict.subDict("addLayersControls");
// absolute merge distance
const scalar mergeDist = getMergeDistance
(
mesh,
@ -181,17 +189,16 @@ int main(int argc, char *argv[])
);
// Debug
// ~~~~~
const label debug(readLabel(meshDict.lookup("debug")));
const label debug = meshDict.lookupOrDefault<label>("debug", 0);
if (debug > 0)
{
meshRefinement::debug = debug;
meshRefinement::debug = debug;
autoRefineDriver::debug = debug;
autoSnapDriver::debug = debug;
autoLayerDriver::debug = debug;
autoSnapDriver::debug = debug;
autoLayerDriver::debug = debug;
}
@ -272,7 +279,7 @@ int main(int argc, char *argv[])
meshRefiner.write
(
debug&meshRefinement::OBJINTERSECTIONS,
debug & meshRefinement::OBJINTERSECTIONS,
mesh.time().path()/meshRefiner.timeName()
);
@ -357,9 +364,9 @@ int main(int argc, char *argv[])
// Now do the real work -refinement -snapping -layers
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Switch wantRefine(meshDict.lookup("castellatedMesh"));
Switch wantSnap(meshDict.lookup("snap"));
Switch wantLayers(meshDict.lookup("addLayers"));
const Switch wantRefine(meshDict.lookup("castellatedMesh"));
const Switch wantSnap(meshDict.lookup("snap"));
const Switch wantLayers(meshDict.lookup("addLayers"));
if (wantRefine)
{
@ -434,6 +441,19 @@ int main(int argc, char *argv[])
// Layer addition parameters
layerParameters layerParams(layerDict, mesh.boundaryMesh());
//!!! Temporary hack to get access to maxLocalCells
bool preBalance;
{
refinementParameters refineParams(refineDict);
preBalance = returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
);
}
if (!overwrite)
{
const_cast<Time&>(mesh.time())++;
@ -444,6 +464,7 @@ int main(int argc, char *argv[])
layerDict,
motionDict,
layerParams,
preBalance,
decomposer,
distributor
);
@ -465,7 +486,7 @@ int main(int argc, char *argv[])
Info<< "End\n" << endl;
return(0);
return 0;
}

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object autoHexMeshDict;
object snappyHexMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -40,7 +40,7 @@ geometry
{
type triSurfaceMesh;
//tolerance 1E-6; // optional:non-default tolerance on intersections
//tolerance 1E-5; // optional:non-default tolerance on intersections
//maxTreeDepth 10; // optional:depth of octree. Decrease only in case
// of memory limitations.
@ -71,9 +71,9 @@ castellatedMeshControls
// Refinement parameters
// ~~~~~~~~~~~~~~~~~~~~~
// While refining maximum number of cells per processor. This is basically
// the number of cells that fit on a processor. If you choose this too small
// it will do just more refinement iterations to obtain a similar mesh.
// If local number of cells is >= maxLocalCells on any processor
// switches from from refinement followed by balancing
// (current method) to (weighted) balancing before refinement.
maxLocalCells 1000000;
// Overall cell limit (approximately). Refinement will stop immediately
@ -89,6 +89,13 @@ castellatedMeshControls
// (unless the number of cells to refine is 0)
minRefinementCells 0;
// Allow a certain level of imbalance during refining
// (since balancing is quite expensive)
// Expressed as fraction of perfect balance (= overall number of cells /
// nProcs). 0=balance always.
maxLoadUnbalance 0.10;
// Number of buffer layers between different levels.
// 1 means normal 2:1 refinement restriction, larger means slower
// refinement.

View File

@ -1,10 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude
EXE_LIBS = \
-ltriSurface \
-ldynamicMesh \
-lmeshTools

View File

@ -47,6 +47,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
Info<< " <<Writing " << nNonAligned
<< " points on non-aligned edges to set "
<< nonAlignedPoints.name() << endl;
nonAlignedPoints.instance() = mesh.pointsInstance();
nonAlignedPoints.write();
}
}
@ -67,6 +68,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
{
Info<< " <<Writing " << nNonClosed
<< " non closed cells to set " << cells.name() << endl;
cells.instance() = mesh.pointsInstance();
cells.write();
}
}
@ -78,6 +80,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
Info<< " <<Writing " << nHighAspect
<< " cells with high aspect ratio to set "
<< aspectCells.name() << endl;
aspectCells.instance() = mesh.pointsInstance();
aspectCells.write();
}
}
@ -94,6 +97,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
{
Info<< " <<Writing " << nFaces
<< " zero area faces to set " << faces.name() << endl;
faces.instance() = mesh.pointsInstance();
faces.write();
}
}
@ -111,6 +115,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
{
Info<< " <<Writing " << nCells
<< " zero volume cells to set " << cells.name() << endl;
cells.instance() = mesh.pointsInstance();
cells.write();
}
}
@ -129,6 +134,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
{
Info<< " <<Writing " << nFaces
<< " non-orthogonal faces to set " << faces.name() << endl;
faces.instance() = mesh.pointsInstance();
faces.write();
}
}
@ -147,6 +153,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
Info<< " <<Writing " << nFaces
<< " faces with incorrect orientation to set "
<< faces.name() << endl;
faces.instance() = mesh.pointsInstance();
faces.write();
}
}
@ -164,6 +171,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
{
Info<< " <<Writing " << nFaces
<< " skew faces to set " << faces.name() << endl;
faces.instance() = mesh.pointsInstance();
faces.write();
}
}
@ -184,6 +192,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
Info<< " <<Writing " << nPoints
<< " points on short edges to set " << points.name()
<< endl;
points.instance() = mesh.pointsInstance();
points.write();
}
}
@ -202,6 +211,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
Info<< " <<Writing " << nPoints
<< " near (closer than " << Foam::sqrt(minDistSqr)
<< " apart) points to set " << nearPoints.name() << endl;
nearPoints.instance() = mesh.pointsInstance();
nearPoints.write();
}
}
@ -221,6 +231,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
Info<< " <<Writing " << nFaces
<< " faces with concave angles to set " << faces.name()
<< endl;
faces.instance() = mesh.pointsInstance();
faces.write();
}
}
@ -239,6 +250,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
{
Info<< " <<Writing " << nFaces
<< " warped faces to set " << faces.name() << endl;
faces.instance() = mesh.pointsInstance();
faces.write();
}
}
@ -255,6 +267,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
Info<< " <<Writing " << nCells
<< " under-determined cells to set " << cells.name() << endl;
cells.instance() = mesh.pointsInstance();
cells.write();
}
}

View File

@ -89,6 +89,7 @@ Foam::label Foam::checkTopology
Info<< " <<Writing " << nPoints
<< " unused points to set " << points.name() << endl;
points.instance() = mesh.pointsInstance();
points.write();
}
}
@ -106,6 +107,7 @@ Foam::label Foam::checkTopology
{
Info<< " <<Writing " << nFaces
<< " unordered faces to set " << faces.name() << endl;
faces.instance() = mesh.pointsInstance();
faces.write();
}
}
@ -122,6 +124,7 @@ Foam::label Foam::checkTopology
Info<< " <<Writing " << nCells
<< " cells with over used edges to set " << cells.name()
<< endl;
cells.instance() = mesh.pointsInstance();
cells.write();
}
}
@ -137,6 +140,7 @@ Foam::label Foam::checkTopology
Info<< " <<Writing " << nFaces
<< " faces with out-of-range or duplicate vertices to set "
<< faces.name() << endl;
faces.instance() = mesh.pointsInstance();
faces.write();
}
}
@ -153,6 +157,7 @@ Foam::label Foam::checkTopology
Info<< " <<Writing " << nFaces
<< " faces with incorrect edges to set " << faces.name()
<< endl;
faces.instance() = mesh.pointsInstance();
faces.write();
}
}
@ -203,6 +208,7 @@ Foam::label Foam::checkTopology
<< " cells with with single non-boundary face to set "
<< oneCells.name()
<< endl;
oneCells.instance() = mesh.pointsInstance();
oneCells.write();
}
@ -214,6 +220,7 @@ Foam::label Foam::checkTopology
<< " cells with with single non-boundary face to set "
<< twoCells.name()
<< endl;
twoCells.instance() = mesh.pointsInstance();
twoCells.write();
}
}
@ -354,6 +361,7 @@ Foam::label Foam::checkTopology
<< " conflicting points to set "
<< points.name() << endl;
points.instance() = mesh.pointsInstance();
points.write();
}

View File

@ -43,6 +43,8 @@ FoamFile
matchTolerance 1E-3;
// Do a synchronisation of coupled points after creation of any patches.
// Note: this does not work with points that are on multiple coupled patches
// with transformations.
pointSync true;
// Patches to create.

View File

@ -1,8 +1 @@
/*
EXE_INC = \
-I$(LIB_SRC)/triSurface/lnInclude
EXE_LIBS = \
-lmeshTools \
-ltriSurface
*/
/* */

View File

@ -1,9 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-ldynamicMesh \
-lmeshTools

View File

@ -45,6 +45,7 @@ Description
#include "cellZoneSet.H"
#include "faceZoneSet.H"
#include "pointZoneSet.H"
#include "timeSelector.H"
#include <stdio.h>
@ -82,45 +83,6 @@ Istream& selectStream(Istream* is0Ptr, Istream* is1Ptr)
}
}
// Copy set
void backup
(
const word& setType,
const polyMesh& mesh,
const word& fromName,
const topoSet& fromSet,
const word& toName
)
{
if (fromSet.size())
{
Info<< " Backing up " << fromName << " into " << toName << endl;
topoSet::New(setType, mesh, toName, fromSet)().write();
}
}
// Read and copy set
void backup
(
const word& setType,
const polyMesh& mesh,
const word& fromName,
const word& toName
)
{
autoPtr<topoSet> fromSet = topoSet::New
(
setType,
mesh,
fromName,
IOobject::READ_IF_PRESENT
);
backup(setType, mesh, fromName, fromSet(), toName);
}
// Write set to VTK readable files
void writeVTK
@ -304,7 +266,13 @@ void printAllSets(const polyMesh& mesh, Ostream& os)
IOobjectList objects
(
mesh,
mesh.pointsInstance(),
mesh.time().findInstance
(
polyMesh::meshSubDir/"sets",
word::null,
IOobject::READ_IF_PRESENT,
mesh.facesInstance()
),
polyMesh::meshSubDir/"sets"
);
IOobjectList cellSets(objects.lookupClass(cellSet::typeName));
@ -417,7 +385,13 @@ void removeSet
IOobjectList objects
(
mesh,
mesh.pointsInstance(),
mesh.time().findInstance
(
polyMesh::meshSubDir/"sets",
word::null,
IOobject::READ_IF_PRESENT,
mesh.facesInstance()
),
polyMesh::meshSubDir/"sets"
);
@ -465,6 +439,7 @@ bool doCommand
const word& setName,
const word& actionName,
const bool writeVTKFile,
const bool writeCurrentTime,
Istream& is
)
{
@ -628,8 +603,6 @@ bool doCommand
/currentSet.name()
<< " and to vtk file " << vtkName << endl << endl;
currentSet.write();
writeVTK(mesh, currentSet, vtkName);
}
else
@ -638,9 +611,13 @@ bool doCommand
<< " (size " << currentSet.size() << ") to "
<< currentSet.instance()/currentSet.local()
/currentSet.name() << endl << endl;
currentSet.write();
}
if (writeCurrentTime)
{
currentSet.instance() = mesh.time().timeName();
}
currentSet.write();
}
}
}
@ -692,6 +669,48 @@ void printMesh(const Time& runTime, const polyMesh& mesh)
}
polyMesh::readUpdateState meshReadUpdate(polyMesh& mesh)
{
polyMesh::readUpdateState stat = mesh.readUpdate();
switch(stat)
{
case polyMesh::UNCHANGED:
{
Info<< " mesh not changed." << endl;
break;
}
case polyMesh::POINTS_MOVED:
{
Info<< " points moved; topology unchanged." << endl;
break;
}
case polyMesh::TOPO_CHANGE:
{
Info<< " topology changed; patches unchanged." << nl
<< " ";
printMesh(mesh.time(), mesh);
break;
}
case polyMesh::TOPO_PATCH_CHANGE:
{
Info<< " topology changed and patches changed." << nl
<< " ";
printMesh(mesh.time(), mesh);
break;
}
default:
{
FatalErrorIn("meshReadUpdate(polyMesh&)")
<< "Illegal mesh update state "
<< stat << abort(FatalError);
break;
}
}
return stat;
}
commandStatus parseType
(
@ -730,44 +749,10 @@ commandStatus parseType
<< " to " << Times[nearestIndex].name()
<< endl;
// Set time
runTime.setTime(Times[nearestIndex], nearestIndex);
polyMesh::readUpdateState stat = mesh.readUpdate();
switch(stat)
{
case polyMesh::UNCHANGED:
{
Info<< " mesh not changed." << endl;
break;
}
case polyMesh::POINTS_MOVED:
{
Info<< " points moved; topology unchanged." << endl;
break;
}
case polyMesh::TOPO_CHANGE:
{
Info<< " topology changed; patches unchanged." << nl
<< " ";
printMesh(runTime, mesh);
break;
}
case polyMesh::TOPO_PATCH_CHANGE:
{
Info<< " topology changed and patches changed." << nl
<< " ";
printMesh(runTime, mesh);
break;
}
default:
{
FatalErrorIn("parseType")
<< "Illegal mesh update state "
<< stat << abort(FatalError);
break;
}
}
// Optionally re-read mesh
meshReadUpdate(mesh);
return INVALID;
}
@ -840,23 +825,28 @@ commandStatus parseAction(const word& actionName)
int main(int argc, char *argv[])
{
timeSelector::addOptions(true, false);
# include "addRegionOption.H"
# include "addTimeOptions.H"
argList::addBoolOption("noVTK");
argList::addBoolOption("noVTK", "do not write VTK files");
argList::addBoolOption("loop", "execute batch commands for all timesteps");
argList::addOption("batch", "file");
# include "setRootCase.H"
# include "createTime.H"
instantList timeDirs = timeSelector::select0(runTime, args);
bool writeVTK = !args.optionFound("noVTK");
bool loop = args.optionFound("loop");
bool batch = args.optionFound("batch");
// Get times list
instantList Times = runTime.times();
# include "checkTimeOptions.H"
if (loop && !batch)
{
FatalErrorIn(args.executable())
<< "Can only loop when in batch mode."
<< exit(FatalError);
}
runTime.setTime(Times[startTime], startTime);
# include "createNamedPolyMesh.H"
@ -866,135 +856,171 @@ int main(int argc, char *argv[])
// Print current sets
printAllSets(mesh, Info);
std::ifstream* fileStreamPtr(NULL);
if (args.optionFound("batch"))
{
fileName batchFile(args.option("batch"));
Info<< "Reading commands from file " << batchFile << endl;
// we cannot handle .gz files
if (!isFile(batchFile, false))
{
FatalErrorIn(args.executable())
<< "Cannot open file " << batchFile << exit(FatalError);
}
fileStreamPtr = new std::ifstream(batchFile.c_str());
}
#if READLINE != 0
else if (!read_history(historyFile))
// Read history if interactive
# if READLINE != 0
if (!batch && !read_history(historyFile))
{
Info<< "Successfully read history from " << historyFile << endl;
}
#endif
# endif
Info<< "Please type 'help', 'quit' or a set command after prompt." << endl;
bool ok = true;
// Exit status
int status = 0;
FatalError.throwExceptions();
FatalIOError.throwExceptions();
do
forAll(timeDirs, timeI)
{
string rawLine;
runTime.setTime(timeDirs[timeI], timeI);
Info<< "Time = " << runTime.timeName() << endl;
// Type: cellSet, faceSet, pointSet
word setType;
// Name of destination set.
word setName;
// Action (new, invert etc.)
word actionName;
// Handle geometry/topology changes
meshReadUpdate(mesh);
commandStatus stat = INVALID;
if (fileStreamPtr)
// Main command read & execute loop
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
autoPtr<IFstream> fileStreamPtr(NULL);
if (batch)
{
if (!fileStreamPtr->good())
fileName batchFile(args.option("batch"));
Info<< "Reading commands from file " << batchFile << endl;
// we cannot handle .gz files
if (!isFile(batchFile, false))
{
Info<< "End of batch file" << endl;
break;
FatalErrorIn(args.executable())
<< "Cannot open file " << batchFile << exit(FatalError);
}
std::getline(*fileStreamPtr, rawLine);
if (rawLine.size())
{
Info<< "Doing:" << rawLine << endl;
}
fileStreamPtr.reset(new IFstream(batchFile));
}
else
Info<< "Please type 'help', 'quit' or a set command after prompt."
<< endl;
// Whether to quit
bool quit = false;
FatalError.throwExceptions();
FatalIOError.throwExceptions();
do
{
# if READLINE != 0
string rawLine;
// Type: cellSet, faceSet, pointSet
word setType;
// Name of destination set.
word setName;
// Action (new, invert etc.)
word actionName;
commandStatus stat = INVALID;
if (fileStreamPtr.valid())
{
char* linePtr = readline("readline>");
rawLine = string(linePtr);
if (*linePtr)
if (!fileStreamPtr().good())
{
add_history(linePtr);
write_history(historyFile);
Info<< "End of batch file" << endl;
// No error.
break;
}
free(linePtr); // readline uses malloc, not new.
}
# else
{
Info<< "Command>" << flush;
std::getline(std::cin, rawLine);
}
# endif
}
fileStreamPtr().getLine(rawLine);
if (rawLine.empty() || rawLine[0] == '#')
{
continue;
}
IStringStream is(rawLine + ' ');
// Type: cellSet, faceSet, pointSet, faceZoneSet
is >> setType;
stat = parseType(runTime, mesh, setType, is);
if (stat == VALIDSETCMD || stat == VALIDZONECMD)
{
if (is >> setName)
{
if (is >> actionName)
if (rawLine.size())
{
stat = parseAction(actionName);
Info<< "Doing:" << rawLine << endl;
}
}
}
ok = true;
else
{
# if READLINE != 0
{
char* linePtr = readline("readline>");
if (stat == QUIT)
rawLine = string(linePtr);
if (*linePtr)
{
add_history(linePtr);
write_history(historyFile);
}
free(linePtr); // readline uses malloc, not new.
}
# else
{
Info<< "Command>" << flush;
std::getline(std::cin, rawLine);
}
# endif
}
if (rawLine.empty() || rawLine[0] == '#')
{
continue;
}
IStringStream is(rawLine + ' ');
// Type: cellSet, faceSet, pointSet, faceZoneSet
is >> setType;
stat = parseType(runTime, mesh, setType, is);
if (stat == VALIDSETCMD || stat == VALIDZONECMD)
{
if (is >> setName)
{
if (is >> actionName)
{
stat = parseAction(actionName);
}
}
}
if (stat == QUIT)
{
// Make sure to quit
quit = true;
}
else if (stat == VALIDSETCMD || stat == VALIDZONECMD)
{
bool ok = doCommand
(
mesh,
setType,
setName,
actionName,
writeVTK,
loop, // if in looping mode dump sets to time directory
is
);
if (!ok)
{
// Exit with error.
quit = true;
status = 1;
}
}
} while (!quit);
if (quit)
{
break;
}
else if (stat == VALIDSETCMD || stat == VALIDZONECMD)
{
ok = doCommand(mesh, setType, setName, actionName, writeVTK, is);
}
} while (ok);
if (fileStreamPtr)
{
delete fileStreamPtr;
}
Info<< "\nEnd\n" << endl;
return 0;
return status;
}

View File

@ -81,14 +81,17 @@ int main(int argc, char *argv[])
# include "createNamedPolyMesh.H"
// Search for list of objects for the time of the mesh
IOobjectList objects
word setsInstance = runTime.findInstance
(
mesh,
mesh.pointsInstance(),
polyMesh::meshSubDir/"sets"
polyMesh::meshSubDir/"sets",
word::null,
IOobject::MUST_READ,
mesh.facesInstance()
);
Info<< "Searched : " << mesh.pointsInstance()/polyMesh::meshSubDir/"sets"
IOobjectList objects(mesh, setsInstance, polyMesh::meshSubDir/"sets");
Info<< "Searched : " << setsInstance/polyMesh::meshSubDir/"sets"
<< nl
<< "Found : " << objects.names() << nl
<< endl;

View File

@ -64,6 +64,7 @@ Description
#include "syncTools.H"
#include "ReadFields.H"
#include "directMappedWallPolyPatch.H"
#include "zeroGradientFvPatchFields.H"
using namespace Foam;
@ -164,25 +165,24 @@ void reorderPatchFields(fvMesh& mesh, const labelList& oldToNew)
// Adds patch if not yet there. Returns patchID.
template<class PatchType>
label addPatch(fvMesh& mesh, const word& patchName)
label addPatch(fvMesh& mesh, const polyPatch& patch)
{
polyBoundaryMesh& polyPatches =
const_cast<polyBoundaryMesh&>(mesh.boundaryMesh());
label patchI = polyPatches.findPatchID(patchName);
label patchI = polyPatches.findPatchID(patch.name());
if (patchI != -1)
{
if (isA<PatchType>(polyPatches[patchI]))
if (polyPatches[patchI].type() == patch.type())
{
// Already there
return patchI;
}
else
{
FatalErrorIn("addPatch<PatchType>(fvMesh&, const word&)")
<< "Already have patch " << patchName
<< " but of type " << PatchType::typeName
FatalErrorIn("addPatch(fvMesh&, const polyPatch*)")
<< "Already have patch " << patch.name()
<< " but of type " << patch.type()
<< exit(FatalError);
}
}
@ -219,14 +219,12 @@ label addPatch(fvMesh& mesh, const word& patchName)
polyPatches.set
(
sz,
polyPatch::New
patch.clone
(
PatchType::typeName,
patchName,
0, // size
startFaceI,
insertPatchI,
polyPatches
polyPatches,
insertPatchI, //index
0, //size
startFaceI //start
)
);
fvPatches.setSize(sz+1);
@ -1086,16 +1084,37 @@ EdgeMap<label> addRegionPatches
if (interfaceSizes[e] > 0)
{
label patchI = addPatch<directMappedWallPolyPatch>
const word inter1 = regionNames[e[0]] + "_to_" + regionNames[e[1]];
const word inter2 = regionNames[e[1]] + "_to_" + regionNames[e[0]];
directMappedWallPolyPatch patch1
(
mesh,
regionNames[e[0]] + "_to_" + regionNames[e[1]]
inter1,
0, // overridden
0, // overridden
0, // overridden
regionNames[e[1]], // sampleRegion
directMappedPatchBase::NEARESTPATCHFACE,
inter2, // samplePatch
point::zero, // offset
mesh.boundaryMesh()
);
addPatch<directMappedWallPolyPatch>
label patchI = addPatch(mesh, patch1);
directMappedWallPolyPatch patch2
(
mesh,
regionNames[e[1]] + "_to_" + regionNames[e[0]]
inter2,
0,
0,
0,
regionNames[e[0]], // sampleRegion
directMappedPatchBase::NEARESTPATCHFACE,
inter1,
point::zero, // offset
mesh.boundaryMesh()
);
addPatch(mesh, patch2);
Info<< "For interface between region " << e[0]
<< " and " << e[1] << " added patch " << patchI
@ -1495,7 +1514,8 @@ int main(int argc, char *argv[])
false
),
mesh,
dimensionedScalar("zero", dimless, 0)
dimensionedScalar("zero", dimless, 0),
zeroGradientFvPatchScalarField::typeName
);
forAll(cellRegion, cellI)
{

View File

@ -18,6 +18,7 @@ EXE_LIBS = \
-lengine \
-lerrorEstimation \
-lfieldFunctionObjects \
-lfileFormats \
-lfiniteVolume \
-lforces \
-lfvMotionSolvers \

View File

@ -46,9 +46,6 @@ Usage
@param -fields \n
Use existing geometry decomposition and convert fields only.
@param -filterPatches \n
Remove empty patches when decomposing the geometry.
@param -force \n
Remove any existing @a processor subdirectories before decomposing the
geometry.
@ -99,11 +96,6 @@ int main(int argc, char *argv[])
"use existing geometry decomposition and convert fields only"
);
argList::addBoolOption
(
"filterPatches",
"remove empty patches when decomposing the geometry"
);
argList::addBoolOption
(
"force",
"remove existing processor*/ subdirs before decomposing the geometry"
@ -128,7 +120,6 @@ int main(int argc, char *argv[])
bool writeCellDist = args.optionFound("cellDist");
bool copyUniform = args.optionFound("copyUniform");
bool decomposeFieldsOnly = args.optionFound("fields");
bool filterPatches = args.optionFound("filterPatches");
bool forceOverwrite = args.optionFound("force");
bool ifRequiredDecomposition = args.optionFound("ifRequired");
@ -249,7 +240,7 @@ int main(int argc, char *argv[])
// Decompose the mesh
if (!decomposeFieldsOnly)
{
mesh.decomposeMesh(filterPatches);
mesh.decomposeMesh();
mesh.writeDecomposition();

View File

@ -69,6 +69,24 @@ void Foam::domainDecomposition::mark
Foam::domainDecomposition::domainDecomposition(const IOobject& io)
:
fvMesh(io),
facesInstancePointsPtr_
(
pointsInstance() != facesInstance()
? new pointIOField
(
IOobject
(
"points",
facesInstance(),
polyMesh::meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
)
: NULL
),
decompositionDict_
(
IOobject
@ -86,7 +104,6 @@ Foam::domainDecomposition::domainDecomposition(const IOobject& io)
procPointAddressing_(nProcs_),
procFaceAddressing_(nProcs_),
procCellAddressing_(nProcs_),
procBoundaryAddressing_(nProcs_),
procPatchSize_(nProcs_),
procPatchStartIndex_(nProcs_),
procNeighbourProcessors_(nProcs_),
@ -263,24 +280,67 @@ bool Foam::domainDecomposition::writeDecomposition()
"system",
"constant"
);
processorDb.setTime(time());
// create the mesh
polyMesh procMesh
(
IOobject
// create the mesh. Two situations:
// - points and faces come from the same time ('instance'). The mesh
// will get constructed in the same instance.
// - points come from a different time (moving mesh cases).
// It will read the points belonging to the faces instance and
// construct the procMesh with it which then gets handled as above.
// (so with 'old' geometry).
// Only at writing time will it additionally write the current
// points.
autoPtr<polyMesh> procMeshPtr;
if (facesInstancePointsPtr_.valid())
{
// Construct mesh from facesInstance.
pointField facesInstancePoints
(
this->polyMesh::name(), // region name of undecomposed mesh
pointsInstance(),
processorDb
),
xferMove(procPoints),
xferMove(procFaces),
xferMove(procCells)
);
facesInstancePointsPtr_(),
curPointLabels
);
procMeshPtr.reset
(
new polyMesh
(
IOobject
(
this->polyMesh::name(), // region of undecomposed mesh
facesInstance(),
processorDb
),
xferMove(facesInstancePoints),
xferMove(procFaces),
xferMove(procCells)
)
);
}
else
{
procMeshPtr.reset
(
new polyMesh
(
IOobject
(
this->polyMesh::name(), // region of undecomposed mesh
facesInstance(),
processorDb
),
xferMove(procPoints),
xferMove(procFaces),
xferMove(procCells)
)
);
}
polyMesh& procMesh = procMeshPtr();
// Create processor boundary patches
const labelList& curBoundaryAddressing = procBoundaryAddressing_[procI];
const labelList& curPatchSizes = procPatchSize_[procI];
const labelList& curPatchStarts = procPatchStartIndex_[procI];
@ -309,8 +369,7 @@ bool Foam::domainDecomposition::writeDecomposition()
{
// Get the face labels consistent with the field mapping
// (reuse the patch field mappers)
const polyPatch& meshPatch =
meshPatches[curBoundaryAddressing[patchi]];
const polyPatch& meshPatch = meshPatches[patchi];
fvFieldDecomposer::patchFieldDecomposer patchMapper
(
@ -324,14 +383,13 @@ bool Foam::domainDecomposition::writeDecomposition()
);
// Map existing patches
procPatches[nPatches] =
meshPatches[curBoundaryAddressing[patchi]].clone
(
procMesh.boundaryMesh(),
nPatches,
patchMapper.directAddressing(),
curPatchStarts[patchi]
).ptr();
procPatches[nPatches] = meshPatch.clone
(
procMesh.boundaryMesh(),
nPatches,
patchMapper.directAddressing(),
curPatchStarts[patchi]
).ptr();
nPatches++;
}
@ -589,6 +647,26 @@ bool Foam::domainDecomposition::writeDecomposition()
procMesh.write();
// Write points if pointsInstance differing from facesInstance
if (facesInstancePointsPtr_.valid())
{
pointIOField pointsInstancePoints
(
IOobject
(
"points",
pointsInstance(),
polyMesh::meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
xferMove(procPoints)
);
pointsInstancePoints.write();
}
Info<< endl
<< "Processor " << procI << nl
<< " Number of cells = " << procMesh.nCells()
@ -678,6 +756,16 @@ bool Foam::domainDecomposition::writeDecomposition()
);
cellProcAddressing.write();
// Write patch map for backwards compatibility.
// (= identity map for original patches, -1 for processor patches)
label nMeshPatches = curPatchSizes.size();
labelList procBoundaryAddressing(identity(nMeshPatches));
procBoundaryAddressing.setSize
(
nMeshPatches+curProcessorPatchSizes.size(),
-1
);
labelIOList boundaryProcAddressing
(
IOobject
@ -689,7 +777,7 @@ bool Foam::domainDecomposition::writeDecomposition()
IOobject::NO_READ,
IOobject::NO_WRITE
),
procBoundaryAddressing_[procI]
procBoundaryAddressing
);
boundaryProcAddressing.write();
}

View File

@ -55,6 +55,9 @@ class domainDecomposition
{
// Private data
//- Optional: points at the facesInstance
autoPtr<pointIOField> facesInstancePointsPtr_;
//- Mesh decomposition control dictionary
IOdictionary decompositionDict_;
@ -83,9 +86,6 @@ class domainDecomposition
//- Labels of cells for each processor
labelListList procCellAddressing_;
//- Original patch index for every processor patch
labelListList procBoundaryAddressing_;
//- Sizes for processor mesh patches
// Excludes inter-processor boundaries
labelListList procPatchSize_;
@ -149,8 +149,8 @@ public:
return distributed_;
}
//- Decompose mesh. Optionally remove zero-sized patches.
void decomposeMesh(const bool filterEmptyPatches);
//- Decompose mesh.
void decomposeMesh();
//- Write decomposition
bool writeDecomposition();

View File

@ -40,7 +40,7 @@ Description
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
void Foam::domainDecomposition::decomposeMesh()
{
// Decide which cell goes to which processor
distributeCells();
@ -598,64 +598,6 @@ void Foam::domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
}
}
Info<< "\nCalculating processor boundary addressing" << endl;
// For every patch of processor boundary, find the index of the original
// patch. Mis-alignment is caused by the fact that patches with zero size
// are omitted. For processor patches, set index to -1.
// At the same time, filter the procPatchSize_ and procPatchStartIndex_
// lists to exclude zero-size patches
forAll(procPatchSize_, procI)
{
// Make a local copy of old lists
const labelList oldPatchSizes = procPatchSize_[procI];
const labelList oldPatchStarts = procPatchStartIndex_[procI];
labelList& curPatchSizes = procPatchSize_[procI];
labelList& curPatchStarts = procPatchStartIndex_[procI];
const labelList& curProcessorPatchSizes =
procProcessorPatchSize_[procI];
labelList& curBoundaryAddressing = procBoundaryAddressing_[procI];
curBoundaryAddressing.setSize
(
oldPatchSizes.size()
+ curProcessorPatchSizes.size()
);
label nPatches = 0;
forAll(oldPatchSizes, patchi)
{
if (!filterEmptyPatches || oldPatchSizes[patchi] > 0)
{
curBoundaryAddressing[nPatches] = patchi;
curPatchSizes[nPatches] = oldPatchSizes[patchi];
curPatchStarts[nPatches] = oldPatchStarts[patchi];
nPatches++;
}
}
// reset to the size of live patches
curPatchSizes.setSize(nPatches);
curPatchStarts.setSize(nPatches);
forAll(curProcessorPatchSizes, procPatchI)
{
curBoundaryAddressing[nPatches] = -1;
nPatches++;
}
curBoundaryAddressing.setSize(nPatches);
}
Info<< "\nDistributing points to processors" << endl;
// For every processor, loop through the list of faces for the processor.
// For every face, loop through the list of points and mark the point as

View File

@ -80,6 +80,4 @@ Foam::lagrangianFieldDecomposer::lagrangianFieldDecomposer
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -1,7 +1,7 @@
// ignore special fields or fields that we don't handle
//
bool variableGood = true;
for (label n1=startTime; n1<endTime && variableGood; ++n1)
for (label n1=0; n1<Times.size() && variableGood; ++n1)
{
// ignore _0 fields
if (fieldName.size() > 2 && fieldName(fieldName.size() - 2, 2) == "_0")

View File

@ -19,7 +19,7 @@ if (Pstream::master())
Info<< "Correcting time values. Adding " << Tcorr << endl;
}
for (int n=startTime; n<endTime; n++)
forAll(Times, n)
{
ensightCaseFile << setw(12) << Times[n].value() + Tcorr << " ";

View File

@ -185,7 +185,6 @@ void writeAllFaceData
const labelList& prims,
const label nPrims,
const Field<Type>& pf,
const labelList& patchProcessors,
OFstream& ensightFile
)
{
@ -199,16 +198,12 @@ void writeAllFaceData
{
writeData(map(pf, prims, cmpt), ensightFile);
forAll(patchProcessors, i)
for (int slave=1; slave<Pstream::nProcs(); slave++)
{
if (patchProcessors[i] != 0)
{
label slave = patchProcessors[i];
IPstream fromSlave(Pstream::scheduled, slave);
scalarField pf(fromSlave);
IPstream fromSlave(Pstream::scheduled, slave);
scalarField pf(fromSlave);
writeData(pf, ensightFile);
}
writeData(pf, ensightFile);
}
}
}
@ -231,7 +226,6 @@ void writeAllFaceDataBinary
const labelList& prims,
const label nPrims,
const Field<Type>& pf,
const labelList& patchProcessors,
std::ofstream& ensightFile
)
{
@ -245,16 +239,12 @@ void writeAllFaceDataBinary
{
writeEnsDataBinary(map(pf, prims, cmpt), ensightFile);
forAll(patchProcessors, i)
for (int slave=1; slave<Pstream::nProcs(); slave++)
{
if (patchProcessors[i] != 0)
{
label slave = patchProcessors[i];
IPstream fromSlave(Pstream::scheduled, slave);
scalarField pf(fromSlave);
IPstream fromSlave(Pstream::scheduled, slave);
scalarField pf(fromSlave);
writeEnsDataBinary(pf, ensightFile);
}
writeEnsDataBinary(pf, ensightFile);
}
}
}
@ -278,7 +268,6 @@ bool writePatchField
const Foam::label ensightPatchI,
const Foam::faceSets& boundaryFaceSet,
const Foam::ensightMesh::nFacePrimitives& nfp,
const Foam::labelList& patchProcessors,
Foam::OFstream& ensightFile
)
{
@ -297,7 +286,6 @@ bool writePatchField
boundaryFaceSet.tris,
nfp.nTris,
pf,
patchProcessors,
ensightFile
);
@ -307,7 +295,6 @@ bool writePatchField
boundaryFaceSet.quads,
nfp.nQuads,
pf,
patchProcessors,
ensightFile
);
@ -317,7 +304,6 @@ bool writePatchField
boundaryFaceSet.polys,
nfp.nPolys,
pf,
patchProcessors,
ensightFile
);
@ -338,7 +324,6 @@ bool writePatchFieldBinary
const Foam::label ensightPatchI,
const Foam::faceSets& boundaryFaceSet,
const Foam::ensightMesh::nFacePrimitives& nfp,
const Foam::labelList& patchProcessors,
std::ofstream& ensightFile
)
{
@ -356,7 +341,6 @@ bool writePatchFieldBinary
boundaryFaceSet.tris,
nfp.nTris,
pf,
patchProcessors,
ensightFile
);
@ -366,7 +350,6 @@ bool writePatchFieldBinary
boundaryFaceSet.quads,
nfp.nQuads,
pf,
patchProcessors,
ensightFile
);
@ -376,7 +359,6 @@ bool writePatchFieldBinary
boundaryFaceSet.polys,
nfp.nPolys,
pf,
patchProcessors,
ensightFile
);
@ -406,7 +388,6 @@ void writePatchField
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
const wordList& allPatchNames = eMesh.allPatchNames();
const List<labelList>& allPatchProcs = eMesh.allPatchProcs();
const HashTable<ensightMesh::nFacePrimitives>&
nPatchPrims = eMesh.nPatchPrims();
@ -425,8 +406,6 @@ void writePatchField
}
const labelList& patchProcessors = allPatchProcs[patchi];
word pfName = patchName + '.' + fieldName;
word timeFile = prepend + itoa(timeIndex);
@ -473,7 +452,6 @@ void writePatchField
ensightPatchI,
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
patchProcessors,
ensightFile
);
}
@ -488,7 +466,6 @@ void writePatchField
ensightPatchI,
nullFaceSets,
nPatchPrims.find(patchName)(),
patchProcessors,
ensightFile
);
}
@ -521,7 +498,6 @@ void ensightFieldAscii
const cellSets& meshCellSets = eMesh.meshCellSets();
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
const wordList& allPatchNames = eMesh.allPatchNames();
const List<labelList>& allPatchProcs = eMesh.allPatchProcs();
const wordHashSet& patchNames = eMesh.patchNames();
const HashTable<ensightMesh::nFacePrimitives>&
nPatchPrims = eMesh.nPatchPrims();
@ -619,50 +595,23 @@ void ensightFieldAscii
forAll(allPatchNames, patchi)
{
const word& patchName = allPatchNames[patchi];
const labelList& patchProcessors = allPatchProcs[patchi];
if (patchNames.empty() || patchNames.found(patchName))
{
if (mesh.boundary()[patchi].size())
{
if
if
(
writePatchField
(
writePatchField
(
vf.boundaryField()[patchi],
patchi,
ensightPatchI,
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
patchProcessors,
ensightFile
)
vf.boundaryField()[patchi],
patchi,
ensightPatchI,
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
ensightFile
)
{
ensightPatchI++;
}
}
else if (Pstream::master())
)
{
faceSets nullFaceSet;
if
(
writePatchField
(
Field<Type>(),
-1,
ensightPatchI,
nullFaceSet,
nPatchPrims.find(patchName)(),
patchProcessors,
ensightFile
)
)
{
ensightPatchI++;
}
ensightPatchI++;
}
}
}
@ -695,7 +644,6 @@ void ensightFieldBinary
const cellSets& meshCellSets = eMesh.meshCellSets();
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
const wordList& allPatchNames = eMesh.allPatchNames();
const List<labelList>& allPatchProcs = eMesh.allPatchProcs();
const wordHashSet& patchNames = eMesh.patchNames();
const HashTable<ensightMesh::nFacePrimitives>&
nPatchPrims = eMesh.nPatchPrims();
@ -819,50 +767,23 @@ void ensightFieldBinary
forAll(allPatchNames, patchi)
{
const word& patchName = allPatchNames[patchi];
const labelList& patchProcessors = allPatchProcs[patchi];
if (patchNames.empty() || patchNames.found(patchName))
{
if (mesh.boundary()[patchi].size())
{
if
if
(
writePatchFieldBinary
(
writePatchFieldBinary
(
vf.boundaryField()[patchi],
patchi,
ensightPatchI,
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
patchProcessors,
ensightFile
)
vf.boundaryField()[patchi],
patchi,
ensightPatchI,
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
ensightFile
)
{
ensightPatchI++;
}
}
else if (Pstream::master())
)
{
faceSets nullFaceSet;
if
(
writePatchFieldBinary
(
Field<Type>(),
-1,
ensightPatchI,
nullFaceSet,
nPatchPrims.find(patchName)(),
patchProcessors,
ensightFile
)
)
{
ensightPatchI++;
}
ensightPatchI++;
}
}
}

View File

@ -42,6 +42,7 @@ SourceFiles
#include "fvMesh.H"
#include "OFstream.H"
#include <fstream>
#include "globalIndex.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -62,14 +63,12 @@ public:
{
public:
label nPoints;
label nTris;
label nQuads;
label nPolys;
nFacePrimitives()
:
nPoints(0),
nTris(0),
nQuads(0),
nPolys(0)
@ -95,8 +94,6 @@ private:
wordList allPatchNames_;
List<labelList> allPatchProcs_;
wordHashSet patchNames_;
HashTable<nFacePrimitives> nPatchPrims_;
@ -119,20 +116,21 @@ private:
cellShapeList map
(
const cellShapeList& cellShapes,
const labelList& prims
const labelList& prims,
const labelList& pointToGlobal
) const;
cellShapeList map
(
const cellShapeList& cellShapes,
const labelList& hexes,
const labelList& wedges
const labelList& wedges,
const labelList& pointToGlobal
) const;
void writePrims
(
const cellShapeList& cellShapes,
const label pointOffset,
OFstream& ensightGeometryFile
) const;
@ -156,13 +154,12 @@ private:
const labelList& polys,
const cellList& cellFaces,
const faceList& faces,
const label pointOffset,
OFstream& ensightGeometryFile
) const;
void writeAllPolys
(
const labelList& pointOffsets,
const labelList& pointToGlobal,
OFstream& ensightGeometryFile
) const;
@ -171,31 +168,21 @@ private:
const char* key,
const label nPrims,
const cellShapeList& cellShapes,
const labelList& pointOffsets,
OFstream& ensightGeometryFile
) const;
void writeFacePrims
(
const faceList& patchFaces,
const label pointOffset,
OFstream& ensightGeometryFile
) const;
faceList map
(
const faceList& patchFaces,
const labelList& prims
) const;
void writeAllFacePrims
(
const char* key,
const labelList& prims,
const label nPrims,
const faceList& patchFaces,
const labelList& pointOffsets,
const labelList& patchProcessors,
OFstream& ensightGeometryFile
) const;
@ -208,7 +195,6 @@ private:
void writeNSidedPoints
(
const faceList& patchFaces,
const label pointOffset,
OFstream& ensightGeometryFile
) const;
@ -217,8 +203,6 @@ private:
const labelList& prims,
const label nPrims,
const faceList& patchFaces,
const labelList& pointOffsets,
const labelList& patchProcessors,
OFstream& ensightGeometryFile
) const;
@ -227,7 +211,10 @@ private:
const fileName& postProcPath,
const word& prepend,
const label timeIndex,
Ostream& ensightCaseFile
Ostream& ensightCaseFile,
const labelList& pointToGlobal,
const pointField& uniquePoints,
const globalIndex& globalPoints
) const;
void writeBinary
@ -235,13 +222,15 @@ private:
const fileName& postProcPath,
const word& prepend,
const label timeIndex,
Ostream& ensightCaseFile
Ostream& ensightCaseFile,
const labelList& pointToGlobal,
const pointField& uniquePoints,
const globalIndex& globalPoints
) const;
void writePrimsBinary
(
const cellShapeList& cellShapes,
const label pointOffset,
std::ofstream& ensightGeometryFile
) const;
@ -250,7 +239,6 @@ private:
const char* key,
const label nPrims,
const cellShapeList& cellShapes,
const labelList& pointOffsets,
std::ofstream& ensightGeometryFile
) const;
@ -274,13 +262,12 @@ private:
const labelList& polys,
const cellList& cellFaces,
const faceList& faces,
const label pointOffset,
std::ofstream& ensightGeometryFile
) const;
void writeAllPolysBinary
(
const labelList& pointOffsets,
const labelList& pointToGlobal,
std::ofstream& ensightGeometryFile
) const;
@ -290,22 +277,18 @@ private:
const labelList& prims,
const label nPrims,
const faceList& patchFaces,
const labelList& pointOffsets,
const labelList& patchProcessors,
std::ofstream& ensightGeometryFile
) const;
void writeFacePrimsBinary
(
const faceList& patchFaces,
const label pointOffset,
std::ofstream& ensightGeometryFile
) const;
void writeNSidedPointsBinary
(
const faceList& patchFaces,
const label pointOffset,
std::ofstream& ensightGeometryFile
) const;
@ -320,8 +303,6 @@ private:
const labelList& prims,
const label nPrims,
const faceList& patchFaces,
const labelList& pointOffsets,
const labelList& patchProcessors,
std::ofstream& ensightGeometryFile
) const;
@ -361,11 +342,6 @@ public:
return allPatchNames_;
}
const List<labelList>& allPatchProcs() const
{
return allPatchProcs_;
}
const wordHashSet& patchNames() const
{
return patchNames_;

View File

@ -93,6 +93,9 @@ bool inFileNameList
int main(int argc, char *argv[])
{
timeSelector::addOptions();
# include "addRegionOption.H"
argList::addBoolOption
(
"ascii",
@ -111,7 +114,6 @@ int main(int argc, char *argv[])
"An empty list suppresses writing the internalMesh."
);
# include "addTimeOptions.H"
# include "setRootCase.H"
// Check options
@ -119,12 +121,7 @@ int main(int argc, char *argv[])
# include "createTime.H"
// get the available time-steps
instantList Times = runTime.times();
# include "checkTimeOptions.H"
runTime.setTime(Times[startTime], startTime);
instantList Times = timeSelector::select0(runTime, args);
# include "createNamedMesh.H"
@ -214,9 +211,9 @@ int main(int argc, char *argv[])
// Identify if lagrangian data exists at each time, and add clouds
// to the 'allCloudNames' hash set
for (label n=startTime; n<endTime; n++)
forAll(Times, timeI)
{
runTime.setTime(Times[n], n);
runTime.setTime(Times[timeI], timeI);
fileNameList cloudDirs = readDir
(
@ -267,9 +264,9 @@ int main(int argc, char *argv[])
// Loop over all times to build list of fields and field types
// for each cloud
for (label n=startTime; n<endTime; n++)
forAll(Times, timeI)
{
runTime.setTime(Times[n], n);
runTime.setTime(Times[timeI], timeI);
IOobjectList cloudObjs
(
@ -296,20 +293,19 @@ int main(int argc, char *argv[])
}
label nTimeSteps = 0;
for (label n=startTime; n<endTime; n++)
forAll(Times, timeIndex)
{
nTimeSteps++;
runTime.setTime(Times[n], n);
label timeIndex = n - startTime;
runTime.setTime(Times[timeIndex], timeIndex);
word timeName = itoa(timeIndex);
word timeFile = prepend + timeName;
Info<< "Translating time = " << runTime.timeName() << nl;
# include "moveMesh.H"
polyMesh::readUpdateState meshState = mesh.readUpdate();
if (timeIndex == 0 || mesh.moving())
if (timeIndex == 0 || (meshState != polyMesh::UNCHANGED))
{
eMesh.write
(

View File

@ -1,28 +0,0 @@
{
IOobject ioPoints
(
"points",
runTime.timeName(),
polyMesh::meshSubDir,
mesh
);
if (ioPoints.headerOk())
{
// Reading new points
pointIOField newPoints
(
IOobject
(
"points",
mesh.time().timeName(),
polyMesh::meshSubDir,
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
mesh.movePoints(newPoints);
}
}

View File

@ -24,14 +24,14 @@ License
\*---------------------------------------------------------------------------*/
#include "tecplotWriter.H"
//extern "C"
//{
#include "MASTER.h"
#include "GLOBAL.h"
//}
#include "tecplotWriter.H"
#include "fvc.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -67,11 +67,11 @@ void Foam::vtkPV3Foam::convertLagrangianField
{
const label nComp = pTraits<Type>::nComponents;
vtkFloatArray *pointData = vtkFloatArray::New();
pointData->SetNumberOfTuples( tf.size() );
pointData->SetNumberOfComponents( nComp );
pointData->Allocate( nComp*tf.size() );
pointData->SetName( tf.name().c_str() );
vtkFloatArray* pointData = vtkFloatArray::New();
pointData->SetNumberOfTuples(tf.size());
pointData->SetNumberOfComponents(nComp);
pointData->Allocate(nComp*tf.size());
pointData->SetName(tf.name().c_str());
if (debug)
{

View File

@ -130,7 +130,7 @@ void Foam::vtkPV3Foam::updateInfoInternalMesh
// Determine mesh parts (internalMesh, patches...)
//- Add internal mesh as first entry
arrayRangeVolume_.reset( arraySelection->GetNumberOfArrays() );
arrayRangeVolume_.reset(arraySelection->GetNumberOfArrays());
arraySelection->AddArray
(
"internalMesh"
@ -173,7 +173,7 @@ void Foam::vtkPV3Foam::updateInfoLagrangian
readDir(dbPtr_->timePath()/lagrangianPrefix, fileName::DIRECTORY)
);
arrayRangeLagrangian_.reset( arraySelection->GetNumberOfArrays() );
arrayRangeLagrangian_.reset(arraySelection->GetNumberOfArrays());
int nClouds = 0;
forAll(cloudDirs, cloudI)
@ -209,7 +209,7 @@ void Foam::vtkPV3Foam::updateInfoPatches
<< " [meshPtr=" << (meshPtr_ ? "set" : "NULL") << "]" << endl;
}
arrayRangePatches_.reset( arraySelection->GetNumberOfArrays() );
arrayRangePatches_.reset(arraySelection->GetNumberOfArrays());
int nPatches = 0;
if (meshPtr_)
@ -319,7 +319,7 @@ void Foam::vtkPV3Foam::updateInfoZones
namesLst = readZoneNames("cellZones");
}
arrayRangeCellZones_.reset( arraySelection->GetNumberOfArrays() );
arrayRangeCellZones_.reset(arraySelection->GetNumberOfArrays());
forAll(namesLst, elemI)
{
arraySelection->AddArray
@ -342,7 +342,7 @@ void Foam::vtkPV3Foam::updateInfoZones
namesLst = readZoneNames("faceZones");
}
arrayRangeFaceZones_.reset( arraySelection->GetNumberOfArrays() );
arrayRangeFaceZones_.reset(arraySelection->GetNumberOfArrays());
forAll(namesLst, elemI)
{
arraySelection->AddArray
@ -365,7 +365,7 @@ void Foam::vtkPV3Foam::updateInfoZones
namesLst = readZoneNames("pointZones");
}
arrayRangePointZones_.reset( arraySelection->GetNumberOfArrays() );
arrayRangePointZones_.reset(arraySelection->GetNumberOfArrays());
forAll(namesLst, elemI)
{
arraySelection->AddArray
@ -400,16 +400,34 @@ void Foam::vtkPV3Foam::updateInfoSets
Info<< "<beg> Foam::vtkPV3Foam::updateInfoSets" << endl;
}
// Add names of sets
IOobjectList objects
// Add names of sets. Search for last time directory with a sets
// subdirectory. Take care not to search beyond the last mesh.
word facesInstance = dbPtr_().findInstance
(
dbPtr_(),
dbPtr_().findInstance(meshDir_, "faces", IOobject::READ_IF_PRESENT),
meshDir_/"sets"
meshDir_,
"faces",
IOobject::READ_IF_PRESENT
);
word setsInstance = dbPtr_().findInstance
(
meshDir_/"sets",
word::null,
IOobject::READ_IF_PRESENT,
facesInstance
);
arrayRangeCellSets_.reset( arraySelection->GetNumberOfArrays() );
IOobjectList objects(dbPtr_(), setsInstance, meshDir_/"sets");
if (debug)
{
Info<< " Foam::vtkPV3Foam::updateInfoSets read "
<< objects.names() << " from " << setsInstance << endl;
}
arrayRangeCellSets_.reset(arraySelection->GetNumberOfArrays());
arrayRangeCellSets_ += addToSelection<cellSet>
(
arraySelection,
@ -417,7 +435,7 @@ void Foam::vtkPV3Foam::updateInfoSets
" - cellSet"
);
arrayRangeFaceSets_.reset( arraySelection->GetNumberOfArrays() );
arrayRangeFaceSets_.reset(arraySelection->GetNumberOfArrays());
arrayRangeFaceSets_ += addToSelection<faceSet>
(
arraySelection,
@ -425,7 +443,7 @@ void Foam::vtkPV3Foam::updateInfoSets
" - faceSet"
);
arrayRangePointSets_.reset( arraySelection->GetNumberOfArrays() );
arrayRangePointSets_.reset(arraySelection->GetNumberOfArrays());
arrayRangePointSets_ += addToSelection<pointSet>
(
arraySelection,

View File

@ -2,7 +2,6 @@ EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude
EXE_LIBS = \
@ -10,5 +9,4 @@ EXE_LIBS = \
-lgenericPatchFields \
-lmeshTools \
-lsampling \
-ltriSurface \
-llagrangian

View File

@ -3,7 +3,6 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude
EXE_LIBS = \
@ -12,5 +11,4 @@ EXE_LIBS = \
-lmeshTools \
-lsampling \
-lsurfMesh \
-ltriSurface \
-llagrangian

View File

@ -83,9 +83,9 @@ sets
type uniform;
axis distance;
//- cavity
start (0.02 0.051 0.005);
end (0.06 0.051 0.005);
//- cavity. Slightly perturbed so not to align with face or edge.
start (0.0201 0.05101 0.00501);
end (0.0601 0.05101 0.00501);
nPoints 10;
}
@ -103,8 +103,8 @@ sets
//end ( 1 0.05 0.005);
//- cavity
start (0.0 0.51 0.005);
end (2 0.51 0.005);
start (0.001 0.5101 0.00501);
end (2.01 0.5101 0.00501);
nPoints 10;
}
@ -112,15 +112,13 @@ sets
{
type cloud;
axis xyz;
points ((0.049 0.049 0.005)(0.051 0.049 0.005));
points ((0.049 0.049 0.00501)(0.051 0.049 0.00501));
}
);
// Surface sampling definition: choice of
// plane : values on plane defined by point, normal.
// patch : values on patch.
// Surface sampling definition
//
// 1] patches are not triangulated by default
// 2] planes are always triangulated
@ -209,6 +207,28 @@ surfaces
// regularise false; // Optional: do not simplify
}
distance
{
// Isosurface from signed/unsigned distance to surface
type distanceSurface;
signed true;
// Definition of surface
surfaceType triSurfaceMesh;
surfaceName integrationPlane.stl;
// Distance to surface
distance 0.0;
interpolate false;
}
triSurfaceSampling
{
// Sampling on triSurface
type sampledTriSurfaceMesh;
surface integrationPlane.stl;
interpolate true;
}
);

View File

@ -1,4 +1,3 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox

View File

@ -1,5 +1,4 @@
EXE_INC = \
/* -I$(LIB_SRC)/cfdTools/general/lnInclude */ \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude

View File

@ -1,9 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/edgeMesh/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude
-I$(LIB_SRC)/edgeMesh/lnInclude
EXE_LIBS = \
-lmeshTools \
-ledgeMesh \
-ltriSurface
-ledgeMesh

View File

@ -82,11 +82,7 @@ void deleteBox
{
const point eMid = surf.edges()[edgeI].centre(surf.localPoints());
if
(
(removeInside && bb.contains(eMid))
|| (!removeInside && !bb.contains(eMid))
)
if (removeInside ? bb.contains(eMid) : !bb.contains(eMid))
{
edgeStat[edgeI] = surfaceFeatures::NONE;
}
@ -138,7 +134,6 @@ int main(int argc, char *argv[])
// Either construct features from surface&featureangle or read set.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,6 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/triSurface/lnInclude
-I$(LIB_SRC)/surfMesh/lnInclude
EXE_LIBS = \
-lmeshTools \
-ltriSurface
-lsurfMesh

View File

@ -23,18 +23,16 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Finds nearest triangle and vertex.
Finds nearest face and vertex.
\*---------------------------------------------------------------------------*/
#include "triSurface.H"
#include "argList.H"
#include "OFstream.H"
#ifndef namespaceFoam
#define namespaceFoam
using namespace Foam;
#endif
#include "MeshedSurfaces.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -44,9 +42,9 @@ int main(int argc, char *argv[])
{
argList::noParallel();
argList::validArgs.clear();
argList::addOption("x", "X");
argList::addOption("y", "Y");
argList::addOption("z", "Z");
argList::addOption("x", "X", "The point x-coordinate (if non-zero)");
argList::addOption("y", "Y", "The point y-coordinate (if non-zero)");
argList::addOption("z", "Z", "The point y-coordinate (if non-zero)");
argList::validArgs.append("surface file");
@ -54,15 +52,15 @@ int main(int argc, char *argv[])
point samplePt
(
args.optionRead<scalar>("x"),
args.optionRead<scalar>("y"),
args.optionRead<scalar>("z")
args.optionLookupOrDefault<scalar>("x", 0),
args.optionLookupOrDefault<scalar>("y", 0),
args.optionLookupOrDefault<scalar>("z", 0)
);
Info<< "Looking for nearest face/vertex to " << samplePt << endl;
Info<< "Reading surf1 ..." << endl;
triSurface surf1(args.additionalArgs()[0]);
Info<< "Reading surf ..." << endl;
meshedSurface surf1(args.additionalArgs()[0]);
//
// Nearest vertex
@ -83,11 +81,11 @@ int main(int argc, char *argv[])
}
}
Info<< "Nearest vertex:" << endl
<< " index :" << minIndex << " (in localPoints)" << endl
Info<< "Nearest vertex:" << nl
<< " index :" << minIndex << " (in localPoints)" << nl
<< " index :" << surf1.meshPoints()[minIndex]
<< " (in points)" << endl
<< " coordinates:" << localPoints[minIndex] << endl
<< " (in points)" << nl
<< " coordinates:" << localPoints[minIndex] << nl
<< endl;
//
@ -101,8 +99,7 @@ int main(int argc, char *argv[])
forAll(surf1, faceI)
{
const labelledTri& f = surf1[faceI];
const point centre = f.centre(points);
const point centre = surf1[faceI].centre(points);
const scalar dist = mag(centre - samplePt);
if (dist < minDist)
@ -112,16 +109,19 @@ int main(int argc, char *argv[])
}
}
const labelledTri& f = surf1[minIndex];
const face& f = surf1[minIndex];
Info<< "Face with nearest centre:" << endl
<< " index :" << minIndex << endl
<< " centre :" << f.centre(points) << endl
<< " face :" << f << endl
<< " vertex coords:" << points[f[0]] << " "
<< points[f[1]] << " " << points[f[2]] << endl
<< endl;
Info<< "Face with nearest centre:" << nl
<< " index :" << minIndex << nl
<< " centre :" << f.centre(points) << nl
<< " face :" << f << nl
<< " vertex coords:\n";
forAll(f, fp)
{
Info<< " " << points[f[fp]] << "\n";
}
Info<< endl;
Info<< "End\n" << endl;

View File

@ -41,6 +41,9 @@ Description
#include "OFstream.H"
#include "meshTools.H"
#include "Random.H"
#include "transform.H"
#include "IOmanip.H"
#include "Pair.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -296,7 +299,7 @@ int main(int argc, char *argv[])
(
"density",
"scalar",
"Specify density,"
"Specify density, "
"kg/m3 for solid properties, kg/m2 for shell properties"
);
@ -355,6 +358,12 @@ int main(int argc, char *argv[])
);
}
if (m < 0)
{
WarningIn(args.executable() + "::main")
<< "Negative mass detected" << endl;
}
vector eVal = eigenValues(J);
tensor eVec = eigenVectors(J);
@ -380,19 +389,221 @@ int main(int argc, char *argv[])
pertI++;
}
Info<< nl
<< "Density = " << density << nl
<< "Mass = " << m << nl
<< "Centre of mass = " << cM << nl
<< "Inertia tensor around centre of mass = " << J << nl
<< "eigenValues (principal moments) = " << eVal << nl
<< "eigenVectors (principal axes) = "
<< eVec.x() << ' ' << eVec.y() << ' ' << eVec.z()
<< endl;
bool showTransform = true;
if
(
(mag(eVec.x() ^ eVec.y()) > (1.0 - SMALL))
&& (mag(eVec.y() ^ eVec.z()) > (1.0 - SMALL))
&& (mag(eVec.z() ^ eVec.x()) > (1.0 - SMALL))
)
{
// Make the eigenvectors a right handed orthogonal triplet
eVec.z() *= sign((eVec.x() ^ eVec.y()) & eVec.z());
// Finding the most natural transformation. Using Lists
// rather than tensors to allow indexed permutation.
// Cartesian basis vectors - right handed orthogonal triplet
List<vector> cartesian(3);
cartesian[0] = vector(1, 0, 0);
cartesian[1] = vector(0, 1, 0);
cartesian[2] = vector(0, 0, 1);
// Principal axis basis vectors - right handed orthogonal
// triplet
List<vector> principal(3);
principal[0] = eVec.x();
principal[1] = eVec.y();
principal[2] = eVec.z();
scalar maxMagDotProduct = -GREAT;
// Matching axis indices, first: cartesian, second:principal
Pair<label> match(-1, -1);
forAll(cartesian, cI)
{
forAll(principal, pI)
{
scalar magDotProduct = mag(cartesian[cI] & principal[pI]);
if (magDotProduct > maxMagDotProduct)
{
maxMagDotProduct = magDotProduct;
match.first() = cI;
match.second() = pI;
}
}
}
scalar sense = sign
(
cartesian[match.first()] & principal[match.second()]
);
if (sense < 0)
{
// Invert the best match direction and swap the order of
// the other two vectors
List<vector> tPrincipal = principal;
tPrincipal[match.second()] *= -1;
tPrincipal[(match.second() + 1) % 3] =
principal[(match.second() + 2) % 3];
tPrincipal[(match.second() + 2) % 3] =
principal[(match.second() + 1) % 3];
principal = tPrincipal;
vector tEVal = eVal;
tEVal[(match.second() + 1) % 3] = eVal[(match.second() + 2) % 3];
tEVal[(match.second() + 2) % 3] = eVal[(match.second() + 1) % 3];
eVal = tEVal;
}
label permutationDelta = match.second() - match.first();
if (permutationDelta != 0)
{
// Add 3 to the permutationDelta to avoid negative indices
permutationDelta += 3;
List<vector> tPrincipal = principal;
vector tEVal = eVal;
for (label i = 0; i < 3; i++)
{
tPrincipal[i] = principal[(i + permutationDelta) % 3];
tEVal[i] = eVal[(i + permutationDelta) % 3];
}
principal = tPrincipal;
eVal = tEVal;
}
label matchedAlready = match.first();
match =Pair<label>(-1, -1);
maxMagDotProduct = -GREAT;
forAll(cartesian, cI)
{
if (cI == matchedAlready)
{
continue;
}
forAll(principal, pI)
{
if (pI == matchedAlready)
{
continue;
}
scalar magDotProduct = mag(cartesian[cI] & principal[pI]);
if (magDotProduct > maxMagDotProduct)
{
maxMagDotProduct = magDotProduct;
match.first() = cI;
match.second() = pI;
}
}
}
sense = sign
(
cartesian[match.first()] & principal[match.second()]
);
if (sense < 0 || (match.second() - match.first()) != 0)
{
principal[match.second()] *= -1;
List<vector> tPrincipal = principal;
tPrincipal[(matchedAlready + 1) % 3] =
principal[(matchedAlready + 2) % 3]*-sense;
tPrincipal[(matchedAlready + 2) % 3] =
principal[(matchedAlready + 1) % 3]*-sense;
principal = tPrincipal;
vector tEVal = eVal;
tEVal[(matchedAlready + 1) % 3] = eVal[(matchedAlready + 2) % 3];
tEVal[(matchedAlready + 2) % 3] = eVal[(matchedAlready + 1) % 3];
eVal = tEVal;
}
eVec.x() = principal[0];
eVec.y() = principal[1];
eVec.z() = principal[2];
// {
// tensor R = rotationTensor(vector(1, 0, 0), eVec.x());
// R = rotationTensor(R & vector(0, 1, 0), eVec.y()) & R;
// Info<< "R = " << nl << R << endl;
// Info<< "R - eVec.T() " << R - eVec.T() << endl;
// }
}
else
{
WarningIn(args.executable() + "::main")
<< "Non-unique eigenvectors, cannot compute transformation "
<< "from Cartesian axes" << endl;
showTransform = false;
}
Info<< nl << setprecision(10)
<< "Density: " << density << nl
<< "Mass: " << m << nl
<< "Centre of mass: " << cM << nl
<< "Inertia tensor around centre of mass: " << nl << J << nl
<< "eigenValues (principal moments): " << eVal << nl
<< "eigenVectors (principal axes): " << nl
<< eVec.x() << nl << eVec.y() << nl << eVec.z() << endl;
if (showTransform)
{
Info<< "Transform tensor from reference state (Q). " << nl
<< "Rotation tensor required to transform "
"from the body reference frame to the global "
"reference frame, i.e.:" << nl
<< "globalVector = Q & bodyLocalVector"
<< nl << eVec.T()
<< endl;
}
if (calcAroundRefPt)
{
Info << "Inertia tensor relative to " << refPt << " = "
Info << "Inertia tensor relative to " << refPt << ": "
<< applyParallelAxisTheorem(m, cM, J, refPt)
<< endl;
}

View File

@ -1,6 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/triSurface/lnInclude
-I$(LIB_SRC)/surfMesh/lnInclude
EXE_LIBS = \
-lmeshTools \
-ltriSurface
-lsurfMesh

View File

@ -23,15 +23,16 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Example of simple laplacian smoother
Example of a simple laplacian smoother
\*---------------------------------------------------------------------------*/
#include "triSurface.H"
#include "argList.H"
#include "OFstream.H"
#include "boundBox.H"
#include "MeshedSurfaces.H"
using namespace Foam;
@ -61,23 +62,20 @@ int main(int argc, char *argv[])
label iters(readLabel(IStringStream(args.additionalArgs()[2])()));
fileName outFileName(args.additionalArgs()[3]);
Info<< "Relax:" << relax << endl;
Info<< "Iters:" << iters << endl;
Info<< "Relax:" << relax << nl
<< "Iters:" << iters << nl
<< "Reading surface from " << surfFileName << " ..." << endl;
meshedSurface surf1(surfFileName);
Info<< "Reading surface from " << surfFileName << " ..." << endl;
triSurface surf1(surfFileName);
Info<< "Triangles : " << surf1.size() << endl;
Info<< "Vertices : " << surf1.nPoints() << endl;
Info<< "Bounding Box : " << boundBox(surf1.localPoints()) << endl;
Info<< "Faces : " << surf1.size() << nl
<< "Vertices : " << surf1.nPoints() << nl
<< "Bounding Box : " << boundBox(surf1.localPoints()) << endl;
pointField newPoints(surf1.localPoints());
const labelListList& pointEdges = surf1.pointEdges();
for (label iter = 0; iter < iters; iter++)
{
forAll(pointEdges, vertI)
@ -100,16 +98,14 @@ int main(int argc, char *argv[])
}
}
triSurface surf2
(
surf1.localFaces(),
surf1.patches(),
newPoints
);
Info<< "Writing surface to " << outFileName << " ..." << endl;
surf2.write(outFileName);
meshedSurface
(
xferMove(newPoints),
xferCopy(surf1.localFaces()),
xferCopy(surf1.surfZones())
).write(outFileName);
Info<< "End\n" << endl;

View File

@ -100,10 +100,8 @@ int main(int argc, char *argv[])
meshSubsetDict.lookup("addFaceNeighbours")
);
Switch invertSelection
(
meshSubsetDict.lookup("invertSelection")
);
const bool invertSelection =
meshSubsetDict.lookupOrDefault<bool>("invertSelection", false);
// Mark the cells for the subset
@ -246,7 +244,7 @@ int main(int argc, char *argv[])
// bb of surface
treeBoundBox bb(selectSurf.localPoints());
// Radnom number generator
// Random number generator
Random rndGen(354543);
// search engine
@ -269,14 +267,11 @@ int main(int argc, char *argv[])
indexedOctree<treeDataTriSurface>::volumeType t =
selectTree.getVolumeType(fc);
if (t == indexedOctree<treeDataTriSurface>::INSIDE && !outside)
{
facesToSubset[faceI] = true;
}
else if
if
(
t == indexedOctree<treeDataTriSurface>::OUTSIDE
&& outside
outside
? (t == indexedOctree<treeDataTriSurface>::OUTSIDE)
: (t == indexedOctree<treeDataTriSurface>::INSIDE)
)
{
facesToSubset[faceI] = true;
@ -346,20 +341,11 @@ int main(int argc, char *argv[])
if (invertSelection)
{
Info<< "Inverting selection." << endl;
boolList newFacesToSubset(facesToSubset.size());
forAll(facesToSubset, i)
{
if (facesToSubset[i])
{
newFacesToSubset[i] = false;
}
else
{
newFacesToSubset[i] = true;
}
facesToSubset[i] = facesToSubset[i] ? false : true;
}
facesToSubset.transfer(newFacesToSubset);
}

View File

@ -36,7 +36,7 @@ zone
surface
{
name "sphere.stl";
outside yes;
outside yes;
}
// Extend selection with edge neighbours

View File

@ -1,6 +1,5 @@
EXE_INC = \
-I$(LIB_SRC)/triSurface/lnInclude
-I$(LIB_SRC)/surfMesh/lnInclude
EXE_LIBS = \
-lmeshTools \
-ltriSurface
-lsurfMesh

View File

@ -35,7 +35,6 @@ Description
\*---------------------------------------------------------------------------*/
#include "triSurface.H"
#include "argList.H"
#include "OFstream.H"
#include "IFstream.H"
@ -45,6 +44,8 @@ Description
#include "quaternion.H"
#include "mathematicalConstants.H"
#include "MeshedSurfaces.H"
using namespace Foam;
using namespace Foam::constant::mathematical;
@ -114,7 +115,7 @@ int main(int argc, char *argv[])
<< exit(FatalError);
}
triSurface surf1(surfFileName);
meshedSurface surf1(surfFileName);
pointField points(surf1.points());
@ -193,9 +194,8 @@ int main(int argc, char *argv[])
points.replace(vector::Z, scaleVector.z()*points.component(vector::Z));
}
triSurface surf2(surf1, surf1.patches(), points);
surf2.write(outFileName);
surf1.movePoints(points);
surf1.write(outFileName);
Info<< "End\n" << endl;