Merge branch 'master' of ssh://dm/home/dm4/OpenFOAM/OpenFOAM-dev

This commit is contained in:
Henry
2012-02-17 10:39:52 +00:00
62 changed files with 3391 additions and 1259 deletions

View File

@ -707,6 +707,12 @@ private:
DynamicList<Foam::point>& existingEdgeLocations
) const;
//- Return a list of the nearest feature edge locations
List<pointIndexHit> nearestFeatureEdgeLocations
(
const Foam::point& pt
) const;
//- Check if a point is near any feature edge points.
bool pointIsNearFeatureEdgeLocation(const Foam::point& pt) const;
@ -983,6 +989,31 @@ private:
labelList& neighbour
) const;
//- Create an empty fvMesh
autoPtr<fvMesh> createDummyMesh
(
const IOobject& io,
const wordList& patchTypes,
const wordList& patchNames,
const labelList& patchSizes,
const labelList& patchStarts,
const labelList& procNeighbours
) const;
//- Rotate the faces on processor patches if necessary
void reorderProcessorPatches
(
const word& meshName,
const fileName& instance,
const pointField& points,
faceList& faces,
const wordList& patchTypes,
const wordList& patchNames,
const labelList& patchSizes,
const labelList& patchStarts,
const labelList& procNeighbours
) const;
//- Disallow default bitwise copy construct
conformalVoronoiMesh(const conformalVoronoiMesh&);

View File

@ -562,6 +562,193 @@ void Foam::conformalVoronoiMesh::writeMesh
}
Foam::autoPtr<Foam::fvMesh> Foam::conformalVoronoiMesh::createDummyMesh
(
const IOobject& io,
const wordList& patchTypes,
const wordList& patchNames,
const labelList& patchSizes,
const labelList& patchStarts,
const labelList& procNeighbours
) const
{
autoPtr<fvMesh> meshPtr
(
new fvMesh
(
io,
xferCopy(pointField()),
xferCopy(faceList()),
xferCopy(cellList())
)
);
fvMesh& mesh = meshPtr();
List<polyPatch*> patches(patchStarts.size());
forAll(patches, patchI)
{
if (patchTypes[patchI] == processorPolyPatch::typeName)
{
patches[patchI] = new processorPolyPatch
(
patchNames[patchI],
0, //patchSizes[p],
0, //patchStarts[p],
patchI,
mesh.boundaryMesh(),
Pstream::myProcNo(),
procNeighbours[patchI]
);
}
else
{
patches[patchI] = polyPatch::New
(
patchTypes[patchI],
patchNames[patchI],
0, //patchSizes[p],
0, //patchStarts[p],
patchI,
mesh.boundaryMesh()
).ptr();
}
}
mesh.addFvPatches(patches);
return meshPtr;
}
void Foam::conformalVoronoiMesh::reorderProcessorPatches
(
const word& meshName,
const fileName& instance,
const pointField& points,
faceList& faces,
const wordList& patchTypes,
const wordList& patchNames,
const labelList& patchSizes,
const labelList& patchStarts,
const labelList& procNeighbours
) const
{
// Create dummy mesh with correct proc boundaries to do sorting
autoPtr<fvMesh> sortMeshPtr
(
createDummyMesh
(
IOobject
(
meshName,
instance,
runTime_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
patchTypes,
patchNames,
patchSizes,
patchStarts,
procNeighbours
)
);
const fvMesh& sortMesh = sortMeshPtr();
// Rotation on new faces.
labelList rotation(faces.size(), 0);
PstreamBuffers pBufs(Pstream::nonBlocking);
// Send ordering
forAll(sortMesh.boundaryMesh(), patchI)
{
const polyPatch& pp = sortMesh.boundaryMesh()[patchI];
if (isA<processorPolyPatch>(pp))
{
refCast<const processorPolyPatch>(pp).initOrder
(
pBufs,
primitivePatch
(
SubList<face>
(
faces,
patchSizes[patchI],
patchStarts[patchI]
),
points
)
);
}
}
pBufs.finishedSends();
// Receive and calculate ordering
bool anyChanged = false;
forAll(sortMesh.boundaryMesh(), patchI)
{
const polyPatch& pp = sortMesh.boundaryMesh()[patchI];
if (isA<processorPolyPatch>(pp))
{
labelList patchFaceMap(patchSizes[patchI], -1);
labelList patchFaceRotation(patchSizes[patchI], 0);
bool changed =
refCast<const processorPolyPatch>(pp).order
(
pBufs,
primitivePatch
(
SubList<face>
(
faces,
patchSizes[patchI],
patchStarts[patchI]
),
points
),
patchFaceMap,
patchFaceRotation
);
if (changed)
{
// Merge patch face reordering into mesh face reordering table
label start = patchStarts[patchI];
forAll(patchFaceRotation, patchFaceI)
{
rotation[patchFaceI + start] =
patchFaceRotation[patchFaceI];
}
anyChanged = true;
}
}
}
reduce(anyChanged, orOp<bool>());
if (anyChanged)
{
// Rotate faces (rotation is already in new face indices).
forAll(rotation, faceI)
{
if (rotation[faceI] != 0)
{
faces[faceI] = faces[faceI].rotateFace(rotation[faceI]);
}
}
}
}
void Foam::conformalVoronoiMesh::writeMesh
(
const word& meshName,
@ -583,6 +770,22 @@ void Foam::conformalVoronoiMesh::writeMesh
writeObjMesh(points, faces, word(meshName + ".obj"));
}
if (Pstream::parRun())
{
reorderProcessorPatches
(
meshName,
instance,
points,
faces,
patchTypes,
patchNames,
patchSizes,
patchStarts,
procNeighbours
);
}
fvMesh mesh
(
IOobject

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -136,6 +136,9 @@ public:
//- Return the object holding the feature points and edges
inline const PtrList<extendedFeatureEdgeMesh>& features() const;
//- Return the location to mesh
inline const point& locationInMesh() const;
//- Return the surface indices
inline const labelList& surfaces() const;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -38,6 +38,12 @@ Foam::conformationSurfaces::features() const
}
const Foam::point& Foam::conformationSurfaces::locationInMesh() const
{
return locationInMesh_;
}
const Foam::labelList& Foam::conformationSurfaces::surfaces() const
{
return surfaces_;

View File

@ -43,10 +43,21 @@ using namespace Foam;
int main(int argc, char *argv[])
{
argList::addBoolOption
(
"noFilter",
"Do not filter the mesh"
);
#include "setRootCase.H"
#include "createTime.H"
runTime.functionObjects().off();
const bool noFilter = !args.optionFound("noFilter");
Info<< "Mesh filtering is " << (noFilter ? "on" : "off") << endl;
IOdictionary cvMeshDict
(
IOobject
@ -74,7 +85,7 @@ int main(int argc, char *argv[])
<< nl << endl;
}
mesh.writeMesh(runTime.constant(), true);
mesh.writeMesh(runTime.constant(), noFilter);
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"

View File

@ -2,5 +2,6 @@ EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = \
-lgenericPatchFields \
-lfiniteVolume

View File

@ -381,7 +381,7 @@ int main(int argc, char *argv[])
break;
case topoSetSource::REMOVE:
Info<< " Removing " << currentSet().type() << endl;
Info<< " Removing set" << endl;
removeSet(mesh, setType, setName);
break;

View File

@ -1,10 +1,12 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools \
-lsampling \
-lgenericPatchFields \
-llagrangian

View File

@ -20,3 +20,4 @@ label maxPositions(readLabel(propsDict.lookup("maxPositions")));
// outputFormat: raw, vtk
//word outputFormat(propsDict.lookup("outputFormat"));
word setFormat(propsDict.lookupOrDefault<word>("setFormat", "vtk"));

View File

@ -20,4 +20,6 @@ sampleFrequency 1;
maxPositions 1000000;
setFormat vtk; // see sampleDict for set formats
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -38,6 +38,7 @@ Description
#include "timeSelector.H"
#include "OFstream.H"
#include "passiveParticleCloud.H"
#include "writer.H"
using namespace Foam;
@ -79,9 +80,23 @@ int main(int argc, char *argv[])
label origId = iter().origId();
label origProc = iter().origProc();
if (origProc >= maxIds.size())
{
// Expand size
maxIds.setSize(origProc+1, -1);
}
maxIds[origProc] = max(maxIds[origProc], origId);
}
}
label maxNProcs = returnReduce(maxIds.size(), maxOp<label>());
Info<< "Detected particles originating from " << maxNProcs
<< " processors." << nl << endl;
maxIds.setSize(maxNProcs, -1);
Pstream::listCombineGather(maxIds, maxEqOp<label>());
Pstream::listCombineScatter(maxIds);
@ -178,56 +193,58 @@ int main(int argc, char *argv[])
}
}
if (Pstream::master())
{
OFstream vtkTracks(vtkPath/"particleTracks.vtk");
PtrList<coordSet> tracks(allTracks.size());
forAll(allTracks, trackI)
{
tracks.set
(
trackI,
new coordSet
(
"track" + Foam::name(trackI),
"distance"
)
);
tracks[trackI].transfer(allTracks[trackI]);
}
Info<< "\nWriting particle tracks to " << vtkTracks.name()
autoPtr<writer<scalar> > scalarFormatterPtr = writer<scalar>::New
(
setFormat
);
//OFstream vtkTracks(vtkPath/"particleTracks.vtk");
fileName vtkFile
(
scalarFormatterPtr().getFileName
(
tracks[0],
wordList(0)
)
);
OFstream vtkTracks
(
vtkPath
/ "particleTracks." + vtkFile.ext()
);
Info<< "\nWriting particle tracks in " << setFormat
<< " format to " << vtkTracks.name()
<< nl << endl;
// Total number of points in tracks + 1 per track
label nPoints = 0;
forAll(allTracks, trackI)
{
nPoints += allTracks[trackI].size();
}
vtkTracks
<< "# vtk DataFile Version 2.0" << nl
<< "particleTracks" << nl
<< "ASCII" << nl
<< "DATASET POLYDATA" << nl
<< "POINTS " << nPoints << " float" << nl;
// Write track points to file
forAll(allTracks, trackI)
{
forAll(allTracks[trackI], i)
{
const vector& pt = allTracks[trackI][i];
vtkTracks << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
}
}
// write track (line) connectivity to file
vtkTracks << "LINES " << nTracks << ' ' << nPoints+nTracks << nl;
// Write ids of track points to file
label globalPtI = 0;
forAll(allTracks, trackI)
{
vtkTracks << allTracks[trackI].size();
forAll(allTracks[trackI], i)
{
vtkTracks << ' ' << globalPtI;
globalPtI++;
}
vtkTracks << nl;
}
Info<< "end" << endl;
scalarFormatterPtr().write
(
true, // writeTracks
tracks,
wordList(0),
List<List<scalarField> >(0),
vtkTracks
);
}
return 0;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -276,7 +276,7 @@ public:
//- Return the binary size in number of characters
// used in the underlying storage
inline label byteSize() const;
inline std::streamsize byteSize() const;
//- Count number of bits set, O(log(n))
// Uses the Hamming weight (population count) method

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -945,7 +945,7 @@ inline Foam::label Foam::PackedList<nBits>::packedLength() const
template<unsigned nBits>
inline Foam::label Foam::PackedList<nBits>::byteSize() const
inline std::streamsize Foam::PackedList<nBits>::byteSize() const
{
return packedLength() * sizeof(StorageType);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -103,7 +103,7 @@ void Foam::UList<T>::swap(UList<T>& a)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
Foam::label Foam::UList<T>::byteSize() const
std::streamsize Foam::UList<T>::byteSize() const
{
if (!contiguous<T>())
{
@ -113,7 +113,7 @@ Foam::label Foam::UList<T>::byteSize() const
<< abort(FatalError);
}
return this->size_*label(sizeof(T));
return this->size_*sizeof(T);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -137,8 +137,9 @@ public:
//- Return the binary size in number of characters of the UList
// if the element is a primitive type
// i.e. contiguous<T>() == true
label byteSize() const;
// i.e. contiguous<T>() == true.
// Note that is of type streamsize since used in stream ops
std::streamsize byteSize() const;
//- Return a const pointer to the first data element,

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -28,6 +28,7 @@ License
#include "Pstream.H"
#include "ops.H"
#include "vector2D.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -95,7 +96,7 @@ T returnReduce
}
// Insist there is a specialisation for the reduction of a scalar
// Insist there is a specialisation for the sum reduction of scalar(s)
void reduce
(
scalar& Value,
@ -103,6 +104,13 @@ void reduce
const int tag = Pstream::msgType()
);
void reduce
(
vector2D& Value,
const sumOp<vector2D>& bop,
const int tag = Pstream::msgType()
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -633,6 +633,27 @@ Foam::face Foam::face::reverseFace() const
}
Foam::face Foam::face::rotateFace(const label nPos) const
{
const labelList& f = *this;
labelList newList(size());
forAll(f, fp)
{
label fp1 = (fp + nPos) % f.size();
if (fp1 < 0)
{
fp1 += f.size();
}
newList[fp1] = f[fp];
}
return face(xferMove(newList));
}
Foam::label Foam::face::which(const label globalIndex) const
{
const labelList& f = *this;

View File

@ -197,6 +197,9 @@ public:
// The starting points of the original and reverse face are identical.
face reverseFace() const;
//- Rotate face by number of positions
face rotateFace(const label nPos) const;
//- Navigation through face vertices
//- Which vertex on face (face index given a global index)

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -73,7 +73,7 @@ inline Foam::triFace Foam::tetCell::face(const label faceI) const
# ifdef FULLDEBUG
if (faceI >= 4)
{
FatalErrorIn("tetCell::tetEdge(const label faceI) const")
FatalErrorIn("tetCell::face(const label faceI) const")
<< "index out of range 0 -> 3. faceI = " << faceI
<< abort(FatalError);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -37,7 +37,7 @@ SourceFiles
#include "labelList.H"
#include "vectorField.H"
#include "triFaceList.H"
#include "pointField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -59,6 +59,9 @@ void Foam::reduce(scalar&, const sumOp<scalar>&, const int)
{}
void Foam::reduce(vector2D&, const sumOp<vector2D>&, const int)
{}
Foam::label Foam::UPstream::nRequests()
{

View File

@ -305,39 +305,48 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop, const int tag)
scalar sum;
MPI_Allreduce(&Value, &sum, 1, MPI_SCALAR, MPI_SUM, MPI_COMM_WORLD);
Value = sum;
}
/*
int myProcNo = UPstream::myProcNo();
int nProcs = UPstream::nProcs();
if (Pstream::debug)
{
Pout<< "Foam::reduce : reduced value:" << Value << endl;
}
}
//
// receive from children
//
int level = 1;
int thisLevelOffset = 2;
int childLevelOffset = thisLevelOffset/2;
int childProcId = 0;
while
(
(childLevelOffset < nProcs)
&& (myProcNo % thisLevelOffset) == 0
)
void Foam::reduce(vector2D& Value, const sumOp<vector2D>& bop, const int tag)
{
if (Pstream::debug)
{
Pout<< "Foam::reduce : value:" << Value << endl;
}
if (!UPstream::parRun())
{
return;
}
if (UPstream::nProcs() <= UPstream::nProcsSimpleSum)
{
if (UPstream::master())
{
childProcId = myProcNo + childLevelOffset;
scalar value;
if (childProcId < nProcs)
for
(
int slave=UPstream::firstSlave();
slave<=UPstream::lastSlave();
slave++
)
{
vector2D value;
if
(
MPI_Recv
(
&value,
1,
2,
MPI_SCALAR,
UPstream::procID(childProcId),
UPstream::procID(slave),
tag,
MPI_COMM_WORLD,
MPI_STATUS_IGNORE
@ -346,34 +355,24 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop, const int tag)
{
FatalErrorIn
(
"reduce(scalar& Value, const sumOp<scalar>& sumOp)"
"reduce(vector2D& Value, const sumOp<vector2D>& sumOp)"
) << "MPI_Recv failed"
<< Foam::abort(FatalError);
}
Value = bop(Value, value);
}
level++;
thisLevelOffset <<= 1;
childLevelOffset = thisLevelOffset/2;
}
//
// send and receive from parent
//
if (!UPstream::master())
else
{
int parentId = myProcNo - (myProcNo % thisLevelOffset);
if
(
MPI_Send
(
&Value,
1,
2,
MPI_SCALAR,
UPstream::procID(parentId),
UPstream::procID(UPstream::masterNo()),
tag,
MPI_COMM_WORLD
)
@ -381,19 +380,53 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop, const int tag)
{
FatalErrorIn
(
"reduce(scalar& Value, const sumOp<scalar>& sumOp)"
"reduce(vector2D& Value, const sumOp<vector2D>& sumOp)"
) << "MPI_Send failed"
<< Foam::abort(FatalError);
}
}
if (UPstream::master())
{
for
(
int slave=UPstream::firstSlave();
slave<=UPstream::lastSlave();
slave++
)
{
if
(
MPI_Send
(
&Value,
2,
MPI_SCALAR,
UPstream::procID(slave),
tag,
MPI_COMM_WORLD
)
)
{
FatalErrorIn
(
"reduce(vector2D& Value, const sumOp<vector2D>& sumOp)"
) << "MPI_Send failed"
<< Foam::abort(FatalError);
}
}
}
else
{
if
(
MPI_Recv
(
&Value,
1,
2,
MPI_SCALAR,
UPstream::procID(parentId),
UPstream::procID(UPstream::masterNo()),
tag,
MPI_COMM_WORLD,
MPI_STATUS_IGNORE
@ -402,52 +435,17 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop, const int tag)
{
FatalErrorIn
(
"reduce(scalar& Value, const sumOp<scalar>& sumOp)"
"reduce(vector2D& Value, const sumOp<vector2D>& sumOp)"
) << "MPI_Recv failed"
<< Foam::abort(FatalError);
}
}
//
// distribute to my children
//
level--;
thisLevelOffset >>= 1;
childLevelOffset = thisLevelOffset/2;
while (level > 0)
{
childProcId = myProcNo + childLevelOffset;
if (childProcId < nProcs)
{
if
(
MPI_Send
(
&Value,
1,
MPI_SCALAR,
UPstream::procID(childProcId),
tag,
MPI_COMM_WORLD
)
)
{
FatalErrorIn
(
"reduce(scalar& Value, const sumOp<scalar>& sumOp)"
) << "MPI_Send failed"
<< Foam::abort(FatalError);
}
}
level--;
thisLevelOffset >>= 1;
childLevelOffset = thisLevelOffset/2;
}
*/
}
else
{
vector2D sum;
MPI_Allreduce(&Value, &sum, 2, MPI_SCALAR, MPI_SUM, MPI_COMM_WORLD);
Value = sum;
}
if (Pstream::debug)

View File

@ -1890,30 +1890,6 @@ void Foam::polyTopoChange::calcFaceZonePointMap
}
Foam::face Foam::polyTopoChange::rotateFace
(
const face& f,
const label nPos
)
{
face newF(f.size());
forAll(f, fp)
{
label fp1 = (fp + nPos) % f.size();
if (fp1 < 0)
{
fp1 += f.size();
}
newF[fp1] = f[fp];
}
return newF;
}
void Foam::polyTopoChange::reorderCoupledFaces
(
const bool syncParallel,
@ -2024,7 +2000,7 @@ void Foam::polyTopoChange::reorderCoupledFaces
{
if (rotation[faceI] != 0)
{
faces_[faceI] = rotateFace(faces_[faceI], rotation[faceI]);
faces_[faceI] = faces_[faceI].rotateFace(rotation[faceI]);
}
}
}

View File

@ -363,9 +363,6 @@ class polyTopoChange
// Coupling
//- Rotate face by number of positions
static face rotateFace(const face& f, const label nPos);
//- Do all coupled patch face reordering
void reorderCoupledFaces
(

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -26,6 +26,7 @@ License
#include "pointLinear.H"
#include "fvMesh.H"
#include "volPointInterpolation.H"
#include "triangle.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -26,6 +26,7 @@ License
#include "primitiveMeshGeometry.H"
#include "pyramidPointFaceRef.H"
#include "unitConversion.H"
#include "triPointRef.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -33,6 +33,7 @@ wallBoundedStreamLine/wallBoundedStreamLine.C
wallBoundedStreamLine/wallBoundedStreamLineFunctionObject.C
wallBoundedStreamLine/wallBoundedStreamLineParticle.C
wallBoundedStreamLine/wallBoundedStreamLineParticleCloud.C
wallBoundedStreamLine/wallBoundedParticle.C
surfaceInterpolateFields/surfaceInterpolateFields.C
surfaceInterpolateFields/surfaceInterpolateFieldsFunctionObject.C

View File

@ -0,0 +1,606 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
\*----------------------------------------------------------------------------*/
#include "wallBoundedParticle.H"
#include "vectorFieldIOField.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
// defineParticleTypeNameAndDebug(wallBoundedParticle, 0);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
//// Check position is inside tet
//void Foam::wallBoundedParticle::checkInside() const
//{
// const tetIndices ti(currentTetIndices());
// const tetPointRef tpr(ti.tet(mesh_));
// if (!tpr.inside(position()))
// {
// FatalErrorIn("wallBoundedParticle::checkInside(..)")
// << "Particle:" //<< static_cast<const particle&>(*this)
// << info()
// << "is not inside " << tpr
// << abort(FatalError);
// }
//}
//
//
//void Foam::wallBoundedParticle::checkOnEdge() const
//{
// // Check that edge (as indicated by meshEdgeStart_, diagEdge_) is
// // indeed one that contains the position.
// const edge e = currentEdge();
//
// linePointRef ln(e.line(mesh_.points()));
//
// pointHit ph(ln.nearestDist(position()));
//
// if (ph.distance() > 1E-6)
// {
// FatalErrorIn
// (
// "wallBoundedParticle::checkOnEdge()"
// ) << "Problem :"
// << " particle:" //<< static_cast<const particle&>(*this)
// << info()
// << "edge:" << e
// << " at:" << ln
// << " distance:" << ph.distance()
// << abort(FatalError);
// }
//}
//
//
//void Foam::wallBoundedParticle::checkOnTriangle(const point& p)
//const
//{
// const triFace tri(currentTetIndices().faceTriIs(mesh_));
// pointHit ph = tri.nearestPoint(p, mesh_.points());
// if (ph.distance() > 1e-9)
// {
// FatalErrorIn
// (
// "wallBoundedParticle::checkOnTriangle(const point&)"
// ) << "Problem :"
// << " particle:" //<< static_cast<const particle&>(*this)
// << info()
// << "point:" << p
// << " distance:" << ph.distance()
// << abort(FatalError);
// }
//}
// Construct the edge the particle is on (according to meshEdgeStart_,
// diagEdge_)
Foam::edge Foam::wallBoundedParticle::currentEdge() const
{
if ((meshEdgeStart_ != -1) == (diagEdge_ != -1))
{
FatalErrorIn("wallBoundedParticle::currentEdge() const")
<< "Particle:" //<< static_cast<const particle&>(*this)
<< info()
<< "cannot both be on a mesh edge and a face-diagonal edge."
<< " meshEdgeStart_:" << meshEdgeStart_
<< " diagEdge_:" << diagEdge_
<< abort(FatalError);
}
const Foam::face& f = mesh_.faces()[tetFace()];
if (meshEdgeStart_ != -1)
{
return edge(f[meshEdgeStart_], f.nextLabel(meshEdgeStart_));
}
else
{
label faceBasePtI = mesh_.tetBasePtIs()[tetFace()];
label diagPtI = (faceBasePtI+diagEdge_)%f.size();
return edge(f[faceBasePtI], f[diagPtI]);
}
}
void Foam::wallBoundedParticle::crossEdgeConnectedFace
(
const edge& meshEdge
)
{
//label oldFaceI = tetFace();
// Update tetFace, tetPt
particle::crossEdgeConnectedFace(cell(), tetFace(), tetPt(), meshEdge);
// Update face to be same as tracking one
face() = tetFace();
// And adapt meshEdgeStart_.
const Foam::face& f = mesh_.faces()[tetFace()];
label fp = findIndex(f, meshEdge[0]);
if (f.nextLabel(fp) == meshEdge[1])
{
meshEdgeStart_ = fp;
}
else
{
label fpMin1 = f.rcIndex(fp);
if (f[fpMin1] == meshEdge[1])
{
meshEdgeStart_ = fpMin1;
}
else
{
FatalErrorIn
(
"wallBoundedParticle::crossEdgeConnectedFace"
"(const edge&)"
) << "Problem :"
<< " particle:" //<< static_cast<const particle&>(*this)
<< info()
<< "face:" << tetFace()
<< " verts:" << f
<< " meshEdge:" << meshEdge
<< abort(FatalError);
}
}
diagEdge_ = -1;
//Pout<< " crossed meshEdge "
// << meshEdge.line(mesh().points())
// << " from face:" << oldFaceI
// << " to face:" << tetFace() << endl;
// Check that still on same mesh edge
const edge eNew(f[meshEdgeStart_], f.nextLabel(meshEdgeStart_));
if (eNew != meshEdge)
{
FatalErrorIn
(
"wallBoundedParticle::crossEdgeConnectedFace"
"(const edge&)"
) << "Problem" << abort(FatalError);
}
// Check that edge (as indicated by meshEdgeStart_) is indeed one that
// contains the position.
//checkOnEdge();
}
void Foam::wallBoundedParticle::crossDiagonalEdge()
{
if (diagEdge_ == -1)
{
FatalErrorIn("wallBoundedParticle::crossDiagonalEdge()")
<< "Particle:" //<< static_cast<const particle&>(*this)
<< info()
<< "not on a diagonal edge" << abort(FatalError);
}
if (meshEdgeStart_ != -1)
{
FatalErrorIn("wallBoundedParticle::crossDiagonalEdge()")
<< "Particle:" //<< static_cast<const particle&>(*this)
<< info()
<< "meshEdgeStart_:" << meshEdgeStart_ << abort(FatalError);
}
//label oldTetPt = tetPt();
const Foam::face& f = mesh_.faces()[tetFace()];
// tetPtI starts from 1, goes up to f.size()-2
if (tetPt() == diagEdge_)
{
tetPt() = f.rcIndex(tetPt());
}
else
{
label nextTetPt = f.fcIndex(tetPt());
if (diagEdge_ == nextTetPt)
{
tetPt() = nextTetPt;
}
else
{
FatalErrorIn("wallBoundedParticle::crossDiagonalEdge()")
<< "Particle:" //<< static_cast<const particle&>(*this)
<< info()
<< "tetPt:" << tetPt()
<< " diagEdge:" << diagEdge_ << abort(FatalError);
}
}
meshEdgeStart_ = -1;
//Pout<< " crossed diagonalEdge "
// << currentEdge().line(mesh().points())
// << " from tetPt:" << oldTetPt
// << " to tetPt:" << tetPt() << endl;
}
//- Track through a single triangle.
// Gets passed tet+triangle the particle is in. Updates position() but nothing
// else. Returns the triangle edge the particle is now on.
Foam::scalar Foam::wallBoundedParticle::trackFaceTri
(
const vector& endPosition,
label& minEdgeI
)
{
// Track p from position to endPosition
const triFace tri(currentTetIndices().faceTriIs(mesh_));
vector n = tri.normal(mesh_.points());
//if (mag(n) < sqr(SMALL))
//{
// FatalErrorIn("wallBoundedParticle::trackFaceTri(..)")
// << "Small triangle." //<< static_cast<const particle&>(*this)
// << info()
// << "n:" << n
// << abort(FatalError);
//}
n /= mag(n)+VSMALL;
// Check which edge intersects the trajectory.
// Project trajectory onto triangle
minEdgeI = -1;
scalar minS = 1; // end position
//const point oldPosition(position());
edge currentE(-1, -1);
if (meshEdgeStart_ != -1 || diagEdge_ != -1)
{
currentE = currentEdge();
}
// Determine path along line position+s*d to see where intersections
// are.
forAll(tri, i)
{
label j = tri.fcIndex(i);
const point& pt0 = mesh_.points()[tri[i]];
const point& pt1 = mesh_.points()[tri[j]];
if (edge(tri[i], tri[j]) == currentE)
{
// Do not check particle is on
continue;
}
// Outwards pointing normal
vector edgeNormal = (pt1-pt0)^n;
//if (mag(edgeNormal) < SMALL)
//{
// FatalErrorIn("wallBoundedParticle::trackFaceTri(..)")
// << "Edge not perpendicular to triangle."
// //<< static_cast<const particle&>(*this)
// << info()
// << "triangle n:" << n
// << " edgeNormal:" << edgeNormal
// << " on tri:" << tri
// << " at:" << pt0
// << " at:" << pt1
// << abort(FatalError);
//}
edgeNormal /= mag(edgeNormal)+VSMALL;
// Determine whether position and end point on either side of edge.
scalar sEnd = (endPosition-pt0)&edgeNormal;
if (sEnd >= 0)
{
// endPos is outside triangle. position() should always be
// inside.
scalar sStart = (position()-pt0)&edgeNormal;
if (mag(sEnd-sStart) > VSMALL)
{
scalar s = sStart/(sStart-sEnd);
if (s >= 0 && s < minS)
{
minS = s;
minEdgeI = i;
}
}
}
}
if (minEdgeI != -1)
{
position() += minS*(endPosition-position());
}
else
{
// Did not hit any edge so tracked to the end position. Set position
// without any calculation to avoid truncation errors.
position() = endPosition;
minS = 1.0;
}
// Project position() back onto plane of triangle
const point& triPt = mesh_.points()[tri[0]];
position() -= ((position()-triPt)&n)*n;
//Pout<< " tracked from:" << oldPosition << " to:" << position()
// << " projectedEnd:" << endPosition
// << " at s:" << minS << endl;
//if (minEdgeI != -1)
//{
// Pout<< " on edge:" << minEdgeI
// << " on edge:"
// << mesh_.points()[tri[minEdgeI]]
// << mesh_.points()[tri[tri.fcIndex(minEdgeI)]]
// << endl;
//}
return minS;
}
// See if the current triangle has got a point on the
// correct side of the edge.
bool Foam::wallBoundedParticle::isTriAlongTrack
(
const point& endPosition
) const
{
const triFace triVerts(currentTetIndices().faceTriIs(mesh_));
const edge currentE = currentEdge();
//if (debug)
{
if
(
currentE[0] == currentE[1]
|| findIndex(triVerts, currentE[0]) == -1
|| findIndex(triVerts, currentE[1]) == -1
)
{
FatalErrorIn
(
"wallBoundedParticle::isTriAlongTrack"
"(const point&)"
) << "Edge " << currentE << " not on triangle " << triVerts
<< info()
<< abort(FatalError);
}
}
const vector dir = endPosition-position();
// Get normal of currentE
vector n = triVerts.normal(mesh_.points());
n /= mag(n);
forAll(triVerts, i)
{
label j = triVerts.fcIndex(i);
const point& pt0 = mesh_.points()[triVerts[i]];
const point& pt1 = mesh_.points()[triVerts[j]];
if (edge(triVerts[i], triVerts[j]) == currentE)
{
vector edgeNormal = (pt1-pt0)^n;
return (dir&edgeNormal) < 0;
}
}
FatalErrorIn
(
"wallBoundedParticle::isTriAlongTrack"
"(const point&)"
) << "Problem" << abort(FatalError);
return false;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::wallBoundedParticle::wallBoundedParticle
(
const polyMesh& mesh,
const vector& position,
const label cellI,
const label tetFaceI,
const label tetPtI,
const label meshEdgeStart,
const label diagEdge
)
:
particle(mesh, position, cellI, tetFaceI, tetPtI),
meshEdgeStart_(meshEdgeStart),
diagEdge_(diagEdge)
{
//checkInside();
//if (meshEdgeStart_ != -1 || diagEdge_ != -1)
//{
// checkOnEdge();
//}
// Unfortunately have no access to trackdata so cannot check if particle
// is on a wallPatch or has an mesh edge set (either of which is
// a requirement).
}
Foam::wallBoundedParticle::wallBoundedParticle
(
const polyMesh& mesh,
Istream& is,
bool readFields
)
:
particle(mesh, is, readFields)
{
if (readFields)
{
if (is.format() == IOstream::ASCII)
{
is >> meshEdgeStart_ >> diagEdge_;
}
else
{
is.read
(
reinterpret_cast<char*>(&meshEdgeStart_),
sizeof(meshEdgeStart_)
+ sizeof(diagEdge_)
);
}
}
// Check state of Istream
is.check
(
"wallBoundedParticle::wallBoundedParticle"
"(const Cloud<wallBoundedParticle>&, Istream&, bool)"
);
}
Foam::wallBoundedParticle::wallBoundedParticle
(
const wallBoundedParticle& p
)
:
particle(p),
meshEdgeStart_(p.meshEdgeStart_),
diagEdge_(p.diagEdge_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::wallBoundedParticle::write(Ostream& os, bool writeFields) const
{
const particle& p = static_cast<const particle&>(*this);
if (os.format() == IOstream::ASCII)
{
// Write base particle
p.write(os, writeFields);
if (writeFields)
{
// Write the additional entries
os << token::SPACE << meshEdgeStart_
<< token::SPACE << diagEdge_;
}
}
else
{
// Write base particle
p.write(os, writeFields);
// Write additional entries
if (writeFields)
{
os.write
(
reinterpret_cast<const char*>(&meshEdgeStart_),
sizeof(meshEdgeStart_)
+ sizeof(diagEdge_)
);
}
}
// Check state of Ostream
os.check("wallBoundedParticle::write(Ostream& os, bool) const");
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const wallBoundedParticle& p
)
{
// Write all data
p.write(os, true);
return os;
}
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const InfoProxy<wallBoundedParticle>& ip
)
{
const wallBoundedParticle& p = ip.t_;
tetPointRef tpr(p.currentTet());
os << " " << static_cast<const particle&>(p) << nl
<< " tet:" << nl;
os << " ";
meshTools::writeOBJ(os, tpr.a());
os << " ";
meshTools::writeOBJ(os, tpr.b());
os << " ";
meshTools::writeOBJ(os, tpr.c());
os << " ";
meshTools::writeOBJ(os, tpr.d());
os << " l 1 2" << nl
<< " l 1 3" << nl
<< " l 1 4" << nl
<< " l 2 3" << nl
<< " l 2 4" << nl
<< " l 3 4" << nl;
os << " ";
meshTools::writeOBJ(os, p.position());
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,345 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
Class
Foam::wallBoundedParticle
Description
Particle class that tracks on triangles of boundary faces. Use
trackToEdge similar to trackToFace on particle.
SourceFiles
wallBoundedParticle.C
wallBoundedParticleTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef wallBoundedParticle_H
#define wallBoundedParticle_H
#include "particle.H"
#include "autoPtr.H"
#include "InfoProxy.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class wallBoundedParticle Declaration
\*---------------------------------------------------------------------------*/
class wallBoundedParticle
:
public particle
{
public:
//- Class used to pass tracking data to the trackToFace function
template<class CloudType>
class TrackingData
:
public particle::TrackingData<CloudType>
{
public:
const PackedBoolList& isWallPatch_;
// Constructors
inline TrackingData
(
CloudType& cloud,
const PackedBoolList& isWallPatch
)
:
particle::TrackingData<CloudType>
(
cloud
),
isWallPatch_(isWallPatch)
{}
};
protected:
// Protected data
//- Particle is on mesh edge:
// const face& f = mesh.faces()[tetFace()]
// const edge e(f[meshEdgeStart_], f.nextLabel(meshEdgeStart_));
// Note that this real edge
// is also one of the edges of the face-triangle (from
// tetFace()+tetPt()).
label meshEdgeStart_;
//- Particle is on diagonal edge:
// const face& f = mesh.faces()[tetFace()]
// label faceBasePtI = mesh.tetBasePtIs()[faceI];
// label diagPtI = (faceBasePtI+diagEdge_)%f.size();
// const edge e(f[faceBasePtI], f[diagPtI]);
label diagEdge_;
// Protected Member Functions
//- Construct current edge
edge currentEdge() const;
//- Check if inside current tet
//void checkInside() const;
//- Check if on current edge
//void checkOnEdge() const;
//- Check if point on triangle
//void checkOnTriangle(const point&) const;
//- Cross mesh edge into different face on same cell
void crossEdgeConnectedFace(const edge& meshEdge);
//- Cross diagonal edge into different triangle on same face,cell
void crossDiagonalEdge();
//- Track through single triangle
scalar trackFaceTri(const vector& endPosition, label& minEdgeI);
//- Is current triangle in the track direction
bool isTriAlongTrack(const point& endPosition) const;
// Patch interactions
//- Do all patch interaction
template<class TrackData>
void patchInteraction(TrackData& td, const scalar trackFraction);
//- Overridable function to handle the particle hitting a patch
// Executed before other patch-hitting functions
template<class TrackData>
bool hitPatch
(
const polyPatch&,
TrackData& td,
const label patchI,
const scalar trackFraction,
const tetIndices& tetIs
);
//- Overridable function to handle the particle hitting a wedge
template<class TrackData>
void hitWedgePatch
(
const wedgePolyPatch&,
TrackData& td
);
//- Overridable function to handle the particle hitting a
// symmetryPlane
template<class TrackData>
void hitSymmetryPatch
(
const symmetryPolyPatch&,
TrackData& td
);
//- Overridable function to handle the particle hitting a cyclic
template<class TrackData>
void hitCyclicPatch
(
const cyclicPolyPatch&,
TrackData& td
);
//- Overridable function to handle the particle hitting a
//- processorPatch
template<class TrackData>
void hitProcessorPatch
(
const processorPolyPatch&,
TrackData& td
);
//- Overridable function to handle the particle hitting a wallPatch
template<class TrackData>
void hitWallPatch
(
const wallPolyPatch&,
TrackData& td,
const tetIndices&
);
//- Overridable function to handle the particle hitting a polyPatch
template<class TrackData>
void hitPatch
(
const polyPatch&,
TrackData& td
);
public:
// Constructors
//- Construct from components
wallBoundedParticle
(
const polyMesh& c,
const vector& position,
const label cellI,
const label tetFaceI,
const label tetPtI,
const label meshEdgeStart,
const label diagEdge
);
//- Construct from Istream
wallBoundedParticle
(
const polyMesh& c,
Istream& is,
bool readFields = true
);
//- Construct copy
wallBoundedParticle(const wallBoundedParticle& p);
//- Construct and return a clone
autoPtr<particle> clone() const
{
return autoPtr<particle>(new wallBoundedParticle(*this));
}
//- Factory class to read-construct particles used for
// parallel transfer
class iNew
{
const polyMesh& mesh_;
public:
iNew(const polyMesh& mesh)
:
mesh_(mesh)
{}
autoPtr<wallBoundedParticle> operator()
(
Istream& is
) const
{
return autoPtr<wallBoundedParticle>
(
new wallBoundedParticle(mesh_, is, true)
);
}
};
// Member Functions
// Access
//- -1 or label of mesh edge
inline label meshEdgeStart() const
{
return meshEdgeStart_;
}
//- -1 or diagonal edge
inline label diagEdge() const
{
return diagEdge_;
}
// Track
//- Equivalent of trackToFace
template<class TrackData>
scalar trackToEdge
(
TrackData& td,
const vector& endPosition
);
// Info
//- Return info proxy.
// Used to print particle information to a stream
inline InfoProxy<wallBoundedParticle> info() const
{
return *this;
}
// I-O
//- Read
template<class CloudType>
static void readFields(CloudType&);
//- Write
template<class CloudType>
static void writeFields(const CloudType&);
//- Write the particle data
void write(Ostream& os, bool writeFields) const;
// Ostream Operator
friend Ostream& operator<<
(
Ostream&,
const wallBoundedParticle&
);
friend Ostream& operator<<
(
Ostream&,
const InfoProxy<wallBoundedParticle>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "wallBoundedParticleTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,543 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
\*----------------------------------------------------------------------------*/
#include "wallBoundedParticle.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class TrackData>
void Foam::wallBoundedParticle::patchInteraction
(
TrackData& td,
const scalar trackFraction
)
{
// typedef TrackData::CloudType cloudType;
typedef typename TrackData::cloudType::particleType particleType;
particleType& p = static_cast<particleType&>(*this);
p.hitFace(td);
if (!internalFace(faceI_))
{
label origFaceI = faceI_;
label patchI = patch(faceI_);
// No action taken for tetPtI_ for tetFaceI_ here, handled by
// patch interaction call or later during processor transfer.
// Dummy tet indices. What to do here?
tetIndices faceHitTetIs;
if
(
!p.hitPatch
(
mesh_.boundaryMesh()[patchI],
td,
patchI,
trackFraction,
faceHitTetIs
)
)
{
// Did patch interaction model switch patches?
// Note: recalculate meshEdgeStart_, diagEdge_!
if (faceI_ != origFaceI)
{
patchI = patch(faceI_);
}
const polyPatch& patch = mesh_.boundaryMesh()[patchI];
if (isA<wedgePolyPatch>(patch))
{
p.hitWedgePatch
(
static_cast<const wedgePolyPatch&>(patch), td
);
}
else if (isA<symmetryPolyPatch>(patch))
{
p.hitSymmetryPatch
(
static_cast<const symmetryPolyPatch&>(patch), td
);
}
else if (isA<cyclicPolyPatch>(patch))
{
p.hitCyclicPatch
(
static_cast<const cyclicPolyPatch&>(patch), td
);
}
else if (isA<processorPolyPatch>(patch))
{
p.hitProcessorPatch
(
static_cast<const processorPolyPatch&>(patch), td
);
}
else if (isA<wallPolyPatch>(patch))
{
p.hitWallPatch
(
static_cast<const wallPolyPatch&>(patch), td, faceHitTetIs
);
}
else
{
p.hitPatch(patch, td);
}
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//- Track particle to a given position and returns 1.0 if the
// trajectory is completed without hitting a face otherwise
// stops at the face and returns the fraction of the trajectory
// completed.
// on entry 'stepFraction()' should be set to the fraction of the
// time-step at which the tracking starts.
template<class TrackData>
Foam::scalar Foam::wallBoundedParticle::trackToEdge
(
TrackData& td,
const vector& endPosition
)
{
// Are we on a track face? If not we do a topological walk.
// Particle:
// - cell_ always set
// - tetFace_, tetPt_ always set (these identify tet particle is in)
// - optionally meshEdgeStart_ or diagEdge_ set (edge particle is on)
//checkInside();
//checkOnTriangle(position());
//if (meshEdgeStart_ != -1 || diagEdge_ != -1)
//{
// checkOnEdge();
//}
scalar trackFraction = 0.0;
if (!td.isWallPatch_[tetFace()])
{
// Don't track across face. Just walk in cell. Particle is on
// mesh edge (as indicated by meshEdgeStart_).
const edge meshEdge(currentEdge());
// If internal face check whether to go to neighbour cell or just
// check to the other internal tet on the edge.
if (mesh_.isInternalFace(tetFace()))
{
label nbrCellI =
(
cellI_ == mesh_.faceOwner()[faceI_]
? mesh_.faceNeighbour()[faceI_]
: mesh_.faceOwner()[faceI_]
);
// Check angle to nbrCell tet. Is it in the direction of the
// endposition? I.e. since volume of nbr tet is positive the
// tracking direction should be into the tet.
tetIndices nbrTi(nbrCellI, tetFaceI_, tetPtI_, mesh_);
if ((nbrTi.faceTri(mesh_).normal() & (endPosition-position())) < 0)
{
// Change into nbrCell. No need to change tetFace, tetPt.
//Pout<< " crossed from cell:" << cellI_
// << " into " << nbrCellI << endl;
cellI_ = nbrCellI;
patchInteraction(td, trackFraction);
}
else
{
// Walk to other face on edge. Changes tetFace, tetPt but not
// cell.
crossEdgeConnectedFace(meshEdge);
patchInteraction(td, trackFraction);
}
}
else
{
// Walk to other face on edge. This might give loop since
// particle should have been removed?
crossEdgeConnectedFace(meshEdge);
patchInteraction(td, trackFraction);
}
}
else
{
// We're inside a tet on the wall. Check if the current tet is
// the one to cross. If not we cross into the neighbouring triangle.
if (mesh_.isInternalFace(tetFace()))
{
FatalErrorIn
(
"wallBoundedParticle::trackToEdge"
"(TrackData&, const vector&)"
) << "Can only track on boundary faces."
<< " Face:" << tetFace()
<< " at:" << mesh_.faceCentres()[tetFace()]
<< abort(FatalError);
}
point projectedEndPosition = endPosition;
// Remove normal component
{
const triFace tri(currentTetIndices().faceTriIs(mesh_));
vector n = tri.normal(mesh_.points());
n /= mag(n);
const point& basePt = mesh_.points()[tri[0]];
projectedEndPosition -= ((projectedEndPosition-basePt)&n)*n;
}
bool doTrack = false;
if (meshEdgeStart_ == -1 && diagEdge_ == -1)
{
// We're starting and not yet on an edge.
doTrack = true;
}
else
{
// See if the current triangle has got a point on the
// correct side of the edge.
doTrack = isTriAlongTrack(projectedEndPosition);
}
if (doTrack)
{
// Track across triangle. Return triangle edge crossed.
label triEdgeI = -1;
trackFraction = trackFaceTri(projectedEndPosition, triEdgeI);
if (triEdgeI == -1)
{
// Reached endpoint
//checkInside();
diagEdge_ = -1;
meshEdgeStart_ = -1;
return trackFraction;
}
const tetIndices ti(currentTetIndices());
// Triangle (faceTriIs) gets constructed from
// f[faceBasePtI_],
// f[facePtAI_],
// f[facePtBI_]
//
// So edge indices are:
// 0 : edge between faceBasePtI_ and facePtAI_
// 1 : edge between facePtAI_ and facePtBI_ (is always a real edge)
// 2 : edge between facePtBI_ and faceBasePtI_
const Foam::face& f = mesh_.faces()[ti.face()];
const label fp0 = ti.faceBasePt();
if (triEdgeI == 0)
{
if (ti.facePtA() == f.fcIndex(fp0))
{
//Pout<< "Real edge." << endl;
diagEdge_ = -1;
meshEdgeStart_ = fp0;
//checkOnEdge();
crossEdgeConnectedFace(currentEdge());
patchInteraction(td, trackFraction);
}
else if (ti.facePtA() == f.rcIndex(fp0))
{
//Note: should not happen since boundary face so owner
//Pout<< "Real edge." << endl;
FatalErrorIn("shold not happend") << info()
<< abort(FatalError);
diagEdge_ = -1;
meshEdgeStart_ = f.rcIndex(fp0);
//checkOnEdge();
crossEdgeConnectedFace(currentEdge());
patchInteraction(td, trackFraction);
}
else
{
// Get index of triangle on other side of edge.
diagEdge_ = ti.facePtA()-fp0;
if (diagEdge_ < 0)
{
diagEdge_ += f.size();
}
meshEdgeStart_ = -1;
//checkOnEdge();
crossDiagonalEdge();
}
}
else if (triEdgeI == 1)
{
//Pout<< "Real edge." << endl;
diagEdge_ = -1;
meshEdgeStart_ = ti.facePtA();
//checkOnEdge();
crossEdgeConnectedFace(currentEdge());
patchInteraction(td, trackFraction);
}
else // if (triEdgeI == 2)
{
if (ti.facePtB() == f.rcIndex(fp0))
{
//Pout<< "Real edge." << endl;
diagEdge_ = -1;
meshEdgeStart_ = ti.facePtB();
//checkOnEdge();
crossEdgeConnectedFace(currentEdge());
patchInteraction(td, trackFraction);
}
else if (ti.facePtB() == f.fcIndex(fp0))
{
//Note: should not happen since boundary face so owner
//Pout<< "Real edge." << endl;
FatalErrorIn("shold not happend") << info()
<< abort(FatalError);
diagEdge_ = -1;
meshEdgeStart_ = fp0;
//checkOnEdge();
crossEdgeConnectedFace(currentEdge());
patchInteraction(td, trackFraction);
}
else
{
//Pout<< "Triangle edge." << endl;
// Get index of triangle on other side of edge.
diagEdge_ = ti.facePtB()-fp0;
if (diagEdge_ < 0)
{
diagEdge_ += f.size();
}
meshEdgeStart_ = -1;
//checkOnEdge();
crossDiagonalEdge();
}
}
}
else
{
// Current tet is not the right one. Check the neighbour tet.
if (meshEdgeStart_ != -1)
{
// Particle is on mesh edge so change into other face on cell
crossEdgeConnectedFace(currentEdge());
//checkOnEdge();
patchInteraction(td, trackFraction);
}
else
{
// Particle is on diagonal edge so change into the other
// triangle.
crossDiagonalEdge();
//checkOnEdge();
}
}
}
//checkInside();
return trackFraction;
}
template<class TrackData>
bool Foam::wallBoundedParticle::hitPatch
(
const polyPatch&,
TrackData& td,
const label patchI,
const scalar trackFraction,
const tetIndices& tetIs
)
{
// Disable generic patch interaction
return false;
}
template<class TrackData>
void Foam::wallBoundedParticle::hitWedgePatch
(
const wedgePolyPatch& pp,
TrackData& td
)
{
// Remove particle
td.keepParticle = false;
}
template<class TrackData>
void Foam::wallBoundedParticle::hitSymmetryPatch
(
const symmetryPolyPatch& pp,
TrackData& td
)
{
// Remove particle
td.keepParticle = false;
}
template<class TrackData>
void Foam::wallBoundedParticle::hitCyclicPatch
(
const cyclicPolyPatch& pp,
TrackData& td
)
{
// Remove particle
td.keepParticle = false;
}
template<class TrackData>
void Foam::wallBoundedParticle::hitProcessorPatch
(
const processorPolyPatch& pp,
TrackData& td
)
{
// Switch particle
td.switchProcessor = true;
// Adapt edgeStart_ for other side.
// E.g. if edgeStart_ is 1 then the edge is between vertex 1 and 2 so
// on the other side between 2 and 3 so edgeStart_ should be
// f.size()-edgeStart_-1.
const Foam::face& f = mesh_.faces()[face()];
if (meshEdgeStart_ != -1)
{
meshEdgeStart_ = f.size()-meshEdgeStart_-1;
}
else
{
// diagEdge_ is relative to faceBasePt
diagEdge_ = f.size()-diagEdge_;
}
}
template<class TrackData>
void Foam::wallBoundedParticle::hitWallPatch
(
const wallPolyPatch& wpp,
TrackData& td,
const tetIndices&
)
{}
template<class TrackData>
void Foam::wallBoundedParticle::hitPatch
(
const polyPatch& wpp,
TrackData& td
)
{
// Remove particle
td.keepParticle = false;
}
template<class CloudType>
void Foam::wallBoundedParticle::readFields(CloudType& c)
{
if (!c.size())
{
return;
}
particle::readFields(c);
IOField<label> meshEdgeStart
(
c.fieldIOobject("meshEdgeStart", IOobject::MUST_READ)
);
IOField<label> diagEdge
(
c.fieldIOobject("diagEdge_", IOobject::MUST_READ)
);
c.checkFieldIOobject(c, diagEdge);
label i = 0;
forAllIter(typename CloudType, c, iter)
{
iter().meshEdgeStart_ = meshEdgeStart[i];
iter().diagEdge_ = diagEdge[i];
i++;
}
}
template<class CloudType>
void Foam::wallBoundedParticle::writeFields(const CloudType& c)
{
particle::writeFields(c);
label np = c.size();
IOField<label> meshEdgeStart
(
c.fieldIOobject("meshEdgeStart", IOobject::NO_READ),
np
);
IOField<label> diagEdge
(
c.fieldIOobject("diagEdge", IOobject::NO_READ),
np
);
label i = 0;
forAllConstIter(typename CloudType, c, iter)
{
meshEdgeStart[i] = iter().meshEdgeStart_;
diagEdge[i] = iter().diagEdge_;
i++;
}
meshEdgeStart.write();
diagEdge.write();
}
// ************************************************************************* //

View File

@ -36,7 +36,7 @@ SourceFiles
#ifndef wallBoundedStreamLineParticle_H
#define wallBoundedStreamLineParticle_H
#include "particle.H"
#include "wallBoundedParticle.H"
#include "autoPtr.H"
#include "interpolation.H"
#include "vectorList.H"
@ -50,20 +50,23 @@ namespace Foam
class wallBoundedStreamLineParticleCloud;
/*---------------------------------------------------------------------------*\
Class wallBoundedStreamLineParticle Declaration
Class wallBoundedStreamLineParticle Declaration
\*---------------------------------------------------------------------------*/
class wallBoundedStreamLineParticle
:
public particle
public wallBoundedParticle
{
public:
//- Class used to pass tracking data to the trackToFace function
//- Class used to pass tracking data to the trackToEdge function
class trackingData
:
public particle::TrackingData<Cloud<wallBoundedStreamLineParticle> >
public wallBoundedParticle::TrackingData
<
Cloud<wallBoundedStreamLineParticle>
>
{
public:
@ -75,8 +78,6 @@ public:
const bool trackForward_;
const scalar trackLength_;
const PackedBoolList& isWallPatch_;
DynamicList<vectorList>& allPositions_;
List<DynamicList<scalarList> >& allScalars_;
List<DynamicList<vectorList> >& allVectors_;
@ -99,16 +100,19 @@ public:
List<DynamicList<vectorList> >& allVectors
)
:
particle::TrackingData<Cloud<wallBoundedStreamLineParticle> >
wallBoundedParticle::TrackingData
<
Cloud<wallBoundedStreamLineParticle>
>
(
cloud
cloud,
isWallPatch
),
vsInterp_(vsInterp),
vvInterp_(vvInterp),
UIndex_(UIndex),
trackForward_(trackForward),
trackLength_(trackLength),
isWallPatch_(isWallPatch),
allPositions_(allPositions),
allScalars_(allScalars),
@ -121,21 +125,6 @@ private:
// Private data
//- Particle is on mesh edge:
// const face& f = mesh.faces()[tetFace()]
// const edge e(f[meshEdgeStart_], f.nextLabel(meshEdgeStart_));
// Note that this real edge
// is also one of the edges of the face-triangle (from
// tetFace()+tetPt()).
label meshEdgeStart_;
//- Particle is on diagonal edge:
// const face& f = mesh.faces()[tetFace()]
// label faceBasePtI = mesh.tetBasePtIs()[faceI];
// label diagPtI = (faceBasePtI+diagEdge_)%f.size();
// const edge e(f[faceBasePtI], f[diagPtI]);
label diagEdge_;
//- Lifetime of particle. Particle dies when reaches 0.
label lifeTime_;
@ -151,52 +140,17 @@ private:
// Private Member Functions
//- Construct current edge
edge currentEdge() const;
//- Check if inside current tet
//void checkInside() const;
//- Check if on current edge
//void checkOnEdge() const;
//- Check if point on triangle
//void checkOnTriangle(const point&) const;
//- Cross mesh edge into different face on same cell
void crossEdgeConnectedFace(const edge& meshEdge);
//- Cross diagonal edge into different triangle on same face,cell
void crossDiagonalEdge();
//- Track through single triangle
scalar trackFaceTri(const vector& endPosition, label& minEdgeI);
//- Do all patch interaction
void patchInteraction(trackingData& td, const scalar trackFraction);
//- Is current triangle in the track direction
bool isTriAlongTrack(const point& endPosition) const;
//- Equivalent of trackToFace
scalar trackToEdge
(
trackingData& td,
const vector& endPosition
);
//- Interpolate all quantities; return interpolated velocity.
vector interpolateFields
(
const trackingData&,
const point&,
const trackingData& td,
const point& position,
const label cellI,
const label faceI
);
//- Interpolate all quantities, return updated velocity.
vector sample(trackingData& td);
public:
// Constructors
@ -265,73 +219,6 @@ public:
bool move(trackingData&, const scalar trackTime);
//- Overridable function to handle the particle hitting a patch
// Executed before other patch-hitting functions
bool hitPatch
(
const polyPatch&,
trackingData& td,
const label patchI,
const scalar trackFraction,
const tetIndices& tetIs
);
//- Overridable function to handle the particle hitting a wedge
void hitWedgePatch
(
const wedgePolyPatch&,
trackingData& td
);
//- Overridable function to handle the particle hitting a
// symmetryPlane
void hitSymmetryPatch
(
const symmetryPolyPatch&,
trackingData& td
);
//- Overridable function to handle the particle hitting a cyclic
void hitCyclicPatch
(
const cyclicPolyPatch&,
trackingData& td
);
//- Overridable function to handle the particle hitting a
//- processorPatch
void hitProcessorPatch
(
const processorPolyPatch&,
trackingData& td
);
//- Overridable function to handle the particle hitting a wallPatch
void hitWallPatch
(
const wallPolyPatch&,
trackingData& td,
const tetIndices&
);
//- Overridable function to handle the particle hitting a polyPatch
void hitPatch
(
const polyPatch&,
trackingData& td
);
// Info
//- Return info proxy.
// Used to print particle information to a stream
InfoProxy<wallBoundedStreamLineParticle> info() const
{
return *this;
}
// I-O
//- Read
@ -351,12 +238,6 @@ public:
Ostream&,
const wallBoundedStreamLineParticle&
);
friend Ostream& operator<<
(
Ostream&,
const InfoProxy<wallBoundedStreamLineParticle>&
);
};

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -202,6 +202,7 @@ Foam::patchProbes::patchProbes
// Not easy to workaround (apart from feeding through flag into constructor)
// so clear out any cells found for now.
elementList_.clear();
faceList_.clear();
read(dict);
}
@ -222,6 +223,12 @@ void Foam::patchProbes::write()
sampleAndWrite(sphericalTensorFields_);
sampleAndWrite(symmTensorFields_);
sampleAndWrite(tensorFields_);
sampleAndWriteSurfaceFields(surfaceScalarFields_);
sampleAndWriteSurfaceFields(surfaceVectorFields_);
sampleAndWriteSurfaceFields(surfaceSphericalTensorFields_);
sampleAndWriteSurfaceFields(surfaceSymmTensorFields_);
sampleAndWriteSurfaceFields(surfaceTensorFields_);
}
}

View File

@ -74,11 +74,24 @@ class patchProbes
);
//- Sample and write a particular surface field
template<class Type>
void sampleAndWrite
(
const GeometricField<Type, fvsPatchField, surfaceMesh>&
);
//- Sample and write all the fields of the given type
template <class Type>
void sampleAndWrite(const fieldGroup<Type>&);
//- Sample and write all the surface fields of the given type
template<class Type>
void sampleAndWriteSurfaceFields(const fieldGroup<Type>&);
//- Sample a volume field at all locations
template<class Type>
tmp<Field<Type> > sample
@ -87,6 +100,14 @@ class patchProbes
) const;
//- Sample a surface field at all locations
template<class Type>
tmp<Field<Type> > sample
(
const GeometricField<Type, fvsPatchField, surfaceMesh>&
) const;
//- Sample a single field on all sample locations
template <class Type>
tmp<Field<Type> > sample(const word& fieldName) const;

View File

@ -54,6 +54,30 @@ void Foam::patchProbes::sampleAndWrite
}
template<class Type>
void Foam::patchProbes::sampleAndWrite
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
)
{
Field<Type> values(sample(sField));
if (Pstream::master())
{
unsigned int w = IOstream::defaultPrecision() + 7;
OFstream& probeStream = *probeFilePtrs_[sField.name()];
probeStream << setw(w) << sField.time().value();
forAll(values, probeI)
{
probeStream << ' ' << setw(w) << values[probeI];
}
probeStream << endl;
}
}
template <class Type>
void Foam::patchProbes::sampleAndWrite
(
@ -106,6 +130,58 @@ void Foam::patchProbes::sampleAndWrite
}
template<class Type>
void Foam::patchProbes::sampleAndWriteSurfaceFields
(
const fieldGroup<Type>& fields
)
{
forAll(fields, fieldI)
{
if (loadFromFiles_)
{
sampleAndWrite
(
GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fields[fieldI],
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
),
mesh_
)
);
}
else
{
objectRegistry::const_iterator iter = mesh_.find(fields[fieldI]);
if
(
iter != objectRegistry::end()
&& iter()->type()
== GeometricField<Type, fvsPatchField, surfaceMesh>::typeName
)
{
sampleAndWrite
(
mesh_.lookupObject
<GeometricField<Type, fvsPatchField, surfaceMesh> >
(
fields[fieldI]
)
);
}
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
@ -159,4 +235,39 @@ Foam::patchProbes::sample(const word& fieldName) const
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::patchProbes::sample
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
) const
{
const Type unsetVal(-VGREAT*pTraits<Type>::one);
tmp<Field<Type> > tValues
(
new Field<Type>(this->size(), unsetVal)
);
Field<Type>& values = tValues();
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
forAll(*this, probeI)
{
label faceI = elementList_[probeI];
if (faceI >= 0)
{
label patchI = patches.whichPatch(faceI);
label localFaceI = patches[patchI].whichFace(faceI);
values[probeI] = sField.boundaryField()[patchI][localFaceI];
}
}
Pstream::listCombineGather(values, isNotEqOp<Type>());
Pstream::listCombineScatter(values);
return tValues;
}
// ************************************************************************* //

View File

@ -41,16 +41,45 @@ void Foam::probes::findElements(const fvMesh& mesh)
elementList_.clear();
elementList_.setSize(size());
faceList_.clear();
faceList_.setSize(size());
forAll(*this, probeI)
{
const vector& location = operator[](probeI);
elementList_[probeI] = mesh.findCell(location);
const label cellI = mesh.findCell(location);
if (debug && elementList_[probeI] != -1)
elementList_[probeI] = cellI;
if (cellI != -1)
{
const labelList& cellFaces = mesh.cells()[cellI];
const vector& cellCentre = mesh.cellCentres()[cellI];
scalar minDistance = GREAT;
label minFaceID = -1;
forAll (cellFaces, i)
{
label faceI = cellFaces[i];
vector dist = mesh.faceCentres()[faceI] - cellCentre;
if (mag(dist) < minDistance)
{
minDistance = mag(dist);
minFaceID = faceI;
}
}
faceList_[probeI] = minFaceID;
}
else
{
faceList_[probeI] = -1;
}
if (debug && (elementList_[probeI] != -1 || faceList_[probeI] != -1))
{
Pout<< "probes : found point " << location
<< " in cell " << elementList_[probeI] << endl;
<< " in cell " << elementList_[probeI]
<< " and face " << faceList_[probeI] << endl;
}
}
@ -60,25 +89,36 @@ void Foam::probes::findElements(const fvMesh& mesh)
{
const vector& location = operator[](probeI);
label cellI = elementList_[probeI];
label faceI = faceList_[probeI];
// Check at least one processor with cell.
reduce(cellI, maxOp<label>());
reduce(faceI, maxOp<label>());
if (cellI == -1)
{
if (Pstream::master())
{
WarningIn("probes::read()")
WarningIn("findElements::findElements(const fvMesh&)")
<< "Did not find location " << location
<< " in any cell. Skipping location." << endl;
}
}
else if (faceI == -1)
{
if (Pstream::master())
{
WarningIn("probes::findElements(const fvMesh&)")
<< "Did not find location " << location
<< " in any face. Skipping location." << endl;
}
}
else
{
// Make sure location not on two domains.
if (elementList_[probeI] != -1 && elementList_[probeI] != cellI)
{
WarningIn("probes::read()")
WarningIn("probes::findElements(const fvMesh&)")
<< "Location " << location
<< " seems to be on multiple domains:"
<< " cell " << elementList_[probeI]
@ -89,6 +129,20 @@ void Foam::probes::findElements(const fvMesh& mesh)
<< " a processor patch. Change the location slightly"
<< " to prevent this." << endl;
}
if (faceList_[probeI] != -1 && faceList_[probeI] != faceI)
{
WarningIn("probes::findElements(const fvMesh&)")
<< "Location " << location
<< " seems to be on multiple domains:"
<< " cell " << faceList_[probeI]
<< " on my domain " << Pstream::myProcNo()
<< " and face " << faceI << " on some other domain."
<< endl
<< "This might happen if the probe location is on"
<< " a processor patch. Change the location slightly"
<< " to prevent this." << endl;
}
}
}
}
@ -109,6 +163,12 @@ Foam::label Foam::probes::prepare()
currentFields.insert(symmTensorFields_);
currentFields.insert(tensorFields_);
currentFields.insert(surfaceScalarFields_);
currentFields.insert(surfaceVectorFields_);
currentFields.insert(surfaceSphericalTensorFields_);
currentFields.insert(surfaceSymmTensorFields_);
currentFields.insert(surfaceTensorFields_);
if (debug)
{
Info<< "Probing fields:" << currentFields << nl
@ -239,6 +299,12 @@ void Foam::probes::write()
sampleAndWrite(sphericalTensorFields_);
sampleAndWrite(symmTensorFields_);
sampleAndWrite(tensorFields_);
sampleAndWriteSurfaceFields(surfaceScalarFields_);
sampleAndWriteSurfaceFields(surfaceVectorFields_);
sampleAndWriteSurfaceFields(surfaceSphericalTensorFields_);
sampleAndWriteSurfaceFields(surfaceSymmTensorFields_);
sampleAndWriteSurfaceFields(surfaceTensorFields_);
}
}

View File

@ -42,7 +42,8 @@ SourceFiles
#include "polyMesh.H"
#include "pointField.H"
#include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
#include "surfaceMesh.H"
#include "wordReList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -104,16 +105,26 @@ protected:
// Calculated
//- Categorized scalar/vector/tensor fields
//- Categorized scalar/vector/tensor vol fields
fieldGroup<scalar> scalarFields_;
fieldGroup<vector> vectorFields_;
fieldGroup<sphericalTensor> sphericalTensorFields_;
fieldGroup<symmTensor> symmTensorFields_;
fieldGroup<tensor> tensorFields_;
//- Categorized scalar/vector/tensor surf fields
fieldGroup<scalar> surfaceScalarFields_;
fieldGroup<vector> surfaceVectorFields_;
fieldGroup<sphericalTensor> surfaceSphericalTensorFields_;
fieldGroup<symmTensor> surfaceSymmTensorFields_;
fieldGroup<tensor> surfaceTensorFields_;
// Cells to be probed (obtained from the locations)
labelList elementList_;
// Faces to be probed
labelList faceList_;
//- Current open files
HashPtrTable<OFstream> probeFilePtrs_;
@ -145,10 +156,22 @@ private:
const GeometricField<Type, fvPatchField, volMesh>&
);
//- Sample and write a particular surface field
template<class Type>
void sampleAndWrite
(
const GeometricField<Type, fvsPatchField, surfaceMesh>&
);
//- Sample and write all the fields of the given type
template<class Type>
void sampleAndWrite(const fieldGroup<Type>&);
//- Sample and write all the surface fields of the given type
template<class Type>
void sampleAndWriteSurfaceFields(const fieldGroup<Type>&);
//- Disallow default bitwise copy construct
probes(const probes&);
@ -242,9 +265,21 @@ public:
const GeometricField<Type, fvPatchField, volMesh>&
) const;
//- Sample a single field on all sample locations
//- Sample a single vol field on all sample locations
template <class Type>
tmp<Field<Type> > sample(const word& fieldName) const;
//- Sample a single scalar field on all sample locations
template <class Type>
tmp<Field<Type> > sampleSurfaceFields(const word& fieldName) const;
//- Sample a surface field at all locations
template<class Type>
tmp<Field<Type> > sample
(
const GeometricField<Type, fvsPatchField, surfaceMesh>&
) const;
};

View File

@ -25,6 +25,7 @@ License
#include "probes.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "IOobjectList.H"
#include "stringListOps.H"
@ -37,6 +38,12 @@ void Foam::probes::clearFieldGroups()
sphericalTensorFields_.clear();
symmTensorFields_.clear();
tensorFields_.clear();
surfaceScalarFields_.clear();
surfaceVectorFields_.clear();
surfaceSphericalTensorFields_.clear();
surfaceSymmTensorFields_.clear();
surfaceTensorFields_.clear();
}
@ -71,6 +78,31 @@ Foam::label Foam::probes::appendFieldGroup
tensorFields_.append(fieldName);
return 1;
}
else if (fieldType == surfaceScalarField::typeName)
{
surfaceScalarFields_.append(fieldName);
return 1;
}
else if (fieldType == surfaceVectorField::typeName)
{
surfaceVectorFields_.append(fieldName);
return 1;
}
else if (fieldType == surfaceSphericalTensorField::typeName)
{
surfaceSphericalTensorFields_.append(fieldName);
return 1;
}
else if (fieldType == surfaceSymmTensorField::typeName)
{
surfaceSymmTensorFields_.append(fieldName);
return 1;
}
else if (fieldType == surfaceTensorField::typeName)
{
surfaceTensorFields_.append(fieldName);
return 1;
}
return 0;
}

View File

@ -25,6 +25,7 @@ License
#include "probes.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "IOmanip.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -86,11 +87,32 @@ void Foam::probes::sampleAndWrite
}
template <class Type>
template<class Type>
void Foam::probes::sampleAndWrite
(
const fieldGroup<Type>& fields
const GeometricField<Type, fvsPatchField, surfaceMesh>& vField
)
{
Field<Type> values(sample(vField));
if (Pstream::master())
{
unsigned int w = IOstream::defaultPrecision() + 7;
OFstream& os = *probeFilePtrs_[vField.name()];
os << setw(w) << vField.time().value();
forAll(values, probeI)
{
os << ' ' << setw(w) << values[probeI];
}
os << endl;
}
}
template <class Type>
void Foam::probes::sampleAndWrite(const fieldGroup<Type>& fields)
{
forAll(fields, fieldI)
{
@ -138,6 +160,54 @@ void Foam::probes::sampleAndWrite
}
template<class Type>
void Foam::probes::sampleAndWriteSurfaceFields(const fieldGroup<Type>& fields)
{
forAll(fields, fieldI)
{
if (loadFromFiles_)
{
sampleAndWrite
(
GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fields[fieldI],
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
),
mesh_
)
);
}
else
{
objectRegistry::const_iterator iter = mesh_.find(fields[fieldI]);
if
(
iter != objectRegistry::end()
&& iter()->type()
== GeometricField<Type, fvsPatchField, surfaceMesh>::typeName
)
{
sampleAndWrite
(
mesh_.lookupObject
<GeometricField<Type, fvsPatchField, surfaceMesh> >
(
fields[fieldI]
)
);
}
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
@ -185,4 +255,48 @@ Foam::probes::sample(const word& fieldName) const
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::probes::sample
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& vField
) const
{
const Type unsetVal(-VGREAT*pTraits<Type>::one);
tmp<Field<Type> > tValues
(
new Field<Type>(this->size(), unsetVal)
);
Field<Type>& values = tValues();
forAll(*this, probeI)
{
if (faceList_[probeI] >= 0)
{
values[probeI] = vField[faceList_[probeI]];
}
}
Pstream::listCombineGather(values, isNotEqOp<Type>());
Pstream::listCombineScatter(values);
return tValues;
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::probes::sampleSurfaceFields(const word& fieldName) const
{
return sample
(
mesh_.lookupObject<GeometricField<Type, fvsPatchField, surfaceMesh> >
(
fieldName
)
);
}
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (3.1 0 0);
boundaryField
{
outlet
{
type inletOutlet;
inletValue uniform (0 0 0);
inlet uniform (0 0 0);
}
inlet
{
type fixedValue;
value uniform (3.1 0 0);
}
up
{
type symmetryPlane;
}
hole
{
type fixedValue;
value uniform (0 0 0);
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object kl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [ 0 2 -2 0 0 0 0 ];
internalField uniform 0;
boundaryField
{
inlet
{
type fixedValue;
value uniform 0;
}
outlet
{
type inletOutlet;
inletValue uniform 0;
value uniform 0;
}
up
{
type symmetryPlane;
}
hole
{
type fixedValue;
value uniform 0;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object kt;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [ 0 2 -2 0 0 0 0 ];
internalField uniform 0;
boundaryField
{
inlet
{
type fixedValue;
value uniform 0;
}
outlet
{
type inletOutlet;
inletValue uniform 0;
value uniform 0;
}
up
{
type symmetryPlane;
}
hole
{
type fixedValue;
value uniform 0;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object nut;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [ 0 2 -1 0 0 0 0 ];
internalField uniform 0;
boundaryField
{
inlet
{
type calculated;
value uniform 0;
}
outlet
{
type calculated;
value uniform 0;
}
up
{
type symmetryPlane;
}
hole
{
type nutLowReWallFunction;
value uniform 0;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object omega;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [ 0 0 -1 0 0 0 0 ];
internalField uniform 1e-5;
boundaryField
{
inlet
{
type fixedValue;
value $internalField;
}
outlet
{
type inletOutlet;
inletValue $internalField;
value $internalField;
}
up
{
type symmetryPlane;
}
hole
{
type fixedValue;
value $internalField;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,46 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 0;
boundaryField
{
inlet
{
type zeroGradient;
}
outlet
{
type fixedValue;
value uniform 0;
}
up
{
type symmetryPlane;
}
hole
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,10 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial clean functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
cleanCase
rm -rf 0/polyMesh
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,29 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
# Get application directory
application=`getApplication`
runApplication blockMesh
transformPoints -scale '(1.6666 1 1)'
cp system/changeDictionaryDict.X system/changeDictionaryDict
runApplication changeDictionary -instance system
runApplication mirrorMesh
rm log.mirrorMesh
rm log.changeDictionary
cp system/changeDictionaryDict.Y system/changeDictionaryDict
runApplication changeDictionary -instance system
runApplication mirrorMesh
cp -rf 0/polyMesh constant/
runApplication topoSet
runApplication createPatch -overwrite
runApplication $application
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,25 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object RASProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
RASModel kkLOmega;
turbulence on;
printCoeffs on;
// ************************************************************************* //

View File

@ -0,0 +1,136 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 0.1;
vertices
(
(0.5 0 0) //0
(2 0 0) //1
(5 0 0) //2
(5 1.414214 0) //3
(1.414214 1.414214 0) //4
(0.353553 0.353553 0) //5
(5 3 0) //6
(1.414214 3 0) //7
(0 3 0) //8
(0 2 0) //9
(0 0.5 0) //10
(0.5 0 0.5) //11
(2 0 0.5) //12
(5 0 0.5) //13
(5 1.414214 0.5) //14
(1.414214 1.414214 0.5) //15
(0.353553 0.353553 0.5) //16
(5 3 0.5) //17
(1.414214 3 0.5) //18
(0 3 0.5) //19
(0 2 0.5) //20
(0 0.5 0.5) //21
);
blocks
(
hex (5 4 9 10 16 15 20 21) (70 70 1) simpleGrading (17 1 1)
hex (0 1 4 5 11 12 15 16) (70 70 1) simpleGrading (17 1 1)
hex (1 2 3 4 12 13 14 15) (25 70 1) simpleGrading (3 1 1)
hex (4 3 6 7 15 14 17 18) (25 10 1) simpleGrading (3 2 1)
hex (9 4 7 8 20 15 18 19) (70 10 1) simpleGrading (1 2 1)
);
edges
(
arc 0 5 (0.469846 0.17101 0)
arc 5 10 (0.17101 0.469846 0)
arc 1 4 (1.87938 0.68404 0)
arc 4 9 (0.68404 1.87938 0)
arc 11 16 (0.469846 0.17101 0.5)
arc 16 21 (0.17101 0.469846 0.5)
arc 12 15 (1.87938 0.68404 0.5)
arc 15 20 (0.68404 1.87938 0.5)
);
boundary
(
left
{
type symmetryPlane;
faces
(
(8 9 20 19)
(9 10 21 20)
);
}
outlet
{
type patch;
faces
(
(2 3 14 13)
(3 6 17 14)
);
}
down
{
type symmetryPlane;
faces
(
(0 1 12 11)
(1 2 13 12)
);
}
up
{
type symmetryPlane;
faces
(
(7 8 19 18)
(6 7 18 17)
);
}
hole
{
type wall;
faces
(
(10 5 16 21)
(5 0 11 16)
);
}
frontAndBack
{
type empty;
faces
(
(10 9 4 5)
(5 4 1 0)
(1 4 3 2)
(4 7 6 3)
(4 9 8 7)
(21 16 15 20)
(16 11 12 15)
(12 13 14 15)
(15 14 17 18)
(15 18 19 20)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1,46 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class polyBoundaryMesh;
location "0/polyMesh";
object boundary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
4
(
outlet
{
type patch;
nFaces 320;
startFace 99370;
}
up
{
type symmetryPlane;
nFaces 380;
startFace 99690;
}
hole
{
type wall;
nFaces 560;
startFace 100070;
}
frontAndBack
{
type empty;
nFaces 100000;
startFace 100630;
}
)
// ************************************************************************* //

View File

@ -0,0 +1,39 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
transportModel Newtonian;
nu nu [ 0 2 -1 0 0 0 0 ] 1.86e-05;
CrossPowerLawCoeffs
{
nu0 nu0 [ 0 2 -1 0 0 0 0 ] 1e-06;
nuInf nuInf [ 0 2 -1 0 0 0 0 ] 1e-06;
m m [ 0 0 1 0 0 0 0 ] 1;
n n [ 0 0 0 0 0 0 0 ] 1;
}
BirdCarreauCoeffs
{
nu0 nu0 [ 0 2 -1 0 0 0 0 ] 1e-06;
nuInf nuInf [ 0 2 -1 0 0 0 0 ] 1e-06;
k k [ 0 0 1 0 0 0 0 ] 0;
n n [ 0 0 0 0 0 0 0 ] 1;
}
// ************************************************************************* //

View File

@ -0,0 +1,20 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType RASModel;
// ************************************************************************* //

View File

@ -0,0 +1,28 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object changeDictionaryDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dictionaryReplacement
{
mirrorMeshDict
{
pointAndNormalDict
{
basePoint (0 0 0);
normalVector (0 -1 0);
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,28 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object changeDictionaryDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dictionaryReplacement
{
mirrorMeshDict
{
pointAndNormalDict
{
basePoint (0 0 0);
normalVector (-1 0 0);
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,28 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object changeDictionaryDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dictionaryReplacement
{
mirrorMeshDict
{
pointAndNormalDict
{
basePoint (0 0 0);
normalVector (0 -1 0);
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,52 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application pimpleFoam;
startFrom latestTime;
startTime 0;
stopAt endTime;
endTime 0.5;
deltaT 0.001;
writeControl adjustableRunTime;
writeInterval 0.01;
purgeWrite 0;
writeFormat ascii;
writePrecision 6;
writeCompression uncompressed;
timeFormat general;
timePrecision 6;
runTimeModifiable true;
adjustTimeStep yes;
maxCo 0.2;
// ************************************************************************* //

View File

@ -0,0 +1,39 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object createPatchDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
pointSync false;
patches
(
{
// Name of new patch
name inlet;
// Dictionary to construct new patch from
patchInfo
{
type patch;
}
// How to construct: either from 'patches' or 'set'
constructFrom set;
// If constructFrom = set : name of faceSet
set f0;
}
);
// ************************************************************************* //

View File

@ -0,0 +1,74 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
grad(p) Gauss linear;
grad(U) Gauss linear;
}
divSchemes
{
default none;
div(phi,U) Gauss limitedLinearV 1;
div(phi,kl) Gauss limitedLinear 1;
div(phi,kt) Gauss limitedLinear 1;
div(phi,omega) Gauss limitedLinear 1;
div(phi,R) Gauss limitedLinear 1;
div(R) Gauss linear;
div(phi,nuTilda) Gauss limitedLinear 1;
div((nuEff*dev(T(grad(U))))) Gauss linear;
}
laplacianSchemes
{
default none;
laplacian(nuEff,U) Gauss linear corrected;
laplacian((1|A(U)),p) Gauss linear corrected;
laplacian(alphaTEff,omega) Gauss linear corrected;
laplacian(alphaTEff,kt) Gauss linear corrected;
laplacian(nu,kl) Gauss linear corrected;
laplacian(DepsilonEff,epsilon) Gauss linear corrected;
laplacian(DREff,R) Gauss linear corrected;
laplacian(DnuTildaEff,nuTilda) Gauss linear corrected;
}
interpolationSchemes
{
default linear;
interpolate(U) linear;
}
snGradSchemes
{
default corrected;
}
fluxRequired
{
default no;
p ;
}
// ************************************************************************* //

View File

@ -0,0 +1,83 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
p
{
solver GAMG;
tolerance 1e-06;
relTol 0.01;
smoother GaussSeidel;
cacheAgglomeration true;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;
}
pFinal
{
solver GAMG;
tolerance 1e-06;
relTol 0;
smoother GaussSeidel;
cacheAgglomeration true;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;
}
"(U|kl|kt|omega)"
{
solver PBiCG;
preconditioner DILU;
tolerance 1e-06;
relTol 0.01;
}
"(U|kl|kt|omega)Final"
{
$U;
tolerance 1e-06;
relTol 0;
}
}
PIMPLE
{
nOuterCorrectors 1;
nCorrectors 2;
nNonOrthogonalCorrectors 0;
pRefCell 0;
pRefValue 0;
}
relaxationFactors
{
fields
{
}
equations
{
"U.*" 1;
"kl.*" 1;
"kt.*" 1;
"omega.*" 1;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,29 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object mirrorMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
planeType pointAndNormal;
pointAndNormalDict
{
basePoint ( 0 0 0 );
normalVector ( 0 -1 0 );
}
planeTolerance 1e-06;
// ************************************************************************* //

View File

@ -0,0 +1,32 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object topoSetDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
actions
(
{
name f0;
type faceSet;
action new;
source boxToFace;
sourceInfo
{
box (-0.84 -0.31 -0.01)(-0.82 0.31 0.06);
}
}
);
// ************************************************************************* //

View File

@ -14,6 +14,13 @@ FoamFile
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
libs
(
"libOpenFOAM.so"
"libincompressibleTurbulenceModel.so"
"libincompressibleRASModels.so"
);
application simpleFoam;
startFrom latestTime;