Merge branch 'master' into cvm

This commit is contained in:
graham
2008-09-08 17:51:45 +01:00
73 changed files with 1868 additions and 340 deletions

View File

@ -1,4 +1,6 @@
EXE_INC = \
-I../rasInterFoam \
-I../interFoam \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/lnInclude \
-I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \

View File

@ -1,34 +0,0 @@
surfaceScalarField muEff
(
"muEff",
twoPhaseProperties.muf()
+ fvc::interpolate(rho*turbulence->nut())
);
fvVectorMatrix UEqn
(
fvm::ddt(rho, U)
+ fvm::div(rhoPhi, U)
- fvm::laplacian(muEff, U)
- (fvc::grad(U) & fvc::grad(muEff))
//- fvc::div(muEff*(fvc::interpolate(dev(fvc::grad(U))) & mesh.Sf()))
);
UEqn.relax();
if (momentumPredictor)
{
solve
(
UEqn
==
fvc::reconstruct
(
(
fvc::interpolate(interface.sigmaK())*fvc::snGrad(gamma)
- ghf*fvc::snGrad(rho)
- fvc::snGrad(pd)
)*mesh.magSf()
)
);
}

View File

@ -1,35 +0,0 @@
{
word gammaScheme("div(phi,gamma)");
word gammarScheme("div(phirb,gamma)");
surfaceScalarField phic = mag(phi/mesh.magSf());
phic = min(interface.cGamma()*phic, max(phic));
surfaceScalarField phir = phic*interface.nHatf();
for (int gCorr=0; gCorr<nGammaCorr; gCorr++)
{
surfaceScalarField phiGamma =
fvc::flux
(
phi,
gamma,
gammaScheme
)
+ fvc::flux
(
-fvc::flux(-phir, scalar(1) - gamma, gammarScheme),
gamma,
gammarScheme
);
MULES::explicitSolve(gamma, phi, phiGamma, 1, 0);
rhoPhi = phiGamma*(rho1 - rho2) + phi*rho2;
}
Info<< "Liquid phase volume fraction = "
<< gamma.weightedAverage(mesh.V()).value()
<< " Min(gamma) = " << min(gamma).value()
<< " Max(gamma) = " << max(gamma).value()
<< endl;
}

View File

@ -1,35 +0,0 @@
label nGammaCorr
(
readLabel(piso.lookup("nGammaCorr"))
);
label nGammaSubCycles
(
readLabel(piso.lookup("nGammaSubCycles"))
);
if (nGammaSubCycles > 1)
{
dimensionedScalar totalDeltaT = runTime.deltaT();
surfaceScalarField rhoPhiSum = 0.0*rhoPhi;
for
(
subCycle<volScalarField> gammaSubCycle(gamma, nGammaSubCycles);
!(++gammaSubCycle).end();
)
{
# include "gammaEqn.H"
rhoPhiSum += (runTime.deltaT()/totalDeltaT)*rhoPhi;
}
rhoPhi = rhoPhiSum;
}
else
{
# include "gammaEqn.H"
}
interface.correct();
rho == gamma*rho1 + (scalar(1) - gamma)*rho2;

View File

@ -41,7 +41,6 @@ Description
#include "twoPhaseMixture.H"
#include "incompressible/RASModel/RASModel.H"
#include "probes.H"
#include "EulerDdtScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -504,7 +504,7 @@ int main(int argc, char *argv[])
!bbsTargetSet[procITarget]
|| (
bbsTargetSet[procITarget]
&& bbsTarget[procITarget].intersects(bbSource)
&& bbsTarget[procITarget].overlaps(bbSource)
)
)
{
@ -533,7 +533,7 @@ int main(int argc, char *argv[])
bbsTarget[procITarget] = meshTarget.bounds();
bbsTargetSet[procITarget] = true;
if (bbsTarget[procITarget].intersects(bbSource))
if (bbsTarget[procITarget].overlaps(bbSource))
{
if (consistent)
{

View File

@ -86,28 +86,7 @@ void Foam::SortableList<Type>::sort()
indices_[i] = i;
}
Foam::sort(indices_, less(*this));
List<Type> tmpValues(this->size());
forAll(indices_, i)
{
tmpValues[i] = this->operator[](indices_[i]);
}
List<Type>::transfer(tmpValues);
}
template <class Type>
void Foam::SortableList<Type>::stableSort()
{
forAll(indices_, i)
{
indices_[i] = i;
}
//Foam::sort(indices_, less(*this));
Foam::stableSort(indices_, less(*this));
List<Type> tmpValues(this->size());

View File

@ -109,12 +109,9 @@ public:
//- Size the list. If grow can cause undefined indices (until next sort)
void setSize(const label);
//- Sort the list (if changed after construction time)
//- (stable) sort the list (if changed after construction time)
void sort();
//- Sort the list (if changed after construction time)
void stableSort();
// Member Operators

View File

@ -118,7 +118,7 @@ public:
// Query
//- Intersects other boundingbox?
bool intersects(const boundBox& bb) const
bool overlaps(const boundBox& bb) const
{
if
(

View File

@ -31,7 +31,11 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::mapDistribute::calcSchedule() const
Foam::List<Foam::labelPair> Foam::mapDistribute::schedule
(
const labelListList& subMap,
const labelListList& constructMap
)
{
// Communications: send and receive processor
List<labelPair> allComms;
@ -40,16 +44,16 @@ void Foam::mapDistribute::calcSchedule() const
HashSet<labelPair, labelPair::Hash<> > commsSet(Pstream::nProcs());
// Find what communication is required
forAll(subMap_, procI)
forAll(subMap, procI)
{
if (procI != Pstream::myProcNo())
{
if (subMap_[procI].size() > 0)
if (subMap[procI].size() > 0)
{
// I need to send to procI
commsSet.insert(labelPair(Pstream::myProcNo(), procI));
}
if (constructMap_[procI].size() > 0)
if (constructMap[procI].size() > 0)
{
// I need to receive from procI
commsSet.insert(labelPair(procI, Pstream::myProcNo()));
@ -120,13 +124,7 @@ void Foam::mapDistribute::calcSchedule() const
);
// Processors involved in my schedule
schedulePtr_.reset
(
new List<labelPair>
(
IndirectList<labelPair>(allComms, mySchedule)
)
);
return IndirectList<labelPair>(allComms, mySchedule);
//if (debug)
@ -152,6 +150,22 @@ void Foam::mapDistribute::calcSchedule() const
}
const Foam::List<Foam::labelPair>& Foam::mapDistribute::schedule() const
{
if (!schedulePtr_.valid())
{
schedulePtr_.reset
(
new List<labelPair>
(
schedule(subMap_, constructMap_)
)
);
}
return schedulePtr_();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct from components
@ -257,13 +271,4 @@ Foam::mapDistribute::mapDistribute
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -36,6 +36,8 @@ Note:
Schedule is a list of processor pairs (one send, one receive. One of
them will be myself) which forms a scheduled (i.e. non-buffered) exchange.
See distribute on how to use it.
Note2: number of items send on one processor have to equal the number
of items received on the other processor.
SourceFiles
@ -80,8 +82,6 @@ class mapDistribute
// Private Member Functions
void calcSchedule() const;
//- Disallow default bitwise copy construct
mapDistribute(const mapDistribute&);
@ -142,15 +142,15 @@ public:
return constructMap_;
}
//- Calculate a schedule. See above.
static List<labelPair> schedule
(
const labelListList& subMap,
const labelListList& constructMap
);
//- Return a schedule. Demand driven. See above.
const List<labelPair>& schedule() const
{
if (!schedulePtr_.valid())
{
calcSchedule();
}
return schedulePtr_();
}
const List<labelPair>& schedule() const;
// Other

View File

@ -48,15 +48,28 @@ void Foam::mapDistribute::distribute
// Send sub field to neighbour
for (label domain = 0; domain < Pstream::nProcs(); domain++)
{
if (domain != Pstream::myProcNo())
const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size() > 0)
{
List<T> subField(map.size());
forAll(map, i)
{
subField[i] = field[map[i]];
}
OPstream toNbr(Pstream::blocking, domain);
toNbr << IndirectList<T>(field, subMap[domain])();
toNbr << subField;
}
}
// Subset myself
List<T> subField(IndirectList<T>(field, subMap[Pstream::myProcNo()]));
const labelList& mySubMap = subMap[Pstream::myProcNo()];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
{
subField[i] = field[mySubMap[i]];
}
// Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()];
@ -71,7 +84,11 @@ void Foam::mapDistribute::distribute
// Receive sub field from neighbour
for (label domain = 0; domain < Pstream::nProcs(); domain++)
{
if (domain != Pstream::myProcNo())
if
(
domain != Pstream::myProcNo()
&& constructMap[domain].size() > 0
)
{
IPstream fromNbr(Pstream::blocking, domain);
List<T> subField(fromNbr);
@ -93,7 +110,13 @@ void Foam::mapDistribute::distribute
List<T> newField(constructSize);
// Subset myself
List<T> subField(IndirectList<T>(field, subMap[Pstream::myProcNo()]));
const labelList& mySubMap = subMap[Pstream::myProcNo()];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
{
subField[i] = field[mySubMap[i]];
}
// Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()];
@ -112,8 +135,16 @@ void Foam::mapDistribute::distribute
if (Pstream::myProcNo() == sendProc)
{
// I am sender. Send to recvProc.
const labelList& map = subMap[recvProc];
List<T> subField(map.size());
forAll(map, i)
{
subField[i] = field[map[i]];
}
OPstream toNbr(Pstream::scheduled, recvProc);
toNbr << IndirectList<T>(field, subMap[recvProc])();
toNbr << subField;
}
else
{
@ -136,7 +167,13 @@ void Foam::mapDistribute::distribute
List<T> newField(constructSize);
// Subset myself
List<T> subField(IndirectList<T>(field, subMap[Pstream::myProcNo()]));
const labelList& mySubMap = subMap[Pstream::myProcNo()];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
{
subField[i] = field[mySubMap[i]];
}
// Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()];
@ -149,10 +186,19 @@ void Foam::mapDistribute::distribute
// Send sub field to neighbour
for (label domain = 0; domain < Pstream::nProcs(); domain++)
{
if (domain != Pstream::myProcNo())
const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size() > 0)
{
List<T> subField(map.size());
forAll(map, i)
{
subField[i] = field[map[i]];
}
OPstream toNbr(Pstream::nonBlocking, domain);
toNbr << IndirectList<T>(field, subMap[domain])();
toNbr << subField;
}
}
@ -160,13 +206,13 @@ void Foam::mapDistribute::distribute
// Receive sub field from neighbour
for (label domain = 0; domain < Pstream::nProcs(); domain++)
{
if (domain != Pstream::myProcNo())
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size() > 0)
{
IPstream fromNbr(Pstream::nonBlocking, domain);
List<T> subField(fromNbr);
const labelList& map = constructMap[domain];
forAll(map, i)
{
newField[map[i]] = subField[i];

View File

@ -25,7 +25,6 @@ License
\*---------------------------------------------------------------------------*/
#include "coupledPolyPatch.H"
#include "SortableList.H"
#include "ListOps.H"
#include "transform.H"
#include "OFstream.H"

View File

@ -68,6 +68,42 @@ PrimitivePatch<Face, FaceList, PointField, PointType>::PrimitivePatch
{}
// Construct from components
template
<
class Face,
template<class> class FaceList,
class PointField,
class PointType
>
PrimitivePatch<Face, FaceList, PointField, PointType>::PrimitivePatch
(
FaceList<Face>& faces,
Field<PointType>& points,
const bool reUse
)
:
FaceList<Face>(faces, reUse),
points_(points, reUse),
edgesPtr_(NULL),
nInternalEdges_(-1),
boundaryPointsPtr_(NULL),
faceFacesPtr_(NULL),
edgeFacesPtr_(NULL),
faceEdgesPtr_(NULL),
pointEdgesPtr_(NULL),
pointFacesPtr_(NULL),
localFacesPtr_(NULL),
meshPointsPtr_(NULL),
meshPointMapPtr_(NULL),
edgeLoopsPtr_(NULL),
localPointsPtr_(NULL),
localPointOrderPtr_(NULL),
faceNormalsPtr_(NULL),
pointNormalsPtr_(NULL)
{}
// Construct as copy
template
<

View File

@ -235,6 +235,14 @@ public:
const Field<PointType>& points
);
//- Construct from components, reuse storage
PrimitivePatch
(
FaceList<Face>& faces,
Field<PointType>& points,
const bool reUse
);
//- Construct as copy
PrimitivePatch
(

View File

@ -467,7 +467,8 @@ const edgeList& primitiveMesh::edges() const
{
if (!edgesPtr_)
{
calcEdges(true);
//calcEdges(true);
calcEdges(false);
}
return *edgesPtr_;
@ -477,10 +478,8 @@ const labelListList& primitiveMesh::pointEdges() const
{
if (!pePtr_)
{
//// Invert edges
//pePtr_ = new labelListList(nPoints());
//invertManyToMany(nPoints(), edges(), *pePtr_);
calcEdges(true);
//calcEdges(true);
calcEdges(false);
}
return *pePtr_;
@ -491,12 +490,53 @@ const labelListList& primitiveMesh::faceEdges() const
{
if (!fePtr_)
{
calcEdges(true);
if (debug)
{
Pout<< "primitiveMesh::faceEdges() : "
<< "calculating faceEdges" << endl;
}
//calcEdges(true);
const faceList& fcs = faces();
const labelListList& pe = pointEdges();
const edgeList& es = edges();
fePtr_ = new labelListList(fcs.size());
labelListList& faceEdges = *fePtr_;
forAll(fcs, faceI)
{
const face& f = fcs[faceI];
labelList& fEdges = faceEdges[faceI];
fEdges.setSize(f.size());
forAll(f, fp)
{
label pointI = f[fp];
label nextPointI = f[f.fcIndex(fp)];
// Find edge between pointI, nextPontI
const labelList& pEdges = pe[pointI];
forAll(pEdges, i)
{
label edgeI = pEdges[i];
if (es[edgeI].otherVertex(pointI) == nextPointI)
{
fEdges[fp] = edgeI;
break;
}
}
}
}
}
return *fePtr_;
}
void primitiveMesh::clearOutEdges()
{
deleteDemandDrivenData(edgesPtr_);

View File

@ -41,8 +41,7 @@ extern "C"
# include "parmetis.h"
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
@ -57,6 +56,8 @@ namespace Foam
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
//- Does prevention of 0 cell domains and calls parmetis.
Foam::label Foam::parMetisDecomp::decompose
(
@ -76,6 +77,16 @@ Foam::label Foam::parMetisDecomp::decompose
// Number of dimensions
int nDims = 3;
if (cellCentres.size() != xadj.size()-1)
{
FatalErrorIn("parMetisDecomp::decompose(..)")
<< "cellCentres:" << cellCentres.size()
<< " xadj:" << xadj.size()
<< abort(FatalError);
}
// Get number of cells on all processors
List<int> nLocalCells(Pstream::nProcs());
nLocalCells[Pstream::myProcNo()] = xadj.size()-1;
@ -106,12 +117,12 @@ Foam::label Foam::parMetisDecomp::decompose
// Make sure every domain has at least one cell
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (Metis falls over with zero sized domains)
// Trickle cells from processors that have them down to those that
// Trickle cells from processors that have them up to those that
// don't.
// Number of cells to send down (is same as number of cells next processor
// has to receive)
// Number of cells to send to the next processor
// (is same as number of cells next processor has to receive)
List<int> nSendCells(Pstream::nProcs(), 0);
for (label procI = nLocalCells.size()-1; procI >=1; procI--)
@ -135,6 +146,15 @@ Foam::label Foam::parMetisDecomp::decompose
Field<int> prevCellWeights(fromPrevProc);
Field<int> prevFaceWeights(fromPrevProc);
if (prevXadj.size() != nSendCells[Pstream::myProcNo()-1])
{
FatalErrorIn("parMetisDecomp::decompose(..)")
<< "Expected from processor " << Pstream::myProcNo()-1
<< " connectivity for " << nSendCells[Pstream::myProcNo()-1]
<< " nCells but only received " << prevXadj.size()
<< abort(FatalError);
}
// Insert adjncy
prepend(prevAdjncy, adjncy);
// Adapt offsets and prepend xadj
@ -222,6 +242,14 @@ Foam::label Foam::parMetisDecomp::decompose
}
if (nLocalCells[Pstream::myProcNo()] != (xadj.size()-1))
{
FatalErrorIn("parMetisDecomp::decompose(..)")
<< "Have connectivity for " << xadj.size()-1
<< " cells but nLocalCells:" << nLocalCells[Pstream::myProcNo()]
<< abort(FatalError);
}
// Weight info
int wgtFlag = 0;
int* vwgtPtr = NULL;
@ -292,6 +320,15 @@ Foam::label Foam::parMetisDecomp::decompose
List<int> nextFinalDecomp(fromNextProc);
if (nextFinalDecomp.size() != nSendCells[Pstream::myProcNo()])
{
FatalErrorIn("parMetisDecomp::decompose(..)")
<< "Expected from processor " << Pstream::myProcNo()+1
<< " decomposition for " << nSendCells[Pstream::myProcNo()]
<< " nCells but only received " << nextFinalDecomp.size()
<< abort(FatalError);
}
append(nextFinalDecomp, finalDecomp);
}

View File

@ -24,7 +24,6 @@ License
\*---------------------------------------------------------------------------*/
#include "SortableList.H"
#include "dynamicRefineFvMesh.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
@ -32,7 +31,6 @@ License
#include "surfaceFields.H"
#include "fvCFD.H"
#include "syncTools.H"
#include "ListListOps.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -399,7 +399,7 @@ bool Foam::octreeDataFaceList::overlaps
const treeBoundBox& sampleBb
) const
{
return sampleBb.intersects(allBb_[index]);
return sampleBb.overlaps(allBb_[index]);
}

View File

@ -32,7 +32,6 @@ License
#include "octreeDataFace.H"
#include "octree.H"
#include "OFstream.H"
#include "SortableList.H"
#include "IndirectList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

View File

@ -84,6 +84,7 @@ $(derivedFvPatchFields)/oscillatingFixedValue/oscillatingFixedValueFvPatchFields
$(derivedFvPatchFields)/outletInlet/outletInletFvPatchFields.C
$(derivedFvPatchFields)/partialSlip/partialSlipFvPatchFields.C
$(derivedFvPatchFields)/pressureDirectedInletOutletVelocity/pressureDirectedInletOutletVelocityFvPatchVectorField.C
$(derivedFvPatchFields)/pressureNormalInletOutletVelocity/pressureNormalInletOutletVelocityFvPatchVectorField.C
$(derivedFvPatchFields)/pressureDirectedInletVelocity/pressureDirectedInletVelocityFvPatchVectorField.C
$(derivedFvPatchFields)/pressureInletOutletVelocity/pressureInletOutletVelocityFvPatchVectorField.C
$(derivedFvPatchFields)/pressureInletUniformVelocity/pressureInletUniformVelocityFvPatchVectorField.C

View File

@ -74,20 +74,10 @@ fluxCorrectedVelocityFvPatchVectorField
)
:
zeroGradientFvPatchVectorField(p, iF),
phiName_("phi"),
rhoName_("rho")
phiName_(dict.lookupOrDefault<word>("phi", "phi")),
rhoName_(dict.lookupOrDefault<word>("rho", "rho"))
{
fvPatchVectorField::operator=(patchInternalField());
if (dict.found("phi"))
{
dict.lookup("phi") >> phiName_;
}
if (dict.found("rho"))
{
dict.lookup("rho") >> rhoName_;
}
}
@ -118,10 +108,8 @@ void fluxCorrectedVelocityFvPatchVectorField::evaluate
zeroGradientFvPatchVectorField::evaluate();
const surfaceScalarField& phi = db().lookupObject<surfaceScalarField>
(
phiName_
);
const surfaceScalarField& phi =
db().lookupObject<surfaceScalarField>(phiName_);
const fvsPatchField<scalar>& phip =
patch().patchField<surfaceScalarField, scalar>(phi);

View File

@ -26,7 +26,10 @@ Class
Foam::fluxCorrectedVelocityFvPatchVectorField
Description
Foam::fluxCorrectedVelocityFvPatchVectorField
Velocity outlet boundary condition for patches where the pressure is
specified. The outflow velocity is obtained by "zeroGradient" and then
corrected from the flux. If reverse flow is possible or expected use
the "pressureInletOutletVelocityFvPatchVectorField" BC instead.
SourceFiles
fluxCorrectedVelocityFvPatchVectorField.C

View File

@ -158,6 +158,22 @@ void inletOutletFvPatchField<Type>::write(Ostream& os) const
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
void inletOutletFvPatchField<Type>::operator=
(
const fvPatchField<Type>& ptf
)
{
fvPatchField<Type>::operator=
(
this->valueFraction()*this->refValue()
+ (1 - this->valueFraction())*ptf
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -134,6 +134,11 @@ public:
//- Write
virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const fvPatchField<Type>& pvf);
};

View File

@ -45,6 +45,8 @@ pressureDirectedInletOutletVelocityFvPatchVectorField
)
:
mixedFvPatchVectorField(p, iF),
phiName_("phi"),
rhoName_("rho"),
inletDir_(p.size())
{
refValue() = *this;
@ -63,6 +65,8 @@ pressureDirectedInletOutletVelocityFvPatchVectorField
)
:
mixedFvPatchVectorField(ptf, p, iF, mapper),
phiName_(ptf.phiName_),
rhoName_(ptf.rhoName_),
inletDir_(ptf.inletDir_, mapper)
{}
@ -76,6 +80,8 @@ pressureDirectedInletOutletVelocityFvPatchVectorField
)
:
mixedFvPatchVectorField(p, iF),
phiName_(dict.lookupOrDefault<word>("phi", "phi")),
rhoName_(dict.lookupOrDefault<word>("rho", "rho")),
inletDir_("inletDirection", dict, p.size())
{
fvPatchVectorField::operator=(vectorField("value", dict, p.size()));
@ -92,6 +98,8 @@ pressureDirectedInletOutletVelocityFvPatchVectorField
)
:
mixedFvPatchVectorField(pivpvf),
phiName_(pivpvf.phiName_),
rhoName_(pivpvf.rhoName_),
inletDir_(pivpvf.inletDir_)
{}
@ -104,6 +112,8 @@ pressureDirectedInletOutletVelocityFvPatchVectorField
)
:
mixedFvPatchVectorField(pivpvf, iF),
phiName_(pivpvf.phiName_),
rhoName_(pivpvf.rhoName_),
inletDir_(pivpvf.inletDir_)
{}
@ -129,7 +139,8 @@ void pressureDirectedInletOutletVelocityFvPatchVectorField::rmap
mixedFvPatchVectorField::rmap(ptf, addr);
const pressureDirectedInletOutletVelocityFvPatchVectorField& tiptf =
refCast<const pressureDirectedInletOutletVelocityFvPatchVectorField>(ptf);
refCast<const pressureDirectedInletOutletVelocityFvPatchVectorField>
(ptf);
inletDir_.rmap(tiptf.inletDir_, addr);
}
@ -143,7 +154,7 @@ void pressureDirectedInletOutletVelocityFvPatchVectorField::updateCoeffs()
}
const surfaceScalarField& phi =
db().lookupObject<surfaceScalarField>("phi");
db().lookupObject<surfaceScalarField>(phiName_);
const fvsPatchField<scalar>& phip =
patch().patchField<surfaceScalarField, scalar>(phi);
@ -158,7 +169,7 @@ void pressureDirectedInletOutletVelocityFvPatchVectorField::updateCoeffs()
else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
{
const fvPatchField<scalar>& rhop =
patch().lookupPatchField<volScalarField, scalar>("rho");
patch().lookupPatchField<volScalarField, scalar>(rhoName_);
refValue() = inletDir_*phip/(rhop*ndmagS);
}
@ -185,11 +196,28 @@ void pressureDirectedInletOutletVelocityFvPatchVectorField::
write(Ostream& os) const
{
fvPatchVectorField::write(os);
os.writeKeyword("phi") << phiName_ << token::END_STATEMENT << nl;
os.writeKeyword("rho") << rhoName_ << token::END_STATEMENT << nl;
inletDir_.writeEntry("inletDirection", os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void pressureDirectedInletOutletVelocityFvPatchVectorField::operator=
(
const fvPatchField<vector>& pvf
)
{
fvPatchField<vector>::operator=
(
valueFraction()*(inletDir_*(inletDir_ & pvf))
+ (1 - valueFraction())*pvf
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField

View File

@ -26,7 +26,10 @@ Class
Foam::pressureDirectedInletOutletVelocityFvPatchVectorField
Description
Foam::pressureDirectedInletOutletVelocityFvPatchVectorField
Velocity inlet/outlet boundary condition for pressure boundary where the
pressure is specified. zero-gradient is applied for outflow (as defined
by the flux) and for inflow the velocity is obtained from the flux with
the specified `inletDirection'.
SourceFiles
pressureDirectedInletOutletVelocityFvPatchVectorField.C
@ -54,6 +57,8 @@ class pressureDirectedInletOutletVelocityFvPatchVectorField
{
// Private data
word phiName_;
word rhoName_;
vectorField inletDir_;
@ -133,9 +138,35 @@ public:
}
// Member functions
// Access
//- Return the name of rho
const word& rhoName() const
{
return rhoName_;
}
//- Return reference to the name of rho to allow adjustment
word& rhoName()
{
return rhoName_;
}
//- Return the name of phi
const word& phiName() const
{
return phiName_;
}
//- Return reference to the name of phi to allow adjustment
word& phiName()
{
return phiName_;
}
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
@ -157,6 +188,11 @@ public:
//- Write
virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const fvPatchField<vector>& pvf);
};

View File

@ -45,6 +45,8 @@ pressureDirectedInletVelocityFvPatchVectorField
)
:
fixedValueFvPatchVectorField(p, iF),
phiName_("phi"),
rhoName_("rho"),
inletDir_(p.size())
{}
@ -59,6 +61,8 @@ pressureDirectedInletVelocityFvPatchVectorField
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
phiName_(ptf.phiName_),
rhoName_(ptf.rhoName_),
inletDir_(ptf.inletDir_, mapper)
{}
@ -72,6 +76,8 @@ pressureDirectedInletVelocityFvPatchVectorField
)
:
fixedValueFvPatchVectorField(p, iF),
phiName_(dict.lookupOrDefault<word>("phi", "phi")),
rhoName_(dict.lookupOrDefault<word>("rho", "rho")),
inletDir_("inletDirection", dict, p.size())
{
fvPatchVectorField::operator=(vectorField("value", dict, p.size()));
@ -85,6 +91,8 @@ pressureDirectedInletVelocityFvPatchVectorField
)
:
fixedValueFvPatchVectorField(pivpvf),
phiName_(pivpvf.phiName_),
rhoName_(pivpvf.rhoName_),
inletDir_(pivpvf.inletDir_)
{}
@ -97,6 +105,8 @@ pressureDirectedInletVelocityFvPatchVectorField
)
:
fixedValueFvPatchVectorField(pivpvf, iF),
phiName_(pivpvf.phiName_),
rhoName_(pivpvf.rhoName_),
inletDir_(pivpvf.inletDir_)
{}
@ -136,7 +146,7 @@ void pressureDirectedInletVelocityFvPatchVectorField::updateCoeffs()
}
const surfaceScalarField& phi =
db().lookupObject<surfaceScalarField>("phi");
db().lookupObject<surfaceScalarField>(phiName_);
const fvsPatchField<scalar>& phip =
patch().patchField<surfaceScalarField, scalar>(phi);
@ -151,7 +161,7 @@ void pressureDirectedInletVelocityFvPatchVectorField::updateCoeffs()
else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
{
const fvPatchField<scalar>& rhop =
patch().lookupPatchField<volScalarField, scalar>("rho");
patch().lookupPatchField<volScalarField, scalar>(rhoName_);
operator==(inletDir_*phip/(rhop*ndmagS));
}
@ -174,11 +184,24 @@ void pressureDirectedInletVelocityFvPatchVectorField::updateCoeffs()
void pressureDirectedInletVelocityFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
os.writeKeyword("phi") << phiName_ << token::END_STATEMENT << nl;
os.writeKeyword("rho") << rhoName_ << token::END_STATEMENT << nl;
inletDir_.writeEntry("inletDirection", os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void pressureDirectedInletVelocityFvPatchVectorField::operator=
(
const fvPatchField<vector>& pvf
)
{
fvPatchField<vector>::operator=(inletDir_*(inletDir_ & pvf));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField

View File

@ -23,10 +23,14 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::pressureDirectedInletVelocityFvPatchVectorField
Foam::pressureDirectedInletVelocityFvPatchVectorField
Description
Foam::pressureDirectedInletOutletVelocityFvPatchVectorField
Velocity inlet boundary condition for patches where the pressure is
specified. The inflow velocity is obtained from the flux with the
specified "inletDirection" direction. If reverse flow is possible or
expected use the "pressureDirectedInletOutletVelocityFvPatchVectorField"
BC instead.
SourceFiles
pressureDirectedInletVelocityFvPatchVectorField.C
@ -54,6 +58,8 @@ class pressureDirectedInletVelocityFvPatchVectorField
{
// Private data
word phiName_;
word rhoName_;
vectorField inletDir_;
@ -130,9 +136,35 @@ public:
}
// Member functions
// Access
//- Return the name of rho
const word& rhoName() const
{
return rhoName_;
}
//- Return reference to the name of rho to allow adjustment
word& rhoName()
{
return rhoName_;
}
//- Return the name of phi
const word& phiName() const
{
return phiName_;
}
//- Return reference to the name of phi to allow adjustment
word& phiName()
{
return phiName_;
}
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
@ -154,6 +186,11 @@ public:
//- Write
virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const fvPatchField<vector>& pvf);
};

View File

@ -26,7 +26,10 @@ Class
Foam::pressureInletOutletVelocityFvPatchVectorField
Description
Foam::pressureInletOutletVelocityFvPatchVectorField
Velocity inlet/outlet boundary condition patches for where the pressure is
specified. zero-gradient is applied for outflow (as defined by the flux)
and for inflow the velocity is obtained from the patch-face normal
component of the internal-cell value.
SourceFiles
pressureInletOutletVelocityFvPatchVectorField.C

View File

@ -108,6 +108,17 @@ void pressureInletUniformVelocityFvPatchVectorField::updateCoeffs()
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void pressureInletUniformVelocityFvPatchVectorField::operator=
(
const fvPatchField<vector>& pvf
)
{
operator==(patch().nf()*sum(patch().Sf() & pvf)/sum(patch().magSf()));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField

View File

@ -26,7 +26,9 @@ Class
Foam::pressureInletUniformVelocityFvPatchVectorField
Description
Foam::pressureInletUniformVelocityFvPatchVectorField
Velocity inlet boundary condition for patches where the pressure is
specified. The uniform inflow velocity is obtained by averaging the flux
over the patch and apply it in the direction normal to the patch faces.
SourceFiles
pressureInletUniformVelocityFvPatchVectorField.C
@ -124,6 +126,11 @@ public:
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
// Member operators
virtual void operator=(const fvPatchField<vector>& pvf);
};

View File

@ -70,20 +70,10 @@ pressureInletVelocityFvPatchVectorField::pressureInletVelocityFvPatchVectorField
)
:
fixedValueFvPatchVectorField(p, iF),
phiName_("phi"),
rhoName_("rho")
phiName_(dict.lookupOrDefault<word>("phi", "phi")),
rhoName_(dict.lookupOrDefault<word>("rho", "rho"))
{
fvPatchVectorField::operator=(vectorField("value", dict, p.size()));
if (dict.found("phi"))
{
dict.lookup("phi") >> phiName_;
}
if (dict.found("rho"))
{
dict.lookup("rho") >> rhoName_;
}
}
@ -164,6 +154,17 @@ void pressureInletVelocityFvPatchVectorField::write(Ostream& os) const
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void pressureInletVelocityFvPatchVectorField::operator=
(
const fvPatchField<vector>& pvf
)
{
fvPatchField<vector>::operator=(patch().nf()*(patch().nf() & pvf));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField

View File

@ -26,7 +26,10 @@ Class
Foam::pressureInletVelocityFvPatchVectorField
Description
Foam::pressureInletVelocityFvPatchVectorField
Velocity inlet boundary condition for patches where the pressure is
specified. The inflow velocity is obtained from the flux with a direction
normal to the patch faces. If reverse flow is possible or expected use
the "pressureInletOutletVelocityFvPatchVectorField" BC instead.
SourceFiles
pressureInletVelocityFvPatchVectorField.C
@ -57,6 +60,7 @@ class pressureInletVelocityFvPatchVectorField
word phiName_;
word rhoName_;
public:
//- Runtime type information
@ -127,6 +131,33 @@ public:
// Member functions
// Access
//- Return the name of rho
const word& rhoName() const
{
return rhoName_;
}
//- Return reference to the name of rho to allow adjustment
word& rhoName()
{
return rhoName_;
}
//- Return the name of phi
const word& phiName() const
{
return phiName_;
}
//- Return reference to the name of phi to allow adjustment
word& phiName()
{
return phiName_;
}
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
@ -136,10 +167,7 @@ public:
// Member operators
virtual void operator=(const fvPatchField<vector>& pvf)
{
fvPatchField<vector>::operator=(pvf);
}
virtual void operator=(const fvPatchField<vector>& pvf);
};

View File

@ -0,0 +1,201 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 "pressureNormalInletOutletVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
pressureNormalInletOutletVelocityFvPatchVectorField::
pressureNormalInletOutletVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
mixedFvPatchVectorField(p, iF),
phiName_("phi"),
rhoName_("rho")
{
refValue() = *this;
refGrad() = vector::zero;
valueFraction() = 0.0;
}
pressureNormalInletOutletVelocityFvPatchVectorField::
pressureNormalInletOutletVelocityFvPatchVectorField
(
const pressureNormalInletOutletVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchVectorField(ptf, p, iF, mapper),
phiName_(ptf.phiName_),
rhoName_(ptf.rhoName_)
{}
pressureNormalInletOutletVelocityFvPatchVectorField::
pressureNormalInletOutletVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchVectorField(p, iF),
phiName_(dict.lookupOrDefault<word>("phi", "phi")),
rhoName_(dict.lookupOrDefault<word>("rho", "rho"))
{
fvPatchVectorField::operator=(vectorField("value", dict, p.size()));
refValue() = *this;
refGrad() = vector::zero;
valueFraction() = 0.0;
}
pressureNormalInletOutletVelocityFvPatchVectorField::
pressureNormalInletOutletVelocityFvPatchVectorField
(
const pressureNormalInletOutletVelocityFvPatchVectorField& pivpvf
)
:
mixedFvPatchVectorField(pivpvf),
phiName_(pivpvf.phiName_),
rhoName_(pivpvf.rhoName_)
{}
pressureNormalInletOutletVelocityFvPatchVectorField::
pressureNormalInletOutletVelocityFvPatchVectorField
(
const pressureNormalInletOutletVelocityFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
mixedFvPatchVectorField(pivpvf, iF),
phiName_(pivpvf.phiName_),
rhoName_(pivpvf.rhoName_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void pressureNormalInletOutletVelocityFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
const surfaceScalarField& phi =
db().lookupObject<surfaceScalarField>(phiName_);
const fvsPatchField<scalar>& phip =
patch().patchField<surfaceScalarField, scalar>(phi);
vectorField n = patch().nf();
const Field<scalar>& magS = patch().magSf();
if (phi.dimensions() == dimVelocity*dimArea)
{
refValue() = n*phip/magS;
}
else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
{
const fvPatchField<scalar>& rhop =
patch().lookupPatchField<volScalarField, scalar>(rhoName_);
refValue() = n*phip/(rhop*magS);
}
else
{
FatalErrorIn
(
"pressureNormalInletOutletVelocityFvPatchVectorField::"
"updateCoeffs()"
) << "dimensions of phi are not correct"
<< "\n on patch " << this->patch().name()
<< " of field " << this->dimensionedInternalField().name()
<< " in file " << this->dimensionedInternalField().objectPath()
<< exit(FatalError);
}
valueFraction() = 1.0 - pos(phip);
mixedFvPatchVectorField::updateCoeffs();
}
void pressureNormalInletOutletVelocityFvPatchVectorField::
write(Ostream& os) const
{
fvPatchVectorField::write(os);
os.writeKeyword("phi") << phiName_ << token::END_STATEMENT << nl;
os.writeKeyword("rho") << rhoName_ << token::END_STATEMENT << nl;
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void pressureNormalInletOutletVelocityFvPatchVectorField::operator=
(
const fvPatchField<vector>& pvf
)
{
fvPatchField<vector>::operator=
(
valueFraction()*(patch().nf()*(patch().nf() & pvf))
+ (1 - valueFraction())*pvf
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchVectorField,
pressureNormalInletOutletVelocityFvPatchVectorField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,191 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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
Foam::pressureNormalInletOutletVelocityFvPatchVectorField
Description
Velocity inlet/outlet boundary condition for patches where the pressure is
specified. zero-gradient is applied for outflow (as defined by the flux)
and for inflow the velocity is obtained from the flux with a direction
normal to the patch faces.
SourceFiles
pressureNormalInletOutletVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef pressureNormalInletOutletVelocityFvPatchVectorField_H
#define pressureNormalInletOutletVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "mixedFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class pressureNormalInletOutletVelocityFvPatch Declaration
\*---------------------------------------------------------------------------*/
class pressureNormalInletOutletVelocityFvPatchVectorField
:
public mixedFvPatchVectorField
{
// Private data
word phiName_;
word rhoName_;
public:
//- Runtime type information
TypeName("pressureNormalInletOutletVelocity");
// Constructors
//- Construct from patch and internal field
pressureNormalInletOutletVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
pressureNormalInletOutletVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// pressureNormalInletOutletVelocityFvPatchVectorField
// onto a new patch
pressureNormalInletOutletVelocityFvPatchVectorField
(
const pressureNormalInletOutletVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
pressureNormalInletOutletVelocityFvPatchVectorField
(
const pressureNormalInletOutletVelocityFvPatchVectorField&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new pressureNormalInletOutletVelocityFvPatchVectorField
(
*this
)
);
}
//- Construct as copy setting internal field reference
pressureNormalInletOutletVelocityFvPatchVectorField
(
const pressureNormalInletOutletVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new pressureNormalInletOutletVelocityFvPatchVectorField
(
*this,
iF
)
);
}
// Member functions
// Access
//- Return the name of rho
const word& rhoName() const
{
return rhoName_;
}
//- Return reference to the name of rho to allow adjustment
word& rhoName()
{
return rhoName_;
}
//- Return the name of phi
const word& phiName() const
{
return phiName_;
}
//- Return reference to the name of phi to allow adjustment
word& phiName()
{
return phiName_;
}
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const fvPatchField<vector>& pvf);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -26,7 +26,10 @@ Class
Foam::rotatingPressureInletOutletVelocityFvPatchVectorField
Description
Foam::rotatingPressureInletOutletVelocityFvPatchVectorField
Velocity inlet/outlet boundary condition in a rotating frame
for patches where the pressure is specified. zero-gradient is applied for
outflow (as defined by the flux) and for inflow the velocity is obtained
from the flux with a direction normal to the patch faces.
SourceFiles
rotatingPressureInletOutletVelocityFvPatchVectorField.C

View File

@ -22,8 +22,6 @@ License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
\*---------------------------------------------------------------------------*/
#include "gaussConvectionScheme.H"

View File

@ -978,14 +978,14 @@ CrankNicholsonDdtScheme<Type>::fvcDdtPhiCorr
ddt0_<GeometricField<Type, fvPatchField, volMesh> >
(
"ddt0(" + U.name() + ')',
rho.dimensions()*U.dimensions()
U.dimensions()
);
DDt0Field<fluxFieldType>& dphidt0 =
ddt0_<fluxFieldType>
(
"ddt0(" + phi.name() + ')',
phi.dimensions()
U.dimensions()*dimArea
);
IOobject ddtIOobject

View File

@ -29,6 +29,8 @@ License
#include "ListListOps.H"
#include "meshSearch.H"
#include "mapDistribute.H"
#include "meshTools.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -47,16 +49,18 @@ void Foam::directMappedPolyPatch::collectSamples
(
pointField& samples,
labelList& patchFaceProcs,
labelList& patchFaces
labelList& patchFaces,
pointField& patchFc
) const
{
const vectorField::subField fc = this->faceCentres();
// Collect all sample points and the faces they come from.
List<pointField> globalFc(Pstream::nProcs());
List<pointField> globalSamples(Pstream::nProcs());
labelListList globalFaces(Pstream::nProcs());
globalSamples[Pstream::myProcNo()] = fc+offset_;
globalFc[Pstream::myProcNo()] = this->faceCentres();
globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offset_;
globalFaces[Pstream::myProcNo()] = identity(size());
// Distribute to all processors
@ -64,6 +68,8 @@ void Foam::directMappedPolyPatch::collectSamples
Pstream::scatterList(globalSamples);
Pstream::gatherList(globalFaces);
Pstream::scatterList(globalFaces);
Pstream::gatherList(globalFc);
Pstream::scatterList(globalFc);
// Rework into straight list
samples = ListListOps::combine<pointField>
@ -76,6 +82,11 @@ void Foam::directMappedPolyPatch::collectSamples
globalFaces,
accessOp<labelList>()
);
patchFc = ListListOps::combine<pointField>
(
globalFc,
accessOp<pointField>()
);
patchFaceProcs.setSize(patchFaces.size());
labelList nPerProc
@ -103,11 +114,14 @@ void Foam::directMappedPolyPatch::findSamples
(
const pointField& samples,
labelList& sampleCellProcs,
labelList& sampleCells
labelList& sampleCells,
pointField& sampleCc
) const
{
sampleCellProcs.setSize(samples.size());
sampleCells.setSize(samples.size());
sampleCc.setSize(samples.size());
sampleCc = point(-GREAT, -GREAT, -GREAT);
{
// Octree based search engine
@ -124,6 +138,8 @@ void Foam::directMappedPolyPatch::findSamples
else
{
sampleCellProcs[sampleI] = Pstream::myProcNo();
sampleCc[sampleI] =
boundaryMesh().mesh().cellCentres()[sampleCells[sampleI]];
}
}
}
@ -136,6 +152,9 @@ void Foam::directMappedPolyPatch::findSamples
Pstream::listCombineGather(sampleCellProcs, maxEqOp<label>());
Pstream::listCombineScatter(sampleCellProcs);
Pstream::listCombineGather(sampleCc, maxEqOp<point>());
Pstream::listCombineScatter(sampleCc);
if (debug)
{
Info<< "directMappedPolyPatch::findSamples : " << endl;
@ -143,7 +162,8 @@ void Foam::directMappedPolyPatch::findSamples
{
Info<< " " << sampleI << " coord:" << samples[sampleI]
<< " found on processor:" << sampleCellProcs[sampleI]
<< " in cell:" << sampleCells[sampleI] << endl;
<< " in cell:" << sampleCells[sampleI]
<< " with cc:" << sampleCc[sampleI] << endl;
}
}
@ -213,12 +233,14 @@ void Foam::directMappedPolyPatch::calcMapping() const
pointField samples;
labelList patchFaceProcs;
labelList patchFaces;
collectSamples(samples, patchFaceProcs, patchFaces);
pointField patchFc;
collectSamples(samples, patchFaceProcs, patchFaces, patchFc);
// Find processor and cell samples are in
labelList sampleCellProcs;
labelList sampleCells;
findSamples(samples, sampleCellProcs, sampleCells);
pointField sampleCc;
findSamples(samples, sampleCellProcs, sampleCells, sampleCc);
// Now we have all the data we need:
@ -227,6 +249,60 @@ void Foam::directMappedPolyPatch::calcMapping() const
// - cell sample is in (so source when mapping)
// sampleCells, sampleCellProcs.
if (debug && Pstream::master())
{
OFstream str
(
boundaryMesh().mesh().time().path()
/ name()
+ "_directMapped.obj"
);
Pout<< "Dumping mapping as lines from patch faceCentres to"
<< " sampled cellCentres to file " << str.name() << endl;
label vertI = 0;
forAll(patchFc, i)
{
meshTools::writeOBJ(str, patchFc[i]);
vertI++;
meshTools::writeOBJ(str, sampleCc[i]);
vertI++;
str << "l " << vertI-1 << ' ' << vertI << nl;
}
}
// Check that actual offset vector (sampleCc - patchFc) is more or less
// constant.
if (Pstream::master())
{
const scalarField magOffset(mag(sampleCc - patchFc));
const scalar avgOffset(average(magOffset));
forAll(magOffset, sampleI)
{
if (mag(magOffset[sampleI]-avgOffset) > 0.001*avgOffset)
{
WarningIn("directMappedPolyPatch::calcMapping() const")
<< "The actual cell centres picked up using offset "
<< offset_ << " are not" << endl
<< " on a single plane."
<< " This might give numerical problems." << endl
<< " At patchface " << patchFc[sampleI]
<< " the sampled cell " << sampleCc[sampleI] << endl
<< " is not on a plane " << avgOffset
<< " offset from the patch." << endl
<< " You might want to shift your plane offset."
<< " Set the debug flag to get a dump of sampled cells."
<< endl;
break;
}
}
}
// Determine schedule.
mapDistribute distMap(sampleCellProcs, patchFaceProcs);

View File

@ -82,7 +82,8 @@ class directMappedPolyPatch
(
pointField&,
labelList& patchFaceProcs,
labelList& patchFaces
labelList& patchFaces,
pointField& patchFc
) const;
//- Find cells containing samples
@ -90,7 +91,8 @@ class directMappedPolyPatch
(
const pointField&,
labelList& sampleCellProcs,
labelList& sampleCells
labelList& sampleCells,
pointField& sampleCc
) const;
//- Calculate matching

View File

@ -40,7 +40,7 @@ namespace Foam
// Does bb intersect a sphere around sample? Or is any corner point of bb
// closer than nearestDistSqr to sample.
template <class Type>
bool indexedOctree<Type>::intersects
bool indexedOctree<Type>::overlaps
(
const point& p0,
const point& p1,
@ -84,7 +84,7 @@ bool indexedOctree<Type>::intersects
// Does bb intersect a sphere around sample? Or is any corner point of bb
// closer than nearestDistSqr to sample.
template <class Type>
bool indexedOctree<Type>::intersects
bool indexedOctree<Type>::overlaps
(
const treeBoundBox& parentBb,
const direction octant,
@ -94,7 +94,7 @@ bool indexedOctree<Type>::intersects
{
//- Speeded up version of
// treeBoundBox subBb(parentBb.subBbox(mid, octant))
// intersects
// overlaps
// (
// subBb.min(),
// subBb.max(),
@ -136,7 +136,7 @@ bool indexedOctree<Type>::intersects
const point mid(0.5*(min+max));
return intersects(mid, other, nearestDistSqr, sample);
return overlaps(mid, other, nearestDistSqr, sample);
}
@ -567,7 +567,7 @@ void indexedOctree<Type>::findNearest
const treeBoundBox& subBb = nodes_[subNodeI].bb_;
if (intersects(subBb.min(), subBb.max(), nearestDistSqr, sample))
if (overlaps(subBb.min(), subBb.max(), nearestDistSqr, sample))
{
findNearest
(
@ -584,7 +584,7 @@ void indexedOctree<Type>::findNearest
{
if
(
intersects
overlaps
(
nod.bb_,
octant,
@ -639,7 +639,7 @@ void indexedOctree<Type>::findNearest
{
const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
if (subBb.intersects(tightest))
if (subBb.overlaps(tightest))
{
findNearest
(
@ -657,7 +657,7 @@ void indexedOctree<Type>::findNearest
{
const treeBoundBox subBb(nodeBb.subBbox(octant));
if (subBb.intersects(tightest))
if (subBb.overlaps(tightest))
{
shapes_.findNearest
(
@ -1121,7 +1121,7 @@ void indexedOctree<Type>::findBox
{
const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
if (subBb.intersects(searchBox))
if (subBb.overlaps(searchBox))
{
findBox(getNode(index), searchBox, elements);
}
@ -1130,7 +1130,7 @@ void indexedOctree<Type>::findBox
{
const treeBoundBox subBb(nodeBb.subBbox(octant));
if (subBb.intersects(searchBox))
if (subBb.overlaps(searchBox))
{
const labelList& indices = contents_[getContent(index)];

View File

@ -36,9 +36,9 @@ SourceFiles
#ifndef indexedOctree_H
#define indexedOctree_H
#include "treeBoundBox.H"
#include "pointIndexHit.H"
#include "FixedList.H"
#include "treeBoundBox.H"
#include "Ostream.H"
#include "labelHashSet.H"
#include "labelBits.H"
@ -146,7 +146,7 @@ private:
//- Like above but now bb is implicitly provided as parent bb + mid
// + octant
static bool intersects
static bool overlaps
(
const treeBoundBox& parentBb,
const direction octant,
@ -497,7 +497,7 @@ public:
//- Helper: does bb intersect a sphere around sample? Or is any
// corner point of bb closer than nearestDistSqr to sample.
static bool intersects
static bool overlaps
(
const point& bbMin,
const point& bbMax,

View File

@ -137,11 +137,11 @@ bool Foam::treeDataCell::overlaps
{
if (cacheBb_)
{
return cubeBb.intersects(bbs_[index]);
return cubeBb.overlaps(bbs_[index]);
}
else
{
return cubeBb.intersects(calcCellBb(cellLabels_[index]));
return cubeBb.overlaps(calcCellBb(cellLabels_[index]));
}
}

View File

@ -110,11 +110,11 @@ bool Foam::treeDataEdge::overlaps
{
if (cacheBb_)
{
return cubeBb.intersects(bbs_[index]);
return cubeBb.overlaps(bbs_[index]);
}
else
{
return cubeBb.intersects(calcBb(edgeLabels_[index]));
return cubeBb.overlaps(calcBb(edgeLabels_[index]));
}
}

View File

@ -412,14 +412,14 @@ bool Foam::treeDataFace::overlaps
// 1. Quick rejection: bb does not intersect face bb at all
if (cacheBb_)
{
if (!cubeBb.intersects(bbs_[index]))
if (!cubeBb.overlaps(bbs_[index]))
{
return false;
}
}
else
{
if (!cubeBb.intersects(calcBb(faceLabels_[index])))
if (!cubeBb.overlaps(calcBb(faceLabels_[index])))
{
return false;
}

View File

@ -284,13 +284,13 @@ bool Foam::treeDataTriSurface::overlaps
triBb.max() = max(triBb.max(), p2);
//- For testing: robust one
//return cubeBb.intersects(triBb);
//return cubeBb.overlaps(triBb);
//- Exact test of triangle intersecting bb
// Quick rejection. If whole bounding box of tri is outside cubeBb then
// there will be no intersection.
if (!cubeBb.intersects(triBb))
if (!cubeBb.overlaps(triBb))
{
return false;
}

View File

@ -94,6 +94,12 @@ public:
index_(-1)
{}
//- Construct from Istream
PointIndexHit(Istream& is)
{
is >> *this;
}
// Member Functions
@ -193,13 +199,45 @@ public:
friend Ostream& operator<< (Ostream& os, const PointIndexHit& pHit)
{
return os << pHit.hit_ << token::SPACE << pHit.hitPoint_
<< token::SPACE << pHit.index_;
if (os.format() == IOstream::ASCII)
{
os << pHit.hit_ << token::SPACE << pHit.hitPoint_
<< token::SPACE << pHit.index_;
}
else
{
os.write
(
reinterpret_cast<const char*>(&pHit),
sizeof(PointIndexHit)
);
}
// Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const PointIndexHit&)");
return os;
}
friend Istream& operator>>(Istream& is, PointIndexHit& pHit)
{
return is >> pHit.hit_ >> pHit.hitPoint_ >> pHit.index_;
if (is.format() == IOstream::ASCII)
{
return is >> pHit.hit_ >> pHit.hitPoint_ >> pHit.index_;
}
else
{
is.read
(
reinterpret_cast<char*>(&pHit),
sizeof(PointIndexHit)
);
}
// Check state of Istream
is.check("Istream& operator>>(Istream&, PointIndexHit&)");
return is;
}
};

View File

@ -113,7 +113,7 @@ bool Foam::octreeDataCell::overlaps
const treeBoundBox& cubeBb
) const
{
return cubeBb.intersects(bbs_[index]);
return cubeBb.overlaps(bbs_[index]);
}

View File

@ -107,7 +107,7 @@ bool Foam::octreeDataEdges::overlaps
const treeBoundBox& sampleBb
) const
{
return sampleBb.intersects(allBb_[index]);
return sampleBb.overlaps(allBb_[index]);
}

View File

@ -507,12 +507,12 @@ bool Foam::octreeDataFace::overlaps
const treeBoundBox& sampleBb
) const
{
//return sampleBb.intersects(allBb_[index]);
//return sampleBb.overlaps(allBb_[index]);
//- Exact test of face intersecting bb
// 1. Quick rejection: bb does not intersect face bb at all
if (!sampleBb.intersects(allBb_[index]))
if (!sampleBb.overlaps(allBb_[index]))
{
return false;
}

View File

@ -39,7 +39,14 @@ Description
namespace Foam
{
typedef PointIndexHit<point> pointIndexHit;
typedef PointIndexHit<point> pointIndexHit;
//- Specify data associated with pointIndexHit type is contiguous
template<>
inline bool contiguous<pointIndexHit>() {return true;}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -297,6 +297,45 @@ Foam::treeBoundBox Foam::treeBoundBox::subBbox
}
bool Foam::treeBoundBox::overlaps
(
const point& centre,
const scalar radiusSqr
) const
{
// Find out where centre is in relation to bb.
// Find nearest point on bb.
scalar distSqr = 0;
for (direction dir = 0; dir < vector::nComponents; dir++)
{
scalar d0 = min()[dir] - centre[dir];
scalar d1 = max()[dir] - centre[dir];
if ((d0 > 0) != (d1 > 0))
{
// centre inside both extrema. This component does not add any
// distance.
}
else if (Foam::mag(d0) < Foam::mag(d1))
{
distSqr += d0*d0;
}
else
{
distSqr += d1*d1;
}
if (distSqr > radiusSqr)
{
return false;
}
}
return true;
}
// line intersection. Returns true if line (start to end) inside
// bb or intersects bb. Sets pt to intersection.
//

View File

@ -263,8 +263,11 @@ public:
FixedList<direction, 8>& octantOrder
) const;
//- Intersects other boundingbox?
inline bool intersects(const treeBoundBox&) const;
//- Overlaps other boundingbox?
inline bool overlaps(const treeBoundBox&) const;
//- Overlaps boundingSphere (centre + sqr(radius))?
bool overlaps(const point&, const scalar radiusSqr) const;
//- Intersects segment; set point to intersection position,
// return true if intersection found.

View File

@ -24,9 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "treeBoundBox.H"
#include "point.H"
#include "Random.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -414,9 +412,9 @@ inline void treeBoundBox::searchOrder
// true if bb's intersect or overlap.
// Note: <= to make sure we catch all.
inline bool treeBoundBox::intersects(const treeBoundBox& bb) const
inline bool treeBoundBox::overlaps(const treeBoundBox& bb) const
{
return boundBox::intersects(bb);
return boundBox::overlaps(bb);
}

View File

@ -798,7 +798,7 @@ bool treeNode<Type>::findTightest
// Node: recurse into subnodes
const treeNode<Type>* subNodePtr = getNodePtr(octant);
if (subNodePtr->bb().intersects(tightest))
if (subNodePtr->bb().overlaps(tightest))
{
// there might be a better fit inside this subNode
changed |=
@ -815,7 +815,7 @@ bool treeNode<Type>::findTightest
// Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant);
if (subLeafPtr->bb().intersects(tightest))
if (subLeafPtr->bb().overlaps(tightest))
{
// there might be a better fit inside this subLeaf
changed |=
@ -884,7 +884,7 @@ bool treeNode<Type>::findNearest
// Node
const treeNode<Type>* subNodePtr = getNodePtr(octant);
if (subNodePtr->bb().intersects(tightest))
if (subNodePtr->bb().overlaps(tightest))
{
// there might be a better fit inside this subNode
changed |=
@ -903,7 +903,7 @@ bool treeNode<Type>::findNearest
// Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant);
if (subLeafPtr->bb().intersects(tightest))
if (subLeafPtr->bb().overlaps(tightest))
{
// there might be a better fit inside this subNode
changed |=
@ -975,7 +975,7 @@ bool treeNode<Type>::findNearest
// Node
const treeNode<Type>* subNodePtr = getNodePtr(octant);
if (subNodePtr->bb().intersects(tightest))
if (subNodePtr->bb().overlaps(tightest))
{
// there might be a better fit inside this subNode
changed |=
@ -995,7 +995,7 @@ bool treeNode<Type>::findNearest
// Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant);
if (subLeafPtr->bb().intersects(tightest))
if (subLeafPtr->bb().overlaps(tightest))
{
// there might be a better fit inside this subNode
changed |=
@ -1060,7 +1060,7 @@ bool treeNode<Type>::findBox
// Node
const treeNode<Type>* subNodePtr = getNodePtr(octant);
if (subNodePtr->bb().intersects(box))
if (subNodePtr->bb().overlaps(box))
{
// Visit sub node.
changed |= subNodePtr->findBox(shapes, box, elements);
@ -1071,7 +1071,7 @@ bool treeNode<Type>::findBox
// Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant);
if (subLeafPtr->bb().intersects(box))
if (subLeafPtr->bb().overlaps(box))
{
// Visit sub leaf.
changed |= subLeafPtr->findBox(shapes, box, elements);

View File

@ -26,7 +26,6 @@ License
#include "searchableSphere.H"
#include "addToRunTimeSelectionTable.H"
#include "SortableList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

View File

@ -27,8 +27,6 @@ License
#include "intersectedSurface.H"
#include "surfaceIntersection.H"
#include "faceList.H"
#include "SortableList.H"
#include "triSurfaceTools.H"
#include "faceTriangulation.H"
#include "treeBoundBox.H"
#include "OFstream.H"

View File

@ -385,12 +385,12 @@ bool Foam::octreeDataTriSurface::overlaps
const treeBoundBox& cubeBb
) const
{
//return cubeBb.intersects(allBb_[index]);
//return cubeBb.overlaps(allBb_[index]);
//- Exact test of triangle intersecting bb
// Quick rejection.
if (!cubeBb.intersects(allBb_[index]))
if (!cubeBb.overlaps(allBb_[index]))
{
return false;
}

View File

@ -54,7 +54,7 @@ bool Foam::treeLeaf<Foam::octreeDataTriSurface>::findNearest
label faceI = indices_[i];
// Quick rejection test.
if (tightest.intersects(allBb[faceI]))
if (tightest.overlaps(allBb[faceI]))
{
// Full calculation
scalar dist = shapes.calcNearest(faceI, sample, nearest);

View File

@ -101,6 +101,7 @@ bool Foam::triangleFuncs::intersectAxesBundle
// Since direction is coordinate axis there is no need to do projection,
// we can directly check u,v components for inclusion in triangle.
scalar localScale = max(max(magSqr(V10), magSqr(V20)), 1.0);
// Get other components
label i1 = (i0 + 1) % 3;
@ -114,8 +115,11 @@ bool Foam::triangleFuncs::intersectAxesBundle
scalar det = v2*u1 - u2*v1;
// Fix for V0:(-31.71428 0 -15.10714) V10:(-1.285715 8.99165e-16 -1.142858) V20:(0 0 -1.678573) i0:0
if (Foam::mag(det)/max(max(mag(V10),mag(V20)),1) < SMALL)
// Fix for V0:(-31.71428 0 -15.10714)
// V10:(-1.285715 8.99165e-16 -1.142858)
// V20:(0 0 -1.678573)
// i0:0
if (Foam::mag(det)/localScale < SMALL)
{
// Triangle parallel to dir
return false;
@ -132,7 +136,7 @@ bool Foam::triangleFuncs::intersectAxesBundle
scalar beta = 0;
bool inter = false;
if (Foam::mag(u1) < SMALL)
if (Foam::mag(u1)/localScale < SMALL)
{
beta = u0/u2;
if ((beta >= 0) && (beta <= 1))

View File

@ -107,18 +107,6 @@ combustionMixture::combustionMixture
);
}
}
// Error check for single component mixtures - should be uniform 1
if (Y_.size() == 1)
{
if (average(Y_[0]).value() < 0.999)
{
FatalErrorIn("combustionMixture::combustionMixture")
<< "Mass fraction for single component mixture must be unity"
<< nl << "Please correct field: " << species_[0]
<< " (Ydefault)" << nl << abort(FatalError);
}
}
}

View File

@ -31,6 +31,7 @@ License
#include "Time.H"
#include "boundBox.H"
#include "SortableList.H"
#include "PackedList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -626,7 +627,7 @@ surfacePatchList triSurface::calcPatches(labelList& faceMap) const
{
sortedRegion[faceI] = operator[](faceI).region();
}
sortedRegion.stableSort();
sortedRegion.sort();
faceMap = sortedRegion.indices();
@ -743,6 +744,26 @@ triSurface::triSurface
{}
triSurface::triSurface
(
List<labelledTri>& triangles,
const geometricSurfacePatchList& patches,
pointField& points,
const bool reUse
)
:
PrimitivePatch<labelledTri, ::Foam::List, pointField>
(
triangles,
points,
reUse
),
patches_(patches),
sortedEdgeFacesPtr_(NULL),
edgeOwnerPtr_(NULL)
{}
triSurface::triSurface
(
const List<labelledTri>& triangles,
@ -1148,9 +1169,7 @@ triSurface triSurface::subsetMesh
}
// Construct subsurface
triSurface subSurface(newTriangles, patches(), newPoints);
return subSurface;
return triSurface(newTriangles, patches(), newPoints, true);
}
@ -1187,30 +1206,36 @@ void triSurface::write(const Time& d) const
void triSurface::writeStats(Ostream& os) const
{
// Calculate bounding box without any additional addressing
// Copy of treeBoundBox code. Cannot use meshTools from triSurface...
// Unfortunately nPoints constructs meshPoints() so do compact version
// ourselves.
PackedList<1> pointIsUsed(points().size());
pointIsUsed = 0U;
label nPoints = 0;
boundBox bb
(
point(VGREAT, VGREAT, VGREAT),
point(-VGREAT, -VGREAT, -VGREAT)
);
forAll(*this, triI)
{
const labelledTri& f = operator[](triI);
forAll(f, fp)
{
const point& pt = points()[f[fp]];
bb.min() = ::Foam::min(bb.min(), pt);
bb.max() = ::Foam::max(bb.max(), pt);
label pointI = f[fp];
if (pointIsUsed.set(pointI, 1))
{
bb.min() = ::Foam::min(bb.min(), points()[pointI]);
bb.max() = ::Foam::max(bb.max(), points()[pointI]);
nPoints++;
}
}
}
// Unfortunately nPoints constructs meshPoints() ...
os << "Triangles : " << size() << endl
//<< "Edges : " << nEdges() << endl
<< "Vertices : " << nPoints() << endl
<< "Vertices : " << nPoints << endl
<< "Bounding Box : " << bb << endl;
}

View File

@ -36,9 +36,9 @@ SourceFiles
#ifndef triSurface_H
#define triSurface_H
#include "PrimitivePatch.H"
#include "pointField.H"
#include "labelledTri.H"
#include "PrimitivePatch.H"
#include "boolList.H"
#include "geometricSurfacePatchList.H"
#include "surfacePatchList.H"
@ -215,6 +215,15 @@ public:
const pointField&
);
//- Construct from triangles, patches, points. Reuse storage.
triSurface
(
List<labelledTri>&,
const geometricSurfacePatchList&,
pointField&,
const bool reUse
);
//- Construct from triangles, points. Set patchnames to default.
triSurface(const List<labelledTri>&, const pointField&);

View File

@ -5,6 +5,7 @@ laminar/laminar.C
kEpsilon/kEpsilon.C
RNGkEpsilon/RNGkEpsilon.C
realizableKE/realizableKE.C
kOmega/kOmega.C
kOmegaSST/kOmegaSST.C
SpalartAllmaras/SpalartAllmaras.C
LRR/LRR.C

View File

@ -0,0 +1,268 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 "kOmega.H"
#include "addToRunTimeSelectionTable.H"
#include "wallFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
namespace RASModels
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(kOmega, 0);
addToRunTimeSelectionTable(RASModel, kOmega, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
kOmega::kOmega
(
const volVectorField& U,
const surfaceScalarField& phi,
transportModel& lamTransportModel
)
:
RASModel(typeName, U, phi, lamTransportModel),
Cmu_
(
dimensioned<scalar>::lookupOrAddToDict
(
"betaStar",
coeffDict_,
0.09
)
),
beta_
(
dimensioned<scalar>::lookupOrAddToDict
(
"beta",
coeffDict_,
0.072
)
),
alphaK_
(
dimensioned<scalar>::lookupOrAddToDict
(
"alphaK",
coeffDict_,
0.5
)
),
alphaOmega_
(
dimensioned<scalar>::lookupOrAddToDict
(
"alphaOmega",
coeffDict_,
0.5
)
),
omega0_("omega0", dimless/dimTime, SMALL),
omegaSmall_("omegaSmall", dimless/dimTime, SMALL),
k_
(
IOobject
(
"k",
runTime_.timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh_
),
omega_
(
IOobject
(
"omega",
runTime_.timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh_
),
nut_(k_/(omega_ + omegaSmall_))
{
# include "kOmegaWallViscosityI.H"
printCoeffs();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
tmp<volSymmTensorField> kOmega::R() const
{
return tmp<volSymmTensorField>
(
new volSymmTensorField
(
IOobject
(
"R",
runTime_.timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
((2.0/3.0)*I)*k_ - nut_*twoSymm(fvc::grad(U_)),
k_.boundaryField().types()
)
);
}
tmp<volSymmTensorField> kOmega::devReff() const
{
return tmp<volSymmTensorField>
(
new volSymmTensorField
(
IOobject
(
"devRhoReff",
runTime_.timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
-nuEff()*dev(twoSymm(fvc::grad(U_)))
)
);
}
tmp<fvVectorMatrix> kOmega::divDevReff(volVectorField& U) const
{
return
(
- fvm::laplacian(nuEff(), U)
- fvc::div(nuEff()*dev(fvc::grad(U)().T()))
);
}
bool kOmega::read()
{
if (RASModel::read())
{
Cmu_.readIfPresent(coeffDict_);
beta_.readIfPresent(coeffDict_);
alphaK_.readIfPresent(coeffDict_);
alphaOmega_.readIfPresent(coeffDict_);
return true;
}
else
{
return false;
}
}
void kOmega::correct()
{
transportModel_.correct();
if (!turbulence_)
{
return;
}
RASModel::correct();
volScalarField G = nut_*2*magSqr(symm(fvc::grad(U_)));
# include "kOmegaWallFunctionsI.H"
// Turbulence specific dissipation rate equation
tmp<fvScalarMatrix> omegaEqn
(
fvm::ddt(omega_)
+ fvm::div(phi_, omega_)
- fvm::Sp(fvc::div(phi_), omega_)
- fvm::laplacian(DomegaEff(), omega_)
==
G*omega_/k_
- fvm::Sp(beta_*omega_, omega_)
);
omegaEqn().relax();
# include "wallOmegaI.H"
solve(omegaEqn);
bound(omega_, omega0_);
// Turbulent kinetic energy equation
tmp<fvScalarMatrix> kEqn
(
fvm::ddt(k_)
+ fvm::div(phi_, k_)
- fvm::Sp(fvc::div(phi_), k_)
- fvm::laplacian(DkEff(), k_)
==
G
- fvm::Sp(Cmu_*omega_, k_)
);
kEqn().relax();
solve(kEqn);
bound(k_, k0_);
// Re-calculate viscosity
nut_ = k_/omega_;
# include "kOmegaWallViscosityI.H"
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace RASModels
} // End namespace incompressible
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,205 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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
Foam::incompressible::RASModels::kOmega
Description
Standard high Reynolds-number k-omega turbulence model for
incompressible flows.
References:
@verbatim
"Turbulence Modeling for CFD"
D. C. Wilcox,
DCW Industries, Inc., La Canada,
California, 1998.
@endverbatim
The default model coefficients correspond to the following:
@verbatim
kOmegaCoeffs
{
Cmu 0.09; // Equivalent to betaStar
beta 0.072;
alphak 0.5;
alphaOmega 0.5;
}
@endverbatim
SourceFiles
kOmega.C
\*---------------------------------------------------------------------------*/
#ifndef kOmega_H
#define kOmega_H
#include "RASModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
namespace RASModels
{
/*---------------------------------------------------------------------------*\
Class kOmega Declaration
\*---------------------------------------------------------------------------*/
class kOmega
:
public RASModel
{
// Private data
// Model coefficients
dimensionedScalar Cmu_;
dimensionedScalar beta_;
dimensionedScalar alphaK_;
dimensionedScalar alphaOmega_;
dimensionedScalar omega0_;
dimensionedScalar omegaSmall_;
// Fields
volScalarField k_;
volScalarField omega_;
volScalarField nut_;
public:
//- Runtime type information
TypeName("kOmega");
// Constructors
//- Construct from components
kOmega
(
const volVectorField& U,
const surfaceScalarField& phi,
transportModel& transport
);
// Destructor
~kOmega()
{}
// Member Functions
//- Return the turbulence viscosity
tmp<volScalarField> nut() const
{
return nut_;
}
//- Return the effective diffusivity for k
tmp<volScalarField> DkEff() const
{
return tmp<volScalarField>
(
new volScalarField("DkEff", alphaK_*nut_ + nu())
);
}
//- Return the effective diffusivity for omega
tmp<volScalarField> DomegaEff() const
{
return tmp<volScalarField>
(
new volScalarField("DomegaEff", alphaOmega_*nut_ + nu())
);
}
//- Return the turbulence kinetic energy
tmp<volScalarField> k() const
{
return k_;
}
//- Return the turbulence specific dissipation rate
tmp<volScalarField> omega() const
{
return omega_;
}
//- Return the turbulence kinetic energy dissipation rate
tmp<volScalarField> epsilon() const
{
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"epsilon",
mesh_.time().timeName(),
mesh_
),
Cmu_*k_*omega_,
omega_.boundaryField().types()
)
);
}
//- Return the Reynolds stress tensor
tmp<volSymmTensorField> R() const;
//- Return the effective stress tensor including the laminar stress
tmp<volSymmTensorField> devReff() const;
//- Return the source term for the momentum equation
tmp<fvVectorMatrix> divDevReff(volVectorField& U) const;
//- Solve the turbulence equations and correct the turbulence viscosity
void correct();
//- Read turbulenceProperties dictionary
bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace RASModels
} // End namespace incompressible
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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
kOmegaWallFunctions
Description
Calculate wall generation and frequency omega from wall-functions.
\*---------------------------------------------------------------------------*/
{
labelList cellBoundaryFaceCount(omega_.size(), 0);
scalar Cmu25 = pow(Cmu_.value(), 0.25);
const fvPatchList& patches = mesh_.boundary();
//- Initialise the near-wall omega and G fields to zero
forAll(patches, patchi)
{
const fvPatch& curPatch = patches[patchi];
if (isType<wallFvPatch>(curPatch))
{
forAll(curPatch, facei)
{
label faceCelli = curPatch.faceCells()[facei];
omega_[faceCelli] = 0.0;
G[faceCelli] = 0.0;
}
}
}
//- Accumulate the wall face contributions to omega and G
// Increment cellBoundaryFaceCount for each face for averaging
forAll(patches, patchi)
{
const fvPatch& curPatch = patches[patchi];
if (isType<wallFvPatch>(curPatch))
{
# include "checkkOmegaPatchFieldTypes.H"
const scalarField& nuw = nu().boundaryField()[patchi];
const scalarField& nutw = nut_.boundaryField()[patchi];
scalarField magFaceGradU =
mag(U_.boundaryField()[patchi].snGrad());
forAll(curPatch, facei)
{
label faceCelli = curPatch.faceCells()[facei];
scalar yPlus =
Cmu25*y_[patchi][facei]
*sqrt(k_[faceCelli])
/nuw[facei];
// For corner cells (with two boundary or more faces),
// omega and G in the near-wall cell are calculated
// as an average
cellBoundaryFaceCount[faceCelli]++;
omega_[faceCelli] +=
sqrt(k_[faceCelli])
/(Cmu25*kappa_.value()*y_[patchi][facei]);
if (yPlus > yPlusLam_)
{
G[faceCelli] +=
(nutw[facei] + nuw[facei])
*magFaceGradU[facei]
*Cmu25*sqrt(k_[faceCelli])
/(kappa_.value()*y_[patchi][facei]);
}
}
}
}
// Perform the averaging
forAll(patches, patchi)
{
const fvPatch& curPatch = patches[patchi];
if (isType<wallFvPatch>(curPatch))
{
forAll(curPatch, facei)
{
label faceCelli = curPatch.faceCells()[facei];
omega_[faceCelli] /= cellBoundaryFaceCount[faceCelli];
G[faceCelli] /= cellBoundaryFaceCount[faceCelli];
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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
kOmegaWallViscosity
Description
Calculate wall viscosity from wall-functions.
\*---------------------------------------------------------------------------*/
{
scalar Cmu25 = pow(Cmu_.value(), 0.25);
const fvPatchList& patches = mesh_.boundary();
forAll(patches, patchi)
{
const fvPatch& curPatch = patches[patchi];
if (isType<wallFvPatch>(curPatch))
{
const scalarField& nuw = nu().boundaryField()[patchi];
scalarField& nutw = nut_.boundaryField()[patchi];
forAll(curPatch, facei)
{
label faceCelli = curPatch.faceCells()[facei];
scalar yPlus =
Cmu25*y_[patchi][facei]*sqrt(k_[faceCelli])/nuw[facei];
if (yPlus > yPlusLam_)
{
nutw[facei] =
nuw[facei]
*(yPlus*kappa_.value()/log(E_.value()*yPlus) - 1);
}
else
{
nutw[facei] = 0.0;
}
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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
wallOmega
Description
Set wall dissipation in the omega matrix
\*---------------------------------------------------------------------------*/
{
const fvPatchList& patches = mesh_.boundary();
forAll(patches, patchi)
{
const fvPatch& p = patches[patchi];
if (isType<wallFvPatch>(p))
{
omegaEqn().setValues
(
p.faceCells(),
omega_.boundaryField()[patchi].patchInternalField()
);
}
}
}
// ************************************************************************* //

View File

@ -238,6 +238,7 @@ public:
return k_;
}
//- Return the turbulence specific dissipation rate
tmp<volScalarField> omega() const
{
return omega_;

View File

@ -22,7 +22,7 @@ dictionaryReplacement
inlet
{
type directMappedPatch;
offset (0.05 0 0);
offset (0.0495 0 0);
}
}
}