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 = \ EXE_INC = \
-I../rasInterFoam \
-I../interFoam \
-I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/lnInclude \ -I$(LIB_SRC)/transportModels/incompressible/lnInclude \
-I$(LIB_SRC)/transportModels/interfaceProperties/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 "twoPhaseMixture.H"
#include "incompressible/RASModel/RASModel.H" #include "incompressible/RASModel/RASModel.H"
#include "probes.H" #include "probes.H"
#include "EulerDdtScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

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

View File

@ -86,28 +86,7 @@ void Foam::SortableList<Type>::sort()
indices_[i] = i; indices_[i] = i;
} }
Foam::sort(indices_, less(*this)); //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::stableSort(indices_, less(*this)); Foam::stableSort(indices_, less(*this));
List<Type> tmpValues(this->size()); List<Type> tmpValues(this->size());

View File

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

View File

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

View File

@ -31,7 +31,11 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * 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 // Communications: send and receive processor
List<labelPair> allComms; List<labelPair> allComms;
@ -40,16 +44,16 @@ void Foam::mapDistribute::calcSchedule() const
HashSet<labelPair, labelPair::Hash<> > commsSet(Pstream::nProcs()); HashSet<labelPair, labelPair::Hash<> > commsSet(Pstream::nProcs());
// Find what communication is required // Find what communication is required
forAll(subMap_, procI) forAll(subMap, procI)
{ {
if (procI != Pstream::myProcNo()) if (procI != Pstream::myProcNo())
{ {
if (subMap_[procI].size() > 0) if (subMap[procI].size() > 0)
{ {
// I need to send to procI // I need to send to procI
commsSet.insert(labelPair(Pstream::myProcNo(), procI)); commsSet.insert(labelPair(Pstream::myProcNo(), procI));
} }
if (constructMap_[procI].size() > 0) if (constructMap[procI].size() > 0)
{ {
// I need to receive from procI // I need to receive from procI
commsSet.insert(labelPair(procI, Pstream::myProcNo())); commsSet.insert(labelPair(procI, Pstream::myProcNo()));
@ -120,13 +124,7 @@ void Foam::mapDistribute::calcSchedule() const
); );
// Processors involved in my schedule // Processors involved in my schedule
schedulePtr_.reset return IndirectList<labelPair>(allComms, mySchedule);
(
new List<labelPair>
(
IndirectList<labelPair>(allComms, mySchedule)
)
);
//if (debug) //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 * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct from components //- 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 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. them will be myself) which forms a scheduled (i.e. non-buffered) exchange.
See distribute on how to use it. 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 SourceFiles
@ -80,8 +82,6 @@ class mapDistribute
// Private Member Functions // Private Member Functions
void calcSchedule() const;
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
mapDistribute(const mapDistribute&); mapDistribute(const mapDistribute&);
@ -142,15 +142,15 @@ public:
return constructMap_; return constructMap_;
} }
//- Calculate a schedule. See above.
static List<labelPair> schedule
(
const labelListList& subMap,
const labelListList& constructMap
);
//- Return a schedule. Demand driven. See above. //- Return a schedule. Demand driven. See above.
const List<labelPair>& schedule() const const List<labelPair>& schedule() const;
{
if (!schedulePtr_.valid())
{
calcSchedule();
}
return schedulePtr_();
}
// Other // Other

View File

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

View File

@ -25,7 +25,6 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "coupledPolyPatch.H" #include "coupledPolyPatch.H"
#include "SortableList.H"
#include "ListOps.H" #include "ListOps.H"
#include "transform.H" #include "transform.H"
#include "OFstream.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 // Construct as copy
template template
< <

View File

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

View File

@ -467,7 +467,8 @@ const edgeList& primitiveMesh::edges() const
{ {
if (!edgesPtr_) if (!edgesPtr_)
{ {
calcEdges(true); //calcEdges(true);
calcEdges(false);
} }
return *edgesPtr_; return *edgesPtr_;
@ -477,10 +478,8 @@ const labelListList& primitiveMesh::pointEdges() const
{ {
if (!pePtr_) if (!pePtr_)
{ {
//// Invert edges //calcEdges(true);
//pePtr_ = new labelListList(nPoints()); calcEdges(false);
//invertManyToMany(nPoints(), edges(), *pePtr_);
calcEdges(true);
} }
return *pePtr_; return *pePtr_;
@ -491,12 +490,53 @@ const labelListList& primitiveMesh::faceEdges() const
{ {
if (!fePtr_) 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_; return *fePtr_;
} }
void primitiveMesh::clearOutEdges() void primitiveMesh::clearOutEdges()
{ {
deleteDemandDrivenData(edgesPtr_); deleteDemandDrivenData(edgesPtr_);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -74,20 +74,10 @@ fluxCorrectedVelocityFvPatchVectorField
) )
: :
zeroGradientFvPatchVectorField(p, iF), zeroGradientFvPatchVectorField(p, iF),
phiName_("phi"), phiName_(dict.lookupOrDefault<word>("phi", "phi")),
rhoName_("rho") rhoName_(dict.lookupOrDefault<word>("rho", "rho"))
{ {
fvPatchVectorField::operator=(patchInternalField()); 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(); zeroGradientFvPatchVectorField::evaluate();
const surfaceScalarField& phi = db().lookupObject<surfaceScalarField> const surfaceScalarField& phi =
( db().lookupObject<surfaceScalarField>(phiName_);
phiName_
);
const fvsPatchField<scalar>& phip = const fvsPatchField<scalar>& phip =
patch().patchField<surfaceScalarField, scalar>(phi); patch().patchField<surfaceScalarField, scalar>(phi);

View File

@ -26,7 +26,10 @@ Class
Foam::fluxCorrectedVelocityFvPatchVectorField Foam::fluxCorrectedVelocityFvPatchVectorField
Description 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 SourceFiles
fluxCorrectedVelocityFvPatchVectorField.C 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 } // End namespace Foam

View File

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

View File

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

View File

@ -26,7 +26,10 @@ Class
Foam::pressureDirectedInletOutletVelocityFvPatchVectorField Foam::pressureDirectedInletOutletVelocityFvPatchVectorField
Description 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 SourceFiles
pressureDirectedInletOutletVelocityFvPatchVectorField.C pressureDirectedInletOutletVelocityFvPatchVectorField.C
@ -53,7 +56,9 @@ class pressureDirectedInletOutletVelocityFvPatchVectorField
public mixedFvPatchVectorField public mixedFvPatchVectorField
{ {
// Private data // Private data
word phiName_;
word rhoName_;
vectorField inletDir_; vectorField inletDir_;
@ -133,9 +138,35 @@ public:
} }
// Member functions // 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 // Mapping functions
//- Map (and resize as needed) from self given a mapping object //- Map (and resize as needed) from self given a mapping object
@ -157,6 +188,11 @@ public:
//- Write //- Write
virtual void write(Ostream&) const; virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const fvPatchField<vector>& pvf);
}; };

View File

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

View File

@ -23,10 +23,14 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class Class
Foam::pressureDirectedInletVelocityFvPatchVectorField Foam::pressureDirectedInletVelocityFvPatchVectorField
Description 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 SourceFiles
pressureDirectedInletVelocityFvPatchVectorField.C pressureDirectedInletVelocityFvPatchVectorField.C
@ -53,7 +57,9 @@ class pressureDirectedInletVelocityFvPatchVectorField
public fixedValueFvPatchVectorField public fixedValueFvPatchVectorField
{ {
// Private data // Private data
word phiName_;
word rhoName_;
vectorField inletDir_; vectorField inletDir_;
@ -130,9 +136,35 @@ public:
} }
// Member functions // 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 // Mapping functions
//- Map (and resize as needed) from self given a mapping object //- Map (and resize as needed) from self given a mapping object
@ -154,6 +186,11 @@ public:
//- Write //- Write
virtual void write(Ostream&) const; virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const fvPatchField<vector>& pvf);
}; };

View File

@ -26,7 +26,10 @@ Class
Foam::pressureInletOutletVelocityFvPatchVectorField Foam::pressureInletOutletVelocityFvPatchVectorField
Description 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 SourceFiles
pressureInletOutletVelocityFvPatchVectorField.C 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 makePatchTypeField

View File

@ -26,7 +26,9 @@ Class
Foam::pressureInletUniformVelocityFvPatchVectorField Foam::pressureInletUniformVelocityFvPatchVectorField
Description 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 SourceFiles
pressureInletUniformVelocityFvPatchVectorField.C pressureInletUniformVelocityFvPatchVectorField.C
@ -124,6 +126,11 @@ public:
//- Update the coefficients associated with the patch field //- Update the coefficients associated with the patch field
virtual void updateCoeffs(); virtual void updateCoeffs();
// Member operators
virtual void operator=(const fvPatchField<vector>& pvf);
}; };

View File

@ -70,20 +70,10 @@ pressureInletVelocityFvPatchVectorField::pressureInletVelocityFvPatchVectorField
) )
: :
fixedValueFvPatchVectorField(p, iF), fixedValueFvPatchVectorField(p, iF),
phiName_("phi"), phiName_(dict.lookupOrDefault<word>("phi", "phi")),
rhoName_("rho") rhoName_(dict.lookupOrDefault<word>("rho", "rho"))
{ {
fvPatchVectorField::operator=(vectorField("value", dict, p.size())); 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 makePatchTypeField

View File

@ -26,7 +26,10 @@ Class
Foam::pressureInletVelocityFvPatchVectorField Foam::pressureInletVelocityFvPatchVectorField
Description 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 SourceFiles
pressureInletVelocityFvPatchVectorField.C pressureInletVelocityFvPatchVectorField.C
@ -57,6 +60,7 @@ class pressureInletVelocityFvPatchVectorField
word phiName_; word phiName_;
word rhoName_; word rhoName_;
public: public:
//- Runtime type information //- Runtime type information
@ -127,6 +131,33 @@ public:
// Member functions // 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 //- Update the coefficients associated with the patch field
virtual void updateCoeffs(); virtual void updateCoeffs();
@ -136,10 +167,7 @@ public:
// Member operators // Member operators
virtual void operator=(const fvPatchField<vector>& pvf) virtual void operator=(const fvPatchField<vector>& pvf);
{
fvPatchField<vector>::operator=(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 Foam::rotatingPressureInletOutletVelocityFvPatchVectorField
Description 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 SourceFiles
rotatingPressureInletOutletVelocityFvPatchVectorField.C rotatingPressureInletOutletVelocityFvPatchVectorField.C

View File

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

View File

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

View File

@ -29,6 +29,8 @@ License
#include "ListListOps.H" #include "ListListOps.H"
#include "meshSearch.H" #include "meshSearch.H"
#include "mapDistribute.H" #include "mapDistribute.H"
#include "meshTools.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -47,16 +49,18 @@ void Foam::directMappedPolyPatch::collectSamples
( (
pointField& samples, pointField& samples,
labelList& patchFaceProcs, labelList& patchFaceProcs,
labelList& patchFaces labelList& patchFaces,
pointField& patchFc
) const ) const
{ {
const vectorField::subField fc = this->faceCentres();
// Collect all sample points and the faces they come from. // Collect all sample points and the faces they come from.
List<pointField> globalFc(Pstream::nProcs());
List<pointField> globalSamples(Pstream::nProcs()); List<pointField> globalSamples(Pstream::nProcs());
labelListList globalFaces(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()); globalFaces[Pstream::myProcNo()] = identity(size());
// Distribute to all processors // Distribute to all processors
@ -64,6 +68,8 @@ void Foam::directMappedPolyPatch::collectSamples
Pstream::scatterList(globalSamples); Pstream::scatterList(globalSamples);
Pstream::gatherList(globalFaces); Pstream::gatherList(globalFaces);
Pstream::scatterList(globalFaces); Pstream::scatterList(globalFaces);
Pstream::gatherList(globalFc);
Pstream::scatterList(globalFc);
// Rework into straight list // Rework into straight list
samples = ListListOps::combine<pointField> samples = ListListOps::combine<pointField>
@ -76,6 +82,11 @@ void Foam::directMappedPolyPatch::collectSamples
globalFaces, globalFaces,
accessOp<labelList>() accessOp<labelList>()
); );
patchFc = ListListOps::combine<pointField>
(
globalFc,
accessOp<pointField>()
);
patchFaceProcs.setSize(patchFaces.size()); patchFaceProcs.setSize(patchFaces.size());
labelList nPerProc labelList nPerProc
@ -103,11 +114,14 @@ void Foam::directMappedPolyPatch::findSamples
( (
const pointField& samples, const pointField& samples,
labelList& sampleCellProcs, labelList& sampleCellProcs,
labelList& sampleCells labelList& sampleCells,
pointField& sampleCc
) const ) const
{ {
sampleCellProcs.setSize(samples.size()); sampleCellProcs.setSize(samples.size());
sampleCells.setSize(samples.size()); sampleCells.setSize(samples.size());
sampleCc.setSize(samples.size());
sampleCc = point(-GREAT, -GREAT, -GREAT);
{ {
// Octree based search engine // Octree based search engine
@ -124,6 +138,8 @@ void Foam::directMappedPolyPatch::findSamples
else else
{ {
sampleCellProcs[sampleI] = Pstream::myProcNo(); 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::listCombineGather(sampleCellProcs, maxEqOp<label>());
Pstream::listCombineScatter(sampleCellProcs); Pstream::listCombineScatter(sampleCellProcs);
Pstream::listCombineGather(sampleCc, maxEqOp<point>());
Pstream::listCombineScatter(sampleCc);
if (debug) if (debug)
{ {
Info<< "directMappedPolyPatch::findSamples : " << endl; Info<< "directMappedPolyPatch::findSamples : " << endl;
@ -143,7 +162,8 @@ void Foam::directMappedPolyPatch::findSamples
{ {
Info<< " " << sampleI << " coord:" << samples[sampleI] Info<< " " << sampleI << " coord:" << samples[sampleI]
<< " found on processor:" << sampleCellProcs[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; pointField samples;
labelList patchFaceProcs; labelList patchFaceProcs;
labelList patchFaces; labelList patchFaces;
collectSamples(samples, patchFaceProcs, patchFaces); pointField patchFc;
collectSamples(samples, patchFaceProcs, patchFaces, patchFc);
// Find processor and cell samples are in // Find processor and cell samples are in
labelList sampleCellProcs; labelList sampleCellProcs;
labelList sampleCells; labelList sampleCells;
findSamples(samples, sampleCellProcs, sampleCells); pointField sampleCc;
findSamples(samples, sampleCellProcs, sampleCells, sampleCc);
// Now we have all the data we need: // 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) // - cell sample is in (so source when mapping)
// sampleCells, sampleCellProcs. // 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. // Determine schedule.
mapDistribute distMap(sampleCellProcs, patchFaceProcs); mapDistribute distMap(sampleCellProcs, patchFaceProcs);

View File

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

View File

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

View File

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

View File

@ -137,11 +137,11 @@ bool Foam::treeDataCell::overlaps
{ {
if (cacheBb_) if (cacheBb_)
{ {
return cubeBb.intersects(bbs_[index]); return cubeBb.overlaps(bbs_[index]);
} }
else 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_) if (cacheBb_)
{ {
return cubeBb.intersects(bbs_[index]); return cubeBb.overlaps(bbs_[index]);
} }
else 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 // 1. Quick rejection: bb does not intersect face bb at all
if (cacheBb_) if (cacheBb_)
{ {
if (!cubeBb.intersects(bbs_[index])) if (!cubeBb.overlaps(bbs_[index]))
{ {
return false; return false;
} }
} }
else else
{ {
if (!cubeBb.intersects(calcBb(faceLabels_[index]))) if (!cubeBb.overlaps(calcBb(faceLabels_[index])))
{ {
return false; return false;
} }

View File

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

View File

@ -94,6 +94,12 @@ public:
index_(-1) index_(-1)
{} {}
//- Construct from Istream
PointIndexHit(Istream& is)
{
is >> *this;
}
// Member Functions // Member Functions
@ -193,13 +199,45 @@ public:
friend Ostream& operator<< (Ostream& os, const PointIndexHit& pHit) friend Ostream& operator<< (Ostream& os, const PointIndexHit& pHit)
{ {
return os << pHit.hit_ << token::SPACE << pHit.hitPoint_ if (os.format() == IOstream::ASCII)
<< token::SPACE << pHit.index_; {
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) 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 treeBoundBox& cubeBb
) const ) 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 treeBoundBox& sampleBb
) const ) 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 treeBoundBox& sampleBb
) const ) const
{ {
//return sampleBb.intersects(allBb_[index]); //return sampleBb.overlaps(allBb_[index]);
//- Exact test of face intersecting bb //- Exact test of face intersecting bb
// 1. Quick rejection: bb does not intersect face bb at all // 1. Quick rejection: bb does not intersect face bb at all
if (!sampleBb.intersects(allBb_[index])) if (!sampleBb.overlaps(allBb_[index]))
{ {
return false; return false;
} }

View File

@ -39,7 +39,14 @@ Description
namespace Foam 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 // line intersection. Returns true if line (start to end) inside
// bb or intersects bb. Sets pt to intersection. // bb or intersects bb. Sets pt to intersection.
// //

View File

@ -263,8 +263,11 @@ public:
FixedList<direction, 8>& octantOrder FixedList<direction, 8>& octantOrder
) const; ) const;
//- Intersects other boundingbox? //- Overlaps other boundingbox?
inline bool intersects(const treeBoundBox&) const; 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, //- Intersects segment; set point to intersection position,
// return true if intersection found. // return true if intersection found.

View File

@ -24,9 +24,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H"
#include "treeBoundBox.H" #include "treeBoundBox.H"
#include "point.H"
#include "Random.H" #include "Random.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -414,9 +412,9 @@ inline void treeBoundBox::searchOrder
// true if bb's intersect or overlap. // true if bb's intersect or overlap.
// Note: <= to make sure we catch all. // 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 // Node: recurse into subnodes
const treeNode<Type>* subNodePtr = getNodePtr(octant); 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 // there might be a better fit inside this subNode
changed |= changed |=
@ -815,7 +815,7 @@ bool treeNode<Type>::findTightest
// Leaf: let leaf::find handle this // Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant); 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 // there might be a better fit inside this subLeaf
changed |= changed |=
@ -884,7 +884,7 @@ bool treeNode<Type>::findNearest
// Node // Node
const treeNode<Type>* subNodePtr = getNodePtr(octant); 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 // there might be a better fit inside this subNode
changed |= changed |=
@ -903,7 +903,7 @@ bool treeNode<Type>::findNearest
// Leaf: let leaf::find handle this // Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant); 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 // there might be a better fit inside this subNode
changed |= changed |=
@ -975,7 +975,7 @@ bool treeNode<Type>::findNearest
// Node // Node
const treeNode<Type>* subNodePtr = getNodePtr(octant); 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 // there might be a better fit inside this subNode
changed |= changed |=
@ -995,7 +995,7 @@ bool treeNode<Type>::findNearest
// Leaf: let leaf::find handle this // Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant); 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 // there might be a better fit inside this subNode
changed |= changed |=
@ -1060,7 +1060,7 @@ bool treeNode<Type>::findBox
// Node // Node
const treeNode<Type>* subNodePtr = getNodePtr(octant); const treeNode<Type>* subNodePtr = getNodePtr(octant);
if (subNodePtr->bb().intersects(box)) if (subNodePtr->bb().overlaps(box))
{ {
// Visit sub node. // Visit sub node.
changed |= subNodePtr->findBox(shapes, box, elements); changed |= subNodePtr->findBox(shapes, box, elements);
@ -1071,7 +1071,7 @@ bool treeNode<Type>::findBox
// Leaf: let leaf::find handle this // Leaf: let leaf::find handle this
const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant); const treeLeaf<Type>* subLeafPtr = getLeafPtr(octant);
if (subLeafPtr->bb().intersects(box)) if (subLeafPtr->bb().overlaps(box))
{ {
// Visit sub leaf. // Visit sub leaf.
changed |= subLeafPtr->findBox(shapes, box, elements); changed |= subLeafPtr->findBox(shapes, box, elements);

View File

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

View File

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

View File

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

View File

@ -54,7 +54,7 @@ bool Foam::treeLeaf<Foam::octreeDataTriSurface>::findNearest
label faceI = indices_[i]; label faceI = indices_[i];
// Quick rejection test. // Quick rejection test.
if (tightest.intersects(allBb[faceI])) if (tightest.overlaps(allBb[faceI]))
{ {
// Full calculation // Full calculation
scalar dist = shapes.calcNearest(faceI, sample, nearest); 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, // Since direction is coordinate axis there is no need to do projection,
// we can directly check u,v components for inclusion in triangle. // we can directly check u,v components for inclusion in triangle.
scalar localScale = max(max(magSqr(V10), magSqr(V20)), 1.0);
// Get other components // Get other components
label i1 = (i0 + 1) % 3; label i1 = (i0 + 1) % 3;
@ -114,8 +115,11 @@ bool Foam::triangleFuncs::intersectAxesBundle
scalar det = v2*u1 - u2*v1; 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 // Fix for V0:(-31.71428 0 -15.10714)
if (Foam::mag(det)/max(max(mag(V10),mag(V20)),1) < SMALL) // 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 // Triangle parallel to dir
return false; return false;
@ -132,7 +136,7 @@ bool Foam::triangleFuncs::intersectAxesBundle
scalar beta = 0; scalar beta = 0;
bool inter = false; bool inter = false;
if (Foam::mag(u1) < SMALL) if (Foam::mag(u1)/localScale < SMALL)
{ {
beta = u0/u2; beta = u0/u2;
if ((beta >= 0) && (beta <= 1)) 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 "Time.H"
#include "boundBox.H" #include "boundBox.H"
#include "SortableList.H" #include "SortableList.H"
#include "PackedList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -626,7 +627,7 @@ surfacePatchList triSurface::calcPatches(labelList& faceMap) const
{ {
sortedRegion[faceI] = operator[](faceI).region(); sortedRegion[faceI] = operator[](faceI).region();
} }
sortedRegion.stableSort(); sortedRegion.sort();
faceMap = sortedRegion.indices(); 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 triSurface::triSurface
( (
const List<labelledTri>& triangles, const List<labelledTri>& triangles,
@ -1148,9 +1169,7 @@ triSurface triSurface::subsetMesh
} }
// Construct subsurface // Construct subsurface
triSurface subSurface(newTriangles, patches(), newPoints); return triSurface(newTriangles, patches(), newPoints, true);
return subSurface;
} }
@ -1187,30 +1206,36 @@ void triSurface::write(const Time& d) const
void triSurface::writeStats(Ostream& os) const void triSurface::writeStats(Ostream& os) const
{ {
// Calculate bounding box without any additional addressing // Unfortunately nPoints constructs meshPoints() so do compact version
// Copy of treeBoundBox code. Cannot use meshTools from triSurface... // ourselves.
PackedList<1> pointIsUsed(points().size());
pointIsUsed = 0U;
label nPoints = 0;
boundBox bb boundBox bb
( (
point(VGREAT, VGREAT, VGREAT), point(VGREAT, VGREAT, VGREAT),
point(-VGREAT, -VGREAT, -VGREAT) point(-VGREAT, -VGREAT, -VGREAT)
); );
forAll(*this, triI) forAll(*this, triI)
{ {
const labelledTri& f = operator[](triI); const labelledTri& f = operator[](triI);
forAll(f, fp) forAll(f, fp)
{ {
const point& pt = points()[f[fp]]; label pointI = f[fp];
bb.min() = ::Foam::min(bb.min(), pt); if (pointIsUsed.set(pointI, 1))
bb.max() = ::Foam::max(bb.max(), pt); {
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 os << "Triangles : " << size() << endl
//<< "Edges : " << nEdges() << endl << "Vertices : " << nPoints << endl
<< "Vertices : " << nPoints() << endl
<< "Bounding Box : " << bb << endl; << "Bounding Box : " << bb << endl;
} }

View File

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

View File

@ -5,6 +5,7 @@ laminar/laminar.C
kEpsilon/kEpsilon.C kEpsilon/kEpsilon.C
RNGkEpsilon/RNGkEpsilon.C RNGkEpsilon/RNGkEpsilon.C
realizableKE/realizableKE.C realizableKE/realizableKE.C
kOmega/kOmega.C
kOmegaSST/kOmegaSST.C kOmegaSST/kOmegaSST.C
SpalartAllmaras/SpalartAllmaras.C SpalartAllmaras/SpalartAllmaras.C
LRR/LRR.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 k_;
} }
//- Return the turbulence specific dissipation rate
tmp<volScalarField> omega() const tmp<volScalarField> omega() const
{ {
return omega_; return omega_;

View File

@ -16,7 +16,7 @@ FoamFile
convertToMeters 0.05; convertToMeters 0.05;
vertices vertices
( (
(0 -1 0) (0 -1 0)
(0 0 0) (0 0 0)
@ -32,24 +32,24 @@ vertices
(0.1 1 0.1) (0.1 1 0.1)
); );
blocks blocks
( (
hex (0 3 4 1 6 9 10 7) (1 40 1) simpleGrading (1 1 1) hex (0 3 4 1 6 9 10 7) (1 40 1) simpleGrading (1 1 1)
hex (1 4 5 2 7 10 11 8) (1 40 1) simpleGrading (1 1 1) hex (1 4 5 2 7 10 11 8) (1 40 1) simpleGrading (1 1 1)
); );
edges edges
( (
); );
patches patches
( (
wall lowerWall wall lowerWall
( (
(0 3 9 6) (0 3 9 6)
) )
wall upperWall wall upperWall
( (
(2 8 11 5) (2 8 11 5)
) )

View File

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