Merging master, fixing conflict in searchableBox.C

This commit is contained in:
graham
2009-06-18 15:26:01 +01:00
775 changed files with 31691 additions and 7312 deletions

View File

@ -816,6 +816,8 @@ int main(int argc, char *argv[])
// Pre-filtering: flip "owner" boundary or wrong oriented internal
// faces and move to neighbour
boolList fm(faces.size(), false);
forAll (faces, facei)
{
if
@ -824,6 +826,7 @@ int main(int argc, char *argv[])
|| (neighbour[facei] != -1 && owner[facei] > neighbour[facei])
)
{
fm[facei] = true;
faces[facei] = faces[facei].reverseFace();
Swap(owner[facei], neighbour[facei]);
}
@ -1175,7 +1178,7 @@ int main(int argc, char *argv[])
false, // flipFaceFlux
-1, // patchID
faceZonei, // zoneID
false // zoneFlip
fm[facei] // zoneFlip
);
}

View File

@ -1077,7 +1077,7 @@ void Foam::meshDualiser::setRefinement
{
label pointI = multiCellFeaturePoints[i];
if (pointToDualCells_[pointI].size())
if (pointToDualCells_[pointI].size() > 0)
{
FatalErrorIn
(

View File

@ -25,22 +25,34 @@ License
Description
Calculate the dual of a polyMesh. Adheres to all the feature&patch edges.
Feature angle:
convex features : point becomes single boundary cell with multiple
boundary faces.
concave features: point becomes multiple boundary cells.
-splitAllFaces:
Usage
- polyDualMesh featureAngle
Detects any boundary edge > angle and creates multiple boundary faces
for it. Normal behaviour is to have each point become a cell
(1.5 behaviour)
@param -concaveMultiCells
Creates multiple cells for each point on a concave edge. Might limit
the amount of distortion on some meshes.
@param -splitAllFaces
Normally only constructs a single face between two cells. This single face
might be too distorted. splitAllFaces will create a single face for every
original cell the face passes through. The mesh will thus have
multiple faces inbetween two cells! (so is not strictly upper-triangular
anymore - checkMesh will complain)
-doNotPreserveFaceZones:
@param -doNotPreserveFaceZones:
By default all faceZones are preserved by marking all faces, edges and
points on them as features. The -doNotPreserveFaceZones disables this
behaviour.
Note: is just a driver for meshDualiser. Substitute your own
simpleMarkFeatures to have different behaviour.
\*---------------------------------------------------------------------------*/
#include "argList.H"
@ -70,6 +82,7 @@ void simpleMarkFeatures
const polyMesh& mesh,
const PackedBoolList& isBoundaryEdge,
const scalar featureAngle,
const bool concaveMultiCells,
const bool doNotPreserveFaceZones,
labelList& featureFaces,
@ -182,7 +195,7 @@ void simpleMarkFeatures
- allBoundary[f0].centre(allBoundary.points())
);
if ((c1c0 & n0) > SMALL)
if (concaveMultiCells && (c1c0 & n0) > SMALL)
{
// Found concave edge. Make into multiCell features
Info<< "Detected concave feature edge:" << edgeI
@ -230,7 +243,7 @@ void simpleMarkFeatures
if (doNotPreserveFaceZones)
{
if (faceZones.size())
if (faceZones.size() > 0)
{
WarningIn("simpleMarkFeatures(..)")
<< "Detected " << faceZones.size()
@ -240,7 +253,7 @@ void simpleMarkFeatures
}
else
{
if (faceZones.size())
if (faceZones.size() > 0)
{
Info<< "Detected " << faceZones.size()
<< " faceZones. Preserving these by marking their"
@ -345,6 +358,7 @@ int main(int argc, char *argv[])
argList::validArgs.append("feature angle[0-180]");
argList::validOptions.insert("splitAllFaces", "");
argList::validOptions.insert("concaveMultiCells", "");
argList::validOptions.insert("doNotPreserveFaceZones", "");
argList::validOptions.insert("overwrite", "");
@ -381,11 +395,25 @@ int main(int argc, char *argv[])
const bool splitAllFaces = args.optionFound("splitAllFaces");
if (splitAllFaces)
{
Info<< "Splitting all internal faces to create multiple faces"
<< " between two cells." << nl
<< endl;
}
const bool overwrite = args.optionFound("overwrite");
const bool doNotPreserveFaceZones = args.optionFound
(
"doNotPreserveFaceZones"
);
const bool concaveMultiCells = args.optionFound("concaveMultiCells");
if (concaveMultiCells)
{
Info<< "Generating multiple cells for points on concave feature edges."
<< nl << endl;
}
// Face(centre)s that need inclusion in the dual mesh
labelList featureFaces;
@ -393,7 +421,7 @@ int main(int argc, char *argv[])
labelList featureEdges;
// Points (that become a single cell) that need inclusion in the dual mesh
labelList singleCellFeaturePoints;
// Points (that become a mulitple cells) ,,
// Points (that become a multiple cells) ,,
labelList multiCellFeaturePoints;
// Sample implementation of feature detection.
@ -402,6 +430,7 @@ int main(int argc, char *argv[])
mesh,
isBoundaryEdge,
featureAngle,
concaveMultiCells,
doNotPreserveFaceZones,
featureFaces,

View File

@ -23,7 +23,8 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Extrude mesh from existing patch or from patch read from file.
Extrude mesh from existing patch (flipped so has inwards pointing
normals) or from patch read from file.
Note: Merges close points so be careful.
Type of extrusion prescribed by run-time selectable model.
@ -52,43 +53,34 @@ using namespace Foam;
int main(int argc, char *argv[])
{
#include "setRoots.H"
#include "setRootCase.H"
#include "createTimeExtruded.H"
if (args.optionFound("sourceCase") == args.optionFound("surface"))
{
FatalErrorIn(args.executable())
<< "Specify either -sourceCase and -sourcePatch"
" or -surface options\n"
" to specify the source of the patch to extrude"
<< exit(FatalError);
}
autoPtr<extrudedMesh> meshPtr(NULL);
autoPtr<extrudeModel> model
IOdictionary dict
(
extrudeModel::New
IOobject
(
IOdictionary
(
IOobject
(
"extrudeProperties",
runTimeExtruded.constant(),
runTimeExtruded,
IOobject::MUST_READ
)
)
"extrudeProperties",
runTimeExtruded.constant(),
runTimeExtruded,
IOobject::MUST_READ
)
);
if (args.optionFound("sourceCase"))
autoPtr<extrudeModel> model(extrudeModel::New(dict));
const word sourceType(dict.lookup("constructFrom"));
autoPtr<faceMesh> fMesh;
if (sourceType == "patch")
{
fileName sourceCasePath(args.option("sourceCase"));
fileName sourceCasePath(dict.lookup("sourceCase"));
fileName sourceRootDir = sourceCasePath.path();
fileName sourceCaseDir = sourceCasePath.name();
word patchName(args.option("sourcePatch"));
word patchName(dict.lookup("sourcePatch"));
Info<< "Extruding patch " << patchName
<< " on mesh " << sourceCasePath << nl
@ -114,75 +106,69 @@ int main(int argc, char *argv[])
}
const polyPatch& pp = mesh.boundaryMesh()[patchID];
fMesh.reset(new faceMesh(pp.localFaces(), pp.localPoints()));
fMesh().flip();
{
fileName surfName(patchName + ".sMesh");
Info<< "Writing patch as surfaceMesh to " << surfName << nl << endl;
faceMesh fMesh(pp.localFaces(), pp.localPoints());
Info<< "Writing (flipped) patch as surfaceMesh to "
<< surfName << nl << endl;
OFstream os(surfName);
os << fMesh << nl;
os << fMesh() << nl;
}
meshPtr.reset
(
new extrudedMesh
(
IOobject
(
extrudedMesh::defaultRegion,
runTimeExtruded.constant(),
runTimeExtruded
),
pp,
model()
)
);
}
else
else if (sourceType == "surface")
{
// Read from surface
fileName surfName(args.option("surface"));
fileName surfName(dict.lookup("surface"));
Info<< "Extruding surfaceMesh read from file " << surfName << nl
<< endl;
IFstream is(surfName);
faceMesh fMesh(is);
fMesh.reset(new faceMesh(is));
Info<< "Read patch from file " << surfName << ':' << nl
<< " points : " << fMesh.points().size() << nl
<< " faces : " << fMesh.size() << nl
Info<< "Read patch from file " << surfName << nl
<< endl;
}
else
{
FatalErrorIn(args.executable())
<< "Illegal 'constructFrom' specification. Should either be "
<< "patch or surface." << exit(FatalError);
}
Info<< "Extruding patch with :" << nl
<< " points : " << fMesh().points().size() << nl
<< " faces : " << fMesh().size() << nl
<< " normals[0] : " << fMesh().faceNormals()[0]
<< nl
<< endl;
meshPtr.reset
extrudedMesh mesh
(
IOobject
(
new extrudedMesh
(
IOobject
(
extrudedMesh::defaultRegion,
runTimeExtruded.constant(),
runTimeExtruded
),
fMesh,
model()
)
);
}
extrudedMesh& mesh = meshPtr();
extrudedMesh::defaultRegion,
runTimeExtruded.constant(),
runTimeExtruded
),
fMesh(),
model()
);
const boundBox& bb = mesh.globalData().bb();
const vector span = bb.span();
const scalar mergeDim = 1E-4 * bb.minDim();
Info<< "Mesh bounding box:" << bb << nl
<< " with span:" << span << nl
<< "Merge distance :" << mergeDim << nl
Info<< "Mesh bounding box : " << bb << nl
<< " with span : " << span << nl
<< "Merge distance : " << mergeDim << nl
<< endl;
const polyBoundaryMesh& patches = mesh.boundaryMesh();
@ -250,7 +236,8 @@ int main(int argc, char *argv[])
// Merging front and back patch faces
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (args.optionFound("mergeFaces"))
Switch mergeFaces(dict.lookup("mergeFaces"));
if (mergeFaces)
{
Info<< "Assuming full 360 degree axisymmetric case;"
<< " stitching faces on patches "

View File

@ -88,7 +88,8 @@ point wedge::operator()
}
else
{
sliceAngle = angle_*(layer + 1)/nLayers_;
//sliceAngle = angle_*(layer + 1)/nLayers_;
sliceAngle = angle_*layer/nLayers_;
}
// Find projection onto axis (or rather decompose surfacePoint

View File

@ -14,23 +14,41 @@ FoamFile
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
extrudeModel wedge;
// Where to get surface from: either from surface ('surface') or
// from (flipped) patch of existing case ('patch')
constructFrom patch; //surface;
// If construct from (flipped) patch
sourceCase "../cavity";
sourcePatch movingWall;
// If construct from surface
surface "movingWall.sMesh";
// Do front and back need to be merged?
mergeFaces false;
//- Linear extrusion in point-normal direction
//extrudeModel linearNormal;
//- Wedge extrusion. If nLayers is 1 assumes symmetry around plane.
extrudeModel wedge;
//- Extrudes into sphere around (0 0 0)
//extrudeModel linearRadial;
//extrudeModel sigmaRadial;
nLayers 1;
nLayers 6;
wedgeCoeffs
{
axisPt (0 0 0);
axis (0 -1 0);
angle 2.0;
axisPt (0 0.1 0);
axis (1 0 0);
angle 90.0; // For nLayers=1 assume symmetry so angle/2 on each side
}
linearNormalCoeffs
{
thickness 0.1;
thickness 0.05;
}
linearRadialCoeffs
@ -47,3 +65,4 @@ sigmaRadialCoeffs
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -117,7 +117,7 @@ Foam::Xfer<Foam::faceList> Foam::extrudedMesh::extrudedFaces
quad[2] = surfaceEdges[i][0] + nextLayerOffset;
quad[3] = surfaceEdges[i][1] + nextLayerOffset;
eFaces[facei++] = face(quad);
eFaces[facei++] = face(quad).reverseFace();
}
// Faces between layer and layer+1
@ -130,7 +130,7 @@ Foam::Xfer<Foam::faceList> Foam::extrudedMesh::extrudedFaces
(
surfaceFaces[i].reverseFace()
+ nextLayerOffset
);
).reverseFace();
}
}
}
@ -152,7 +152,7 @@ Foam::Xfer<Foam::faceList> Foam::extrudedMesh::extrudedFaces
label ownerFace = extrudePatch.edgeFaces()[i][0];
if (!sameOrder(surfaceFaces[ownerFace], e))
if (sameOrder(surfaceFaces[ownerFace], e))
{
reverse(quad);
}
@ -164,7 +164,7 @@ Foam::Xfer<Foam::faceList> Foam::extrudedMesh::extrudedFaces
// Top faces
forAll(surfaceFaces, i)
{
eFaces[facei++] = face(surfaceFaces[i]);
eFaces[facei++] = face(surfaceFaces[i]).reverseFace();
}
// Bottom faces
@ -175,7 +175,7 @@ Foam::Xfer<Foam::faceList> Foam::extrudedMesh::extrudedFaces
(
surfaceFaces[i].reverseFace()
+ nLayers*surfacePoints.size()
);
).reverseFace();
}
// return points for transferring

View File

@ -78,6 +78,18 @@ public:
{}
// Member Functions
void flip()
{
forAll(*this, i)
{
face& f = operator[](i);
f = f.reverseFace();
}
clearOut();
}
// IOstream Operators
friend Ostream& operator<<(Ostream& os, const faceMesh& fm)
@ -85,7 +97,8 @@ public:
return os
<< fm.points()
<< token::NL
<< static_cast<PrimitivePatch<face, Foam::List, pointField> >(fm);
<< static_cast<PrimitivePatch<face, Foam::List, pointField> >
(fm);
}
};

View File

@ -96,7 +96,7 @@ void writeMesh
const fvMesh& mesh = meshRefiner.mesh();
meshRefiner.printMeshInfo(debug, msg);
Info<< "Writing mesh to time " << mesh.time().timeName() << endl;
Info<< "Writing mesh to time " << meshRefiner.timeName() << endl;
meshRefiner.write(meshRefinement::MESH|meshRefinement::SCALARLEVELS, "");
if (debug & meshRefinement::OBJINTERSECTIONS)
@ -104,7 +104,7 @@ void writeMesh
meshRefiner.write
(
meshRefinement::OBJINTERSECTIONS,
mesh.time().path()/mesh.time().timeName()
mesh.time().path()/meshRefiner.timeName()
);
}
Info<< "Written mesh in = "
@ -115,6 +115,7 @@ void writeMesh
int main(int argc, char *argv[])
{
argList::validOptions.insert("overwrite", "");
# include "setRootCase.H"
# include "createTime.H"
runTime.functionObjects().off();
@ -123,6 +124,9 @@ int main(int argc, char *argv[])
Info<< "Read mesh in = "
<< runTime.cpuTimeIncrement() << " s" << endl;
const bool overwrite = args.optionFound("overwrite");
// Check patches and faceZones are synchronised
mesh.boundaryMesh().checkParallelSync(true);
meshRefinement::checkCoupledFaceZones(mesh);
@ -170,6 +174,13 @@ int main(int argc, char *argv[])
const dictionary& layerDict = meshDict.subDict("addLayersControls");
const scalar mergeDist = getMergeDistance
(
mesh,
readScalar(meshDict.lookup("mergeTolerance"))
);
// Debug
// ~~~~~
@ -192,8 +203,9 @@ int main(int argc, char *argv[])
IOobject
(
"abc", // dummy name
mesh.time().constant(), // directory
"triSurface", // instance
//mesh.time().constant(), // instance
mesh.time().findInstance("triSurface", word::null),// instance
"triSurface", // local
mesh.time(), // registry
IOobject::MUST_READ,
IOobject::NO_WRITE
@ -235,6 +247,34 @@ int main(int argc, char *argv[])
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
// Refinement engine
// ~~~~~~~~~~~~~~~~~
Info<< nl
<< "Determining initial surface intersections" << nl
<< "-----------------------------------------" << nl
<< endl;
// Main refinement engine
meshRefinement meshRefiner
(
mesh,
mergeDist, // tolerance used in sorting coordinates
overwrite, // overwrite mesh files?
surfaces, // for surface intersection refinement
shells // for volume (inside/outside) refinement
);
Info<< "Calculated surface intersections in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
// Some stats
meshRefiner.printMeshInfo(debug, "Initial mesh");
meshRefiner.write
(
debug&meshRefinement::OBJINTERSECTIONS,
mesh.time().path()/meshRefiner.timeName()
);
// Add all the surface regions as patches
@ -265,9 +305,8 @@ int main(int argc, char *argv[])
forAll(regNames, i)
{
label patchI = meshRefinement::addPatch
label patchI = meshRefiner.addMeshedPatch
(
mesh,
regNames[i],
wallPolyPatch::typeName
);
@ -308,45 +347,10 @@ int main(int argc, char *argv[])
<< exit(FatalError);
}
const scalar mergeDist = getMergeDistance
(
mesh,
readScalar(meshDict.lookup("mergeTolerance"))
);
// Mesh distribution engine (uses tolerance to reconstruct meshes)
fvMeshDistribute distributor(mesh, mergeDist);
// Refinement engine
// ~~~~~~~~~~~~~~~~~
Info<< nl
<< "Determining initial surface intersections" << nl
<< "-----------------------------------------" << nl
<< endl;
// Main refinement engine
meshRefinement meshRefiner
(
mesh,
mergeDist, // tolerance used in sorting coordinates
surfaces, // for surface intersection refinement
shells // for volume (inside/outside) refinement
);
Info<< "Calculated surface intersections in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
// Some stats
meshRefiner.printMeshInfo(debug, "Initial mesh");
meshRefiner.write
(
debug&meshRefinement::OBJINTERSECTIONS,
mesh.time().path()/mesh.time().timeName()
);
@ -370,6 +374,11 @@ int main(int argc, char *argv[])
// Refinement parameters
refinementParameters refineParams(refineDict);
if (!overwrite)
{
const_cast<Time&>(mesh.time())++;
}
refineDriver.doRefine(refineDict, refineParams, wantSnap, motionDict);
writeMesh
@ -391,6 +400,11 @@ int main(int argc, char *argv[])
// Snap parameters
snapParameters snapParams(snapDict);
if (!overwrite)
{
const_cast<Time&>(mesh.time())++;
}
snapDriver.doSnap(snapDict, motionDict, snapParams);
writeMesh
@ -403,15 +417,16 @@ int main(int argc, char *argv[])
if (wantLayers)
{
autoLayerDriver layerDriver
(
meshRefiner,
globalToPatch
);
autoLayerDriver layerDriver(meshRefiner);
// Layer addition parameters
layerParameters layerParams(layerDict, mesh.boundaryMesh());
if (!overwrite)
{
const_cast<Time&>(mesh.time())++;
}
layerDriver.doLayers
(
layerDict,
@ -435,7 +450,7 @@ int main(int argc, char *argv[])
Info<< "End\n" << endl;
return 0;
return(0);
}

View File

@ -566,7 +566,7 @@ int main(int argc, char *argv[])
IOobject
(
"cellProcAddressing",
"constant",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
@ -579,7 +579,7 @@ int main(int argc, char *argv[])
IOobject
(
"boundaryProcAddressing",
"constant",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
@ -603,7 +603,7 @@ int main(int argc, char *argv[])
IOobject
(
"faceProcAddressing",
"constant",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
@ -645,7 +645,7 @@ int main(int argc, char *argv[])
IOobject
(
"pointProcAddressing",
"constant",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,

View File

@ -55,7 +55,17 @@ metisCoeffs
}
scotchCoeffs
{}
{
//processorWeights
//(
// 1
// 1
// 1
// 1
//);
//writeGraph true;
//strategy "b";
}
manualCoeffs
{

View File

@ -269,7 +269,7 @@ bool domainDecomposition::writeDecomposition()
IOobject
(
this->polyMesh::name(), // region name of undecomposed mesh
"constant",
pointsInstance(),
processorDb
),
xferMove(procPoints),
@ -620,7 +620,7 @@ bool domainDecomposition::writeDecomposition()
IOobject
(
"pointProcAddressing",
"constant",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
@ -635,7 +635,7 @@ bool domainDecomposition::writeDecomposition()
IOobject
(
"faceProcAddressing",
"constant",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
@ -650,7 +650,7 @@ bool domainDecomposition::writeDecomposition()
IOobject
(
"cellProcAddressing",
"constant",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
@ -665,7 +665,7 @@ bool domainDecomposition::writeDecomposition()
IOobject
(
"boundaryProcAddressing",
"constant",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,

View File

@ -56,13 +56,12 @@ processorVolPatchFieldDecomposer
const unallocLabelList& addressingSlice
)
:
addressing_(addressingSlice.size()),
weights_(addressingSlice.size())
directAddressing_(addressingSlice.size())
{
const labelList& own = mesh.faceOwner();
const labelList& neighb = mesh.faceNeighbour();
forAll (addressing_, i)
forAll (directAddressing_, i)
{
// Subtract one to align addressing.
label ai = mag(addressingSlice[i]) - 1;
@ -74,18 +73,14 @@ processorVolPatchFieldDecomposer
// on the parallel boundary.
// Give face the value of the neighbour.
addressing_[i].setSize(1);
weights_[i].setSize(1);
weights_[i][0] = 1.0;
if (addressingSlice[i] >= 0)
{
// I have the owner so use the neighbour value
addressing_[i][0] = neighb[ai];
directAddressing_[i] = neighb[ai];
}
else
{
addressing_[i][0] = own[ai];
directAddressing_[i] = own[ai];
}
}
else
@ -96,12 +91,7 @@ processorVolPatchFieldDecomposer
// up the different (face) list of data), so I will
// just grab the value from the owner cell
addressing_[i].setSize(1);
weights_[i].setSize(1);
addressing_[i][0] = own[ai];
weights_[i][0] = 1.0;
directAddressing_[i] = own[ai];
}
}
}

View File

@ -96,15 +96,16 @@ public:
};
//- Processor patch field decomposer class
//- Processor patch field decomposer class. Maps either owner or
// neighbour data (no interpolate anymore - processorFvPatchField
// holds neighbour data)
class processorVolPatchFieldDecomposer
:
public fvPatchFieldMapper
{
// Private data
labelListList addressing_;
scalarListList weights_;
labelList directAddressing_;
public:
@ -120,27 +121,23 @@ public:
label size() const
{
return addressing_.size();
return directAddressing_.size();
}
bool direct() const
{
return false;
return true;
}
const labelListList& addressing() const
const unallocLabelList& directAddressing() const
{
return addressing_;
}
const scalarListList& weights() const
{
return weights_;
return directAddressing_;
}
};
//- Processor patch field decomposer class
//- Processor patch field decomposer class. Surface field is assumed
// to have direction (so manipulates sign when mapping)
class processorSurfacePatchFieldDecomposer
:
public fvPatchFieldMapper

View File

@ -178,7 +178,6 @@ void writeAllDataBinary
}
template<class Type>
void writeAllFaceData
(
@ -275,7 +274,7 @@ template<class Type>
bool writePatchField
(
const Foam::Field<Type>& pf,
const Foam::label patchI,
const Foam::label patchi,
const Foam::label ensightPatchI,
const Foam::faceSets& boundaryFaceSet,
const Foam::ensightMesh::nFacePrimitives& nfp,
@ -335,7 +334,7 @@ template<class Type>
bool writePatchFieldBinary
(
const Foam::Field<Type>& pf,
const Foam::label patchI,
const Foam::label patchi,
const Foam::label ensightPatchI,
const Foam::faceSets& boundaryFaceSet,
const Foam::ensightMesh::nFacePrimitives& nfp,
@ -406,34 +405,27 @@ void writePatchField
const Time& runTime = eMesh.mesh().time();
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
const HashTable<labelList>& allPatchNames = eMesh.allPatchNames();
const HashTable<label>& patchIndices = eMesh.patchIndices();
const wordList& allPatchNames = eMesh.allPatchNames();
const List<labelList>& allPatchProcs = eMesh.allPatchProcs();
const HashTable<ensightMesh::nFacePrimitives>&
nPatchPrims = eMesh.nPatchPrims();
label patchI = -1;
if (patchIndices.found(patchName))
{
patchI = patchIndices.find(patchName)();
}
label ensightPatchI = eMesh.patchPartOffset();
for
(
HashTable<labelList>::const_iterator iter =
allPatchNames.begin();
iter != allPatchNames.end();
++iter
)
label patchi = -1;
forAll(allPatchNames, i)
{
if (iter.key() == patchName) break;
if (allPatchNames[i] == patchName)
{
patchi = i;
break;
}
ensightPatchI++;
}
const labelList& patchProcessors = allPatchNames.find(patchName)();
const labelList& patchProcessors = allPatchProcs[patchi];
word pfName = patchName + '.' + fieldName;
@ -472,14 +464,14 @@ void writePatchField
ensightFile << pTraits<Type>::typeName << nl;
}
if (patchI >= 0)
if (patchi >= 0)
{
writePatchField
(
pf,
patchI,
patchi,
ensightPatchI,
boundaryFaceSets[patchI],
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
patchProcessors,
ensightFile
@ -507,6 +499,7 @@ void writePatchField
}
}
template<class Type>
void ensightFieldAscii
(
@ -527,8 +520,8 @@ void ensightFieldAscii
const cellSets& meshCellSets = eMesh.meshCellSets();
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
const HashTable<labelList>& allPatchNames = eMesh.allPatchNames();
const HashTable<label>& patchIndices = eMesh.patchIndices();
const wordList& allPatchNames = eMesh.allPatchNames();
const List<labelList>& allPatchProcs = eMesh.allPatchProcs();
const wordHashSet& patchNames = eMesh.patchNames();
const HashTable<ensightMesh::nFacePrimitives>&
nPatchPrims = eMesh.nPatchPrims();
@ -623,30 +616,23 @@ void ensightFieldAscii
label ensightPatchI = eMesh.patchPartOffset();
for
(
HashTable<labelList>::const_iterator iter = allPatchNames.begin();
iter != allPatchNames.end();
++iter
)
forAll(allPatchNames, patchi)
{
const word& patchName = iter.key();
const labelList& patchProcessors = iter();
const word& patchName = allPatchNames[patchi];
const labelList& patchProcessors = allPatchProcs[patchi];
if (patchNames.empty() || patchNames.found(patchName))
{
if (patchIndices.found(patchName))
if (mesh.boundary()[patchi].size())
{
label patchI = patchIndices.find(patchName)();
if
(
writePatchField
(
vf.boundaryField()[patchI],
patchI,
vf.boundaryField()[patchi],
patchi,
ensightPatchI,
boundaryFaceSets[patchI],
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
patchProcessors,
ensightFile
@ -708,8 +694,8 @@ void ensightFieldBinary
const cellSets& meshCellSets = eMesh.meshCellSets();
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
const HashTable<labelList>& allPatchNames = eMesh.allPatchNames();
const HashTable<label>& patchIndices = eMesh.patchIndices();
const wordList& allPatchNames = eMesh.allPatchNames();
const List<labelList>& allPatchProcs = eMesh.allPatchProcs();
const wordHashSet& patchNames = eMesh.patchNames();
const HashTable<ensightMesh::nFacePrimitives>&
nPatchPrims = eMesh.nPatchPrims();
@ -726,7 +712,11 @@ void ensightFieldBinary
{
// set the filename of the ensight file
fileName ensightFileName(timeFile + "." + fieldObject.name());
ensightFilePtr = new std::ofstream((postProcPath/ensightFileName).c_str(), ios_base::out | ios_base::binary | ios_base::trunc);
ensightFilePtr = new std::ofstream
(
(postProcPath/ensightFileName).c_str(),
ios_base::out | ios_base::binary | ios_base::trunc
);
// Check on file opened?
}
@ -787,38 +777,62 @@ void ensightFieldBinary
}
}
writeAllDataBinary("penta6", vf, prisms, meshCellSets.nPrisms, ensightFile);
writeAllDataBinary("pyramid5", vf, pyrs, meshCellSets.nPyrs, ensightFile);
writeAllDataBinary("tetra4", vf, tets, meshCellSets.nTets, ensightFile);
writeAllDataBinary("nfaced", vf, polys, meshCellSets.nPolys, ensightFile);
writeAllDataBinary
(
"penta6",
vf,
prisms,
meshCellSets.nPrisms,
ensightFile
);
writeAllDataBinary
(
"pyramid5",
vf,
pyrs,
meshCellSets.nPyrs,
ensightFile
);
writeAllDataBinary
(
"tetra4",
vf,
tets,
meshCellSets.nTets,
ensightFile
);
writeAllDataBinary
(
"nfaced",
vf,
polys,
meshCellSets.nPolys,
ensightFile
);
}
label ensightPatchI = eMesh.patchPartOffset();
for
(
HashTable<labelList>::const_iterator iter = allPatchNames.begin();
iter != allPatchNames.end();
++iter
)
forAll(allPatchNames, patchi)
{
const word& patchName = iter.key();
const labelList& patchProcessors = iter();
const word& patchName = allPatchNames[patchi];
const labelList& patchProcessors = allPatchProcs[patchi];
if (patchNames.empty() || patchNames.found(patchName))
{
if (patchIndices.found(patchName))
if (mesh.boundary()[patchi].size())
{
label patchI = patchIndices.find(patchName)();
if
(
writePatchFieldBinary
(
vf.boundaryField()[patchI],
patchI,
vf.boundaryField()[patchi],
patchi,
ensightPatchI,
boundaryFaceSets[patchI],
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
patchProcessors,
ensightFile
@ -859,6 +873,7 @@ void ensightFieldBinary
}
}
template<class Type>
void ensightField
(

View File

@ -28,6 +28,7 @@ License
#include "Time.H"
#include "ensightMesh.H"
#include "fvMesh.H"
#include "globalMeshData.H"
#include "PstreamCombineReduceOps.H"
#include "processorPolyPatch.H"
#include "cellModeller.H"
@ -40,43 +41,37 @@ License
namespace Foam
{
class concatPatchNames
{
public:
void operator()
(
HashTable<labelList>& x,
const HashTable<labelList>& y
) const
//- Proxy-class to hold the patch processor list combination operator
class concatPatchProcs
{
forAllConstIter(HashTable<labelList>, y, iter)
public:
void operator()
(
List<labelList>& x,
const List<labelList>& y
) const
{
HashTable<labelList>::iterator xiter = x.find(iter.key());
if (xiter == x.end())
forAll(y, i)
{
x.insert(iter.key(), iter());
}
else
{
labelList& xPatches = xiter();
const labelList& yPatches = iter();
const labelList& yPatches = y[i];
label offset = xPatches.size();
xPatches.setSize(offset + yPatches.size());
forAll(yPatches, i)
if (yPatches.size())
{
xPatches[i + offset] = yPatches[i];
labelList& xPatches = x[i];
label offset = xPatches.size();
xPatches.setSize(offset + yPatches.size());
forAll(yPatches, i)
{
xPatches[i + offset] = yPatches[i];
}
}
}
}
}
};
};
} // End namespace Foam
@ -95,7 +90,7 @@ Foam::ensightMesh::ensightMesh
meshCellSets_(mesh_.nCells()),
boundaryFaceSets_(mesh_.boundary().size()),
allPatchNames_(0),
patchIndices_(0),
allPatchProcs_(0),
patchNames_(0),
nPatchPrims_(0)
{
@ -109,32 +104,24 @@ Foam::ensightMesh::ensightMesh
if (!args.optionFound("noPatches"))
{
forAll (mesh_.boundaryMesh(), patchI)
{
if
(
typeid(mesh_.boundaryMesh()[patchI])
!= typeid(processorPolyPatch)
)
{
if (!allPatchNames_.found(mesh_.boundaryMesh()[patchI].name()))
{
allPatchNames_.insert
(
mesh_.boundaryMesh()[patchI].name(),
labelList(1, Pstream::myProcNo())
);
allPatchNames_ = wordList::subList
(
mesh_.boundaryMesh().names(), mesh_.boundary().size()
- mesh_.globalData().processorPatches().size()
);
patchIndices_.insert
(
mesh_.boundaryMesh()[patchI].name(),
patchI
);
}
allPatchProcs_.setSize(allPatchNames_.size());
forAll (allPatchProcs_, patchi)
{
if (mesh_.boundary()[patchi].size())
{
allPatchProcs_[patchi].setSize(1);
allPatchProcs_[patchi][0] = Pstream::myProcNo();
}
}
combineReduce(allPatchNames_, concatPatchNames());
combineReduce(allPatchProcs_, concatPatchProcs());
if (args.optionFound("patches"))
{
@ -142,7 +129,7 @@ Foam::ensightMesh::ensightMesh
if (patchNameList.empty())
{
patchNameList = allPatchNames_.toc();
patchNameList = allPatchNames_;
}
forAll (patchNameList, i)
@ -230,15 +217,15 @@ Foam::ensightMesh::ensightMesh
if (!args.optionFound("noPatches"))
{
forAll (mesh.boundary(), patchI)
forAll (mesh.boundary(), patchi)
{
if (mesh.boundary()[patchI].size())
if (mesh.boundary()[patchi].size())
{
const polyPatch& p = mesh.boundaryMesh()[patchI];
const polyPatch& p = mesh.boundaryMesh()[patchi];
labelList& tris = boundaryFaceSets_[patchI].tris;
labelList& quads = boundaryFaceSets_[patchI].quads;
labelList& polys = boundaryFaceSets_[patchI].polys;
labelList& tris = boundaryFaceSets_[patchi].tris;
labelList& quads = boundaryFaceSets_[patchi].quads;
labelList& polys = boundaryFaceSets_[patchi].polys;
tris.setSize(p.size());
quads.setSize(p.size());
@ -274,21 +261,19 @@ Foam::ensightMesh::ensightMesh
}
forAllConstIter(HashTable<labelList>, allPatchNames_, iter)
forAll(allPatchNames_, patchi)
{
const word& patchName = iter.key();
const word& patchName = allPatchNames_[patchi];
nFacePrimitives nfp;
if (patchNames_.empty() || patchNames_.found(patchName))
{
if (patchIndices_.found(patchName))
if (mesh.boundary()[patchi].size())
{
label patchI = patchIndices_.find(patchName)();
nfp.nPoints = mesh.boundaryMesh()[patchI].localPoints().size();
nfp.nTris = boundaryFaceSets_[patchI].tris.size();
nfp.nQuads = boundaryFaceSets_[patchI].quads.size();
nfp.nPolys = boundaryFaceSets_[patchI].polys.size();
nfp.nPoints = mesh.boundaryMesh()[patchi].localPoints().size();
nfp.nTris = boundaryFaceSets_[patchi].tris.size();
nfp.nQuads = boundaryFaceSets_[patchi].quads.size();
nfp.nPolys = boundaryFaceSets_[patchi].polys.size();
}
}
@ -1052,13 +1037,13 @@ void Foam::ensightMesh::writeAscii
label ensightPatchI = patchPartOffset_;
forAllConstIter(HashTable<labelList>, allPatchNames_, iter)
forAll(allPatchNames_, patchi)
{
const labelList& patchProcessors = iter();
const word& patchName = allPatchNames_[patchi];
const labelList& patchProcessors = allPatchProcs_[patchi];
if (patchNames_.empty() || patchNames_.found(iter.key()))
if (patchNames_.empty() || patchNames_.found(patchName))
{
const word& patchName = iter.key();
const nFacePrimitives& nfp = nPatchPrims_.find(patchName)();
const labelList *trisPtr = NULL;
@ -1068,14 +1053,13 @@ void Foam::ensightMesh::writeAscii
const pointField *patchPointsPtr = NULL;
const faceList *patchFacesPtr = NULL;
if (patchIndices_.found(iter.key()))
if (mesh_.boundary()[patchi].size())
{
label patchI = patchIndices_.find(iter.key())();
const polyPatch& p = mesh_.boundaryMesh()[patchI];
const polyPatch& p = mesh_.boundaryMesh()[patchi];
trisPtr = &boundaryFaceSets_[patchI].tris;
quadsPtr = &boundaryFaceSets_[patchI].quads;
polysPtr = &boundaryFaceSets_[patchI].polys;
trisPtr = &boundaryFaceSets_[patchi].tris;
quadsPtr = &boundaryFaceSets_[patchi].quads;
polysPtr = &boundaryFaceSets_[patchi].polys;
patchPointsPtr = &(p.localPoints());
patchFacesPtr = &(p.localFaces());
@ -1265,7 +1249,7 @@ void Foam::ensightMesh::writeBinary
{
writeEnsDataBinary("part",ensightGeometryFile);
writeEnsDataBinary(1,ensightGeometryFile);
writeEnsDataBinary("FOAM cells",ensightGeometryFile);
writeEnsDataBinary("internalMesh",ensightGeometryFile);
writeEnsDataBinary("coordinates",ensightGeometryFile);
writeEnsDataBinary(nPoints,ensightGeometryFile);
@ -1379,14 +1363,14 @@ void Foam::ensightMesh::writeBinary
label ensightPatchI = patchPartOffset_;
label iCount = 0;
forAllConstIter(HashTable<labelList>, allPatchNames_, iter)
forAll(allPatchNames_, patchi)
{
iCount ++;
const labelList& patchProcessors = iter();
const word& patchName = allPatchNames_[patchi];
const labelList& patchProcessors = allPatchProcs_[patchi];
if (patchNames_.empty() || patchNames_.found(iter.key()))
if (patchNames_.empty() || patchNames_.found(patchName))
{
const word& patchName = iter.key();
const nFacePrimitives& nfp = nPatchPrims_.find(patchName)();
const labelList *trisPtr = NULL;
@ -1396,14 +1380,13 @@ void Foam::ensightMesh::writeBinary
const pointField *patchPointsPtr = NULL;
const faceList *patchFacesPtr = NULL;
if (patchIndices_.found(iter.key()))
if (mesh_.boundary()[patchi].size())
{
label patchI = patchIndices_.find(iter.key())();
const polyPatch& p = mesh_.boundaryMesh()[patchI];
const polyPatch& p = mesh_.boundaryMesh()[patchi];
trisPtr = &boundaryFaceSets_[patchI].tris;
quadsPtr = &boundaryFaceSets_[patchI].quads;
polysPtr = &boundaryFaceSets_[patchI].polys;
trisPtr = &boundaryFaceSets_[patchi].tris;
quadsPtr = &boundaryFaceSets_[patchi].quads;
polysPtr = &boundaryFaceSets_[patchi].polys;
patchPointsPtr = &(p.localPoints());
patchFacesPtr = &(p.localFaces());
@ -1424,7 +1407,7 @@ void Foam::ensightMesh::writeBinary
writeEnsDataBinary("part",ensightGeometryFile);
writeEnsDataBinary(ensightPatchI++,ensightGeometryFile);
//writeEnsDataBinary(patchName.c_str(),ensightGeometryFile);
writeEnsDataBinary(iter.key().c_str(),ensightGeometryFile);
writeEnsDataBinary(patchName.c_str(),ensightGeometryFile);
writeEnsDataBinary("coordinates",ensightGeometryFile);
writeEnsDataBinary(nfp.nPoints,ensightGeometryFile);

View File

@ -91,9 +91,9 @@ class ensightMesh
List<faceSets> boundaryFaceSets_;
HashTable<labelList> allPatchNames_;
wordList allPatchNames_;
HashTable<label> patchIndices_;
List<labelList> allPatchProcs_;
wordHashSet patchNames_;
@ -269,14 +269,14 @@ public:
return boundaryFaceSets_;
}
const HashTable<labelList>& allPatchNames() const
const wordList& allPatchNames() const
{
return allPatchNames_;
}
const HashTable<label>& patchIndices() const
const List<labelList>& allPatchProcs() const
{
return patchIndices_;
return allPatchProcs_;
}
const wordHashSet& patchNames() const

View File

@ -90,6 +90,9 @@ Usage
The quoting is required to avoid shell expansions and to pass the
information as a single argument.
@param -useTimeName \n
use the time index in the VTK file name instead of the time index
Note
mesh subset is handled by vtkMesh. Slight inconsistency in
interpolation: on the internal field it interpolates the whole volfield
@ -242,6 +245,7 @@ int main(int argc, char *argv[])
argList::validOptions.insert("excludePatches","patches to exclude");
argList::validOptions.insert("noFaceZones","");
argList::validOptions.insert("noLinks","");
argList::validOptions.insert("useTimeName","");
# include "setRootCase.H"
# include "createTime.H"
@ -250,6 +254,7 @@ int main(int argc, char *argv[])
bool doFaceZones = !args.optionFound("noFaceZones");
bool doLinks = !args.optionFound("noLinks");
bool binary = !args.optionFound("ascii");
bool useTimeName = args.optionFound("useTimeName");
if (binary && (sizeof(floatScalar) != 4 || sizeof(label) != 4))
{
@ -359,6 +364,16 @@ int main(int argc, char *argv[])
Info<< "Time: " << runTime.timeName() << endl;
word timeDesc = "";
if (useTimeName)
{
timeDesc = runTime.timeName();
}
else
{
timeDesc = name(runTime.timeIndex());
}
// Check for new polyMesh/ and update mesh, fvMeshSubset and cell
// decomposition.
polyMesh::readUpdateState meshState = vMesh.readUpdate();
@ -388,7 +403,7 @@ int main(int argc, char *argv[])
(
fvPath/set.name()/set.name()
+ "_"
+ name(timeI)
+ timeDesc
+ ".vtk"
);
@ -411,7 +426,7 @@ int main(int argc, char *argv[])
(
fvPath/set.name()/set.name()
+ "_"
+ name(timeI)
+ timeDesc
+ ".vtk"
);
@ -548,7 +563,7 @@ int main(int argc, char *argv[])
(
fvPath/vtkName
+ "_"
+ name(timeI)
+ timeDesc
+ ".vtk"
);
@ -654,8 +669,8 @@ int main(int argc, char *argv[])
fvPath
/"surfaceFields"
/"surfaceFields"
+ "_"
+ name(timeI)
+ "_"
+ timeDesc
+ ".vtk"
);
@ -689,7 +704,7 @@ int main(int argc, char *argv[])
patchFileName =
fvPath/"allPatches"/cellSetName
+ "_"
+ name(timeI)
+ timeDesc
+ ".vtk";
}
else
@ -697,7 +712,7 @@ int main(int argc, char *argv[])
patchFileName =
fvPath/"allPatches"/"allPatches"
+ "_"
+ name(timeI)
+ timeDesc
+ ".vtk";
}
@ -767,7 +782,7 @@ int main(int argc, char *argv[])
patchFileName =
fvPath/pp.name()/cellSetName
+ "_"
+ name(timeI)
+ timeDesc
+ ".vtk";
}
else
@ -775,7 +790,7 @@ int main(int argc, char *argv[])
patchFileName =
fvPath/pp.name()/pp.name()
+ "_"
+ name(timeI)
+ timeDesc
+ ".vtk";
}
@ -867,7 +882,7 @@ int main(int argc, char *argv[])
patchFileName =
fvPath/pp.name()/cellSetName
+ "_"
+ name(timeI)
+ timeDesc
+ ".vtk";
}
else
@ -875,7 +890,7 @@ int main(int argc, char *argv[])
patchFileName =
fvPath/pp.name()/pp.name()
+ "_"
+ name(timeI)
+ timeDesc
+ ".vtk";
}
@ -931,7 +946,7 @@ int main(int argc, char *argv[])
fileName lagrFileName
(
fvPath/cloud::prefix/cloudDirs[i]/cloudDirs[i]
+ "_" + name(timeI) + ".vtk"
+ "_" + timeDesc + ".vtk"
);
Info<< " Lagrangian: " << lagrFileName << endl;

View File

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

View File

@ -0,0 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-llagrangian

View File

@ -0,0 +1,22 @@
IOdictionary propsDict
(
IOobject
(
"particleTrackProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ
)
);
word cloudName(propsDict.lookup("cloudName"));
label sampleFrequency(readLabel(propsDict.lookup("sampleFrequency")));
// outputMode: compositeFile, filePerTrack
//word outputmode(propsDict.lookup("outputMode"))
label maxPositions(readLabel(propsDict.lookup("maxPositions")));
// outputFormat: raw, vtk
//word outputFormat(propsDict.lookup("outputFormat"));

View File

@ -0,0 +1,270 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
particleTracks
Description
Generates a VTK file of particle tracks for cases that were computed using
a tracked-parcel-type cloud
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Cloud.H"
#include "IOdictionary.H"
#include "fvMesh.H"
#include "Time.H"
#include "timeSelector.H"
#include "OFstream.H"
#include "passiveParticle.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
# include "setRootCase.H"
# include "createTime.H"
instantList timeDirs = timeSelector::select0(runTime, args);
# include "createMesh.H"
# include "createFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "Scanning times to determine track data" << nl << endl;
labelList maxIds(Pstream::nProcs(), -1);
forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
Info<< "Time = " << runTime.timeName() << endl;
IOobject origProcHeader
(
"origProc",
runTime.timeName(),
cloud::prefix/cloudName,
mesh,
IOobject::MUST_READ
);
IOobject idHeader
(
"id",
runTime.timeName(),
cloud::prefix/cloudName,
mesh,
IOobject::MUST_READ
);
if (idHeader.headerOk() && origProcHeader.headerOk())
{
IOField<label> origProc(origProcHeader);
IOField<label> id(idHeader);
forAll(id, i)
{
maxIds[origProc[i]] = max(maxIds[origProc[i]], id[i]);
}
}
}
Pstream::listCombineGather(maxIds, maxOp<label>());
Pstream::listCombineScatter(maxIds);
labelList numIds = maxIds + 1;
// calc starting ids for particles on each processor
List<label> startIds(numIds.size(), 0);
for (label i = 0; i < numIds.size()-1; i++)
{
startIds[i+1] += startIds[i] + numIds[i];
}
label nParticle = startIds[startIds.size()-1] + numIds[startIds.size()-1];
// number of tracks to generate
label nTracks = nParticle/sampleFrequency;
// storage for all particle tracks
List<DynamicList<vector> > allTracks(nTracks);
Info<< "\nGenerating " << nTracks << " particle tracks" << nl << endl;
forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
Info<< "Time = " << runTime.timeName() << endl;
IOobject positionsHeader
(
"positions",
runTime.timeName(),
cloud::prefix/cloudName,
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
);
IOobject origProcHeader
(
"origProc",
runTime.timeName(),
cloud::prefix/cloudName,
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
);
IOobject idHeader
(
"id",
runTime.timeName(),
cloud::prefix/cloudName,
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
);
if
(
positionsHeader.headerOk()
&& origProcHeader.headerOk()
&& idHeader.headerOk()
)
{
Info<< " Reading particle positions" << endl;
Cloud<passiveParticle> myCloud(mesh, cloudName, false);
Info<< " Reading particle id" << endl;
IOField<label> id(idHeader);
Info<< " Reading particle origProc" << endl;
IOField<label> origProc(origProcHeader);
// collect the track data on the master processor
label i = 0;
List<pointField> allPositions(Pstream::nProcs());
allPositions[Pstream::myProcNo()].setSize(myCloud.size());
forAllConstIter(Cloud<passiveParticle>, myCloud, iter)
{
allPositions[Pstream::myProcNo()][i++] = iter().position();
}
Pstream::gatherList(allPositions);
List<labelList> allIds(Pstream::nProcs());
allIds[Pstream::myProcNo()] = id;
Pstream::gatherList(allIds);
List<labelList> allOrigProcs(Pstream::nProcs());
allOrigProcs[Pstream::myProcNo()] = origProc;
Pstream::gatherList(allOrigProcs);
Info<< " Constructing tracks" << nl << endl;
if (Pstream::master())
{
forAll(allPositions, procI)
{
forAll(allPositions[procI], i)
{
label globalId =
startIds[allOrigProcs[procI][i]]
+ allIds[procI][i];
if (globalId % sampleFrequency == 0)
{
label trackId = globalId/sampleFrequency;
if (allTracks[trackId].size() < maxPositions)
{
allTracks[trackId].append
(
allPositions[procI][i]
);
}
}
}
}
}
}
else
{
Info<< " No particles read" << nl << endl;
}
}
if (Pstream::master())
{
Info<< "\nWriting particle tracks" << nl << endl;
OFstream vtkTracks("particleTracks.vtk");
// 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;
}
return 0;
}
// ************************************************************************* //

View File

@ -78,7 +78,7 @@ int main(int argc, char *argv[])
// Give patch area
if (isType<cyclicPolyPatch>(mesh.boundaryMesh()[patchi]))
{
Info<< " Cyclic patch area: " << nl;
Info<< " Cyclic patch vector area: " << nl;
label nFaces = mesh.boundaryMesh()[patchi].size();
vector sum1 = vector::zero;
vector sum2 = vector::zero;
@ -92,12 +92,18 @@ int main(int argc, char *argv[])
Info<< " - half 1 = " << sum1 << ", " << mag(sum1) << nl
<< " - half 2 = " << sum2 << ", " << mag(sum2) << nl
<< " - total = " << (sum1 + sum2) << ", "
<< mag(sum1 + sum2) << endl;;
<< mag(sum1 + sum2) << endl;
Info<< " Cyclic patch area magnitude = "
<< gSum(mesh.magSf().boundaryField()[patchi])/2.0 << endl;
}
else
{
Info<< " Patch area = "
Info<< " Area vector of patch "
<< patchName << '[' << patchi << ']' << " = "
<< gSum(mesh.Sf().boundaryField()[patchi]) << endl;
Info<< " Area magnitude of patch "
<< patchName << '[' << patchi << ']' << " = "
<< gSum(mesh.magSf().boundaryField()[patchi]) << endl;
}
// Read field and calc integral
@ -107,15 +113,26 @@ int main(int argc, char *argv[])
<< fieldName << endl;
volScalarField field(fieldHeader, mesh);
vector sumField = gSum
(
mesh.Sf().boundaryField()[patchi]
*field.boundaryField()[patchi]
);
Info<< " Integral of " << fieldName << " over patch "
Info<< " Integral of " << fieldName
<< " over vector area of patch "
<< patchName << '[' << patchi << ']' << " = "
<< sumField << nl;
<< gSum
(
mesh.Sf().boundaryField()[patchi]
*field.boundaryField()[patchi]
)
<< nl;
Info<< " Integral of " << fieldName
<< " over area magnitude of patch "
<< patchName << '[' << patchi << ']' << " = "
<< gSum
(
mesh.magSf().boundaryField()[patchi]
*field.boundaryField()[patchi]
)
<< nl;
}
else if
(

View File

@ -1,4 +1,5 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/turbulenceModels/incompressible/LES/LESModel \
-I$(LIB_SRC)/turbulenceModels/LES/LESdeltas/lnInclude \

View File

@ -34,6 +34,7 @@ Description
#include "incompressible/singlePhaseTransportModel/singlePhaseTransportModel.H"
#include "LESModel.H"
#include "nearWallDist.H"
#include "wallDist.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -49,7 +50,18 @@ int main(int argc, char *argv[])
{
runTime.setTime(timeDirs[timeI], timeI);
Info<< "Time = " << runTime.timeName() << endl;
mesh.readUpdate();
fvMesh::readUpdateState state = mesh.readUpdate();
// Wall distance
if (timeI == 0 || state != fvMesh::UNCHANGED)
{
Info<< "Calculating wall distance\n" << endl;
wallDist y(mesh, true);
Info<< "Writing wall distance to field "
<< y.name() << nl << endl;
y.write();
}
volScalarField yPlus
(
@ -116,6 +128,9 @@ int main(int argc, char *argv[])
}
}
Info<< "Writing yPlus to field "
<< yPlus.name() << nl << endl;
yPlus.write();
}

View File

@ -1,4 +1,5 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/RASModel \

View File

@ -34,6 +34,7 @@ Description
#include "incompressible/singlePhaseTransportModel/singlePhaseTransportModel.H"
#include "RASModel.H"
#include "wallFvPatch.H"
#include "wallDist.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -49,7 +50,17 @@ int main(int argc, char *argv[])
{
runTime.setTime(timeDirs[timeI], timeI);
Info<< "Time = " << runTime.timeName() << endl;
mesh.readUpdate();
fvMesh::readUpdateState state = mesh.readUpdate();
// Wall distance
if (timeI == 0 || state != fvMesh::UNCHANGED)
{
Info<< "Calculating wall distance\n" << endl;
wallDist y(mesh, true);
Info<< "Writing wall distance to field "
<< y.name() << nl << endl;
y.write();
}
volScalarField yPlus
(
@ -106,6 +117,9 @@ int main(int argc, char *argv[])
}
}
Info<< "Writing yPlus to field "
<< yPlus.name() << nl << endl;
yPlus.write();
}

View File

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

View File

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

View File

@ -0,0 +1,295 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
surfaceRedistributePar
Description
(Re)distribution of triSurface. Either takes an undecomposed surface
or an already decomposed surface and redistribute it so each processor
has all triangles that overlap its mesh.
Note
- best decomposition option is hierarchGeomDecomp since
guarantees square decompositions.
- triangles might be present on multiple processors.
- merging uses geometric tolerance so take care with writing precision.
\*---------------------------------------------------------------------------*/
#include "treeBoundBox.H"
#include "FixedList.H"
#include "argList.H"
#include "Time.H"
#include "polyMesh.H"
#include "distributedTriSurfaceMesh.H"
#include "mapDistribute.H"
#include "triSurfaceFields.H"
#include "Pair.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Print on master all the per-processor surface stats.
void writeProcStats
(
const triSurface& s,
const List<List<treeBoundBox> >& meshBb
)
{
// Determine surface bounding boxes, faces, points
List<treeBoundBox> surfBb(Pstream::nProcs());
{
surfBb[Pstream::myProcNo()] = boundBox(s.points(), false);
Pstream::gatherList(surfBb);
Pstream::scatterList(surfBb);
}
labelList nPoints(Pstream::nProcs());
nPoints[Pstream::myProcNo()] = s.points().size();
Pstream::gatherList(nPoints);
Pstream::scatterList(nPoints);
labelList nFaces(Pstream::nProcs());
nFaces[Pstream::myProcNo()] = s.size();
Pstream::gatherList(nFaces);
Pstream::scatterList(nFaces);
forAll(surfBb, procI)
{
const List<treeBoundBox>& bbs = meshBb[procI];
Info<< "processor" << procI << endl
<< "\tMesh bounds : " << bbs[0] << nl;
for (label i = 1; i < bbs.size(); i++)
{
Info<< "\t " << bbs[i]<< nl;
}
Info<< "\tSurface bounding box : " << surfBb[procI] << nl
<< "\tTriangles : " << nFaces[procI] << nl
<< "\tVertices : " << nPoints[procI]
<< endl;
}
Info<< endl;
}
// Main program:
int main(int argc, char *argv[])
{
argList::validArgs.append("triSurfaceMesh");
argList::validArgs.append("distributionType");
argList::validOptions.insert("keepNonMapped", "");
# include "setRootCase.H"
# include "createTime.H"
runTime.functionObjects().off();
fileName surfFileName(args.additionalArgs()[0]);
Info<< "Reading surface from " << surfFileName << nl << endl;
const word distType(args.additionalArgs()[1]);
Info<< "Using distribution method "
<< distributedTriSurfaceMesh::distributionTypeNames_[distType]
<< " " << distType << nl << endl;
bool keepNonMapped = args.options().found("keepNonMapped");
if (keepNonMapped)
{
Info<< "Preserving surface outside of mesh bounds." << nl << endl;
}
else
{
Info<< "Removing surface outside of mesh bounds." << nl << endl;
}
if (!Pstream::parRun())
{
FatalErrorIn(args.executable())
<< "Please run this program on the decomposed case."
<< " It will read surface " << surfFileName
<< " and decompose it such that it overlaps the mesh bounding box."
<< exit(FatalError);
}
# include "createPolyMesh.H"
Random rndGen(653213);
// Determine mesh bounding boxes:
List<List<treeBoundBox> > meshBb(Pstream::nProcs());
{
meshBb[Pstream::myProcNo()] = List<treeBoundBox>
(
1,
treeBoundBox
(
boundBox(mesh.points(), false)
).extend(rndGen, 1E-3)
);
Pstream::gatherList(meshBb);
Pstream::scatterList(meshBb);
}
IOobject io
(
surfFileName, // name
//runTime.findInstance("triSurface", surfFileName), // instance
runTime.constant(), // instance
"triSurface", // local
runTime, // registry
IOobject::MUST_READ,
IOobject::NO_WRITE
);
const fileName actualPath(io.filePath());
fileName localPath(actualPath);
localPath.replace(runTime.rootPath() + '/', "");
if (actualPath == io.objectPath())
{
Info<< "Loading local (decomposed) surface " << localPath << nl <<endl;
}
else
{
Info<< "Loading undecomposed surface " << localPath << nl << endl;
}
// Create dummy dictionary for bounding boxes if does not exist.
if (!isFile(actualPath / "Dict"))
{
dictionary dict;
dict.add("bounds", meshBb[Pstream::myProcNo()]);
dict.add("distributionType", distType);
dict.add("mergeDistance", SMALL);
IOdictionary ioDict
(
IOobject
(
io.name() + "Dict",
io.instance(),
io.local(),
io.db(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
dict
);
Info<< "Writing dummy bounds dictionary to " << ioDict.name()
<< nl << endl;
ioDict.regIOobject::writeObject
(
IOstream::ASCII,
IOstream::currentVersion,
ioDict.time().writeCompression()
);
}
// Load surface
distributedTriSurfaceMesh surfMesh(io);
Info<< "Loaded surface" << nl << endl;
// Generate a test field
{
const triSurface& s = static_cast<const triSurface&>(surfMesh);
autoPtr<triSurfaceVectorField> fcPtr
(
new triSurfaceVectorField
(
IOobject
(
surfMesh.searchableSurface::name(), // name
surfMesh.searchableSurface::instance(), // instance
surfMesh.searchableSurface::local(), // local
surfMesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
surfMesh,
dimLength
)
);
triSurfaceVectorField& fc = fcPtr();
forAll(fc, triI)
{
fc[triI] = s[triI].centre(s.points());
}
// Steal pointer and store object on surfMesh
fcPtr.ptr()->store();
}
// Write per-processor stats
Info<< "Before redistribution:" << endl;
writeProcStats(surfMesh, meshBb);
// Do redistribution
Info<< "Redistributing surface" << nl << endl;
autoPtr<mapDistribute> faceMap;
autoPtr<mapDistribute> pointMap;
surfMesh.distribute
(
meshBb[Pstream::myProcNo()],
keepNonMapped,
faceMap,
pointMap
);
faceMap.clear();
pointMap.clear();
Info<< endl;
// Write per-processor stats
Info<< "After redistribution:" << endl;
writeProcStats(surfMesh, meshBb);
Info<< "Writing surface." << nl << endl;
surfMesh.searchableSurface::write();
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //