Back again

This commit is contained in:
henry
2009-08-28 18:21:57 +01:00
143 changed files with 8229 additions and 846 deletions

View File

@ -1,10 +1,14 @@
EXE_INC = \ EXE_INC = \
-IextrudedMesh \ -IextrudedMesh \
-IextrudeModel/lnInclude \ -IextrudeModel/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude -I$(LIB_SRC)/dynamicMesh/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume \
-lsurfMesh \
-lmeshTools \ -lmeshTools \
-ldynamicMesh \ -ldynamicMesh \
-lextrudeModel -lextrudeModel

View File

@ -36,13 +36,15 @@ Description
#include "Time.H" #include "Time.H"
#include "dimensionedTypes.H" #include "dimensionedTypes.H"
#include "IFstream.H" #include "IFstream.H"
#include "faceMesh.H"
#include "polyTopoChange.H" #include "polyTopoChange.H"
#include "polyTopoChanger.H" #include "polyTopoChanger.H"
#include "edgeCollapser.H" #include "edgeCollapser.H"
#include "mathematicalConstants.H" #include "mathematicalConstants.H"
#include "globalMeshData.H" #include "globalMeshData.H"
#include "perfectInterface.H" #include "perfectInterface.H"
#include "addPatchCellLayer.H"
#include "fvMesh.H"
#include "MeshedSurfaces.H"
#include "extrudedMesh.H" #include "extrudedMesh.H"
#include "extrudeModel.H" #include "extrudeModel.H"
@ -50,14 +52,148 @@ Description
using namespace Foam; using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
enum ExtrudeMode
{
MESH,
PATCH,
SURFACE
};
template<>
const char* NamedEnum<ExtrudeMode, 3>::names[] =
{
"mesh",
"patch",
"surface"
};
static const NamedEnum<ExtrudeMode, 3> ExtrudeModeNames;
void createDummyFvMeshFiles(const polyMesh& mesh, const word& regionName)
{
// Create dummy system/fv*
{
IOobject io
(
"fvSchemes",
mesh.time().system(),
regionName,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
);
Info<< "Testing:" << io.objectPath() << endl;
if (!io.headerOk())
{
Info<< "Writing dummy " << regionName/io.name() << endl;
dictionary dummyDict;
dictionary divDict;
dummyDict.add("divSchemes", divDict);
dictionary gradDict;
dummyDict.add("gradSchemes", gradDict);
dictionary laplDict;
dummyDict.add("laplacianSchemes", laplDict);
IOdictionary(io, dummyDict).regIOobject::write();
}
}
{
IOobject io
(
"fvSolution",
mesh.time().system(),
regionName,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
);
if (!io.headerOk())
{
Info<< "Writing dummy " << regionName/io.name() << endl;
dictionary dummyDict;
IOdictionary(io, dummyDict).regIOobject::write();
}
}
}
label findPatchID(const polyBoundaryMesh& patches, const word& name)
{
label patchID = patches.findPatchID(name);
if (patchID == -1)
{
FatalErrorIn("findPatchID(const polyBoundaryMesh&, const word&)")
<< "Cannot find patch " << name
<< " in the source mesh.\n"
<< "Valid patch names are " << patches.names()
<< exit(FatalError);
}
return patchID;
}
labelList patchFaces(const polyBoundaryMesh& patches, const word& name)
{
label patchID = findPatchID(patches, name);
const polyPatch& pp = patches[patchID];
return identity(pp.size()) + pp.start();
}
void updateFaceLabels(const mapPolyMesh& map, labelList& faceLabels)
{
const labelList& reverseMap = map.reverseFaceMap();
labelList newFaceLabels(faceLabels.size());
label newI = 0;
forAll(faceLabels, i)
{
label oldFaceI = faceLabels[i];
if (reverseMap[oldFaceI] >= 0)
{
newFaceLabels[newI++] = reverseMap[oldFaceI];
}
}
newFaceLabels.setSize(newI);
faceLabels.transfer(newFaceLabels);
}
// Main program: // Main program:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
#include "addRegionOption.H"
#include "setRootCase.H" #include "setRootCase.H"
#include "createTimeExtruded.H" #include "createTimeExtruded.H"
autoPtr<extrudedMesh> meshPtr(NULL); // Get optional regionName
word regionName;
word regionDir;
if (args.optionReadIfPresent("region", regionName))
{
regionDir = regionName;
Info<< "Create mesh " << regionName << " for time = "
<< runTimeExtruded.timeName() << nl << endl;
}
else
{
regionName = fvMesh::defaultRegion;
Info<< "Create mesh for time = "
<< runTimeExtruded.timeName() << nl << endl;
}
IOdictionary dict IOdictionary dict
( (
@ -65,26 +201,44 @@ int main(int argc, char *argv[])
( (
"extrudeProperties", "extrudeProperties",
runTimeExtruded.constant(), runTimeExtruded.constant(),
regionDir,
runTimeExtruded, runTimeExtruded,
IOobject::MUST_READ IOobject::MUST_READ
) )
); );
// Point generator
autoPtr<extrudeModel> model(extrudeModel::New(dict)); autoPtr<extrudeModel> model(extrudeModel::New(dict));
const word sourceType(dict.lookup("constructFrom")); // Whether to flip normals
const Switch flipNormals(dict.lookup("flipNormals"));
autoPtr<faceMesh> fMesh; // What to extrude
const ExtrudeMode mode = ExtrudeModeNames.read
(
dict.lookup("constructFrom")
);
if (sourceType == "patch")
// Generated mesh (one of either)
autoPtr<fvMesh> meshFromMesh;
autoPtr<polyMesh> meshFromSurface;
// Faces on front and back for stitching (in case of mergeFaces)
word frontPatchName;
labelList frontPatchFaces;
word backPatchName;
labelList backPatchFaces;
if (mode == PATCH || mode == MESH)
{ {
fileName sourceCasePath(dict.lookup("sourceCase")); fileName sourceCasePath(dict.lookup("sourceCase"));
sourceCasePath.expand(); sourceCasePath.expand();
fileName sourceRootDir = sourceCasePath.path(); fileName sourceRootDir = sourceCasePath.path();
fileName sourceCaseDir = sourceCasePath.name(); fileName sourceCaseDir = sourceCasePath.name();
word patchName(dict.lookup("sourcePatch")); dict.lookup("sourcePatch") >> frontPatchName;
Info<< "Extruding patch " << patchName Info<< "Extruding patch " << frontPatchName
<< " on mesh " << sourceCasePath << nl << " on mesh " << sourceCasePath << nl
<< endl; << endl;
@ -94,31 +248,183 @@ int main(int argc, char *argv[])
sourceRootDir, sourceRootDir,
sourceCaseDir sourceCaseDir
); );
#include "createPolyMesh.H" #include "createMesh.H"
label patchID = mesh.boundaryMesh().findPatchID(patchName); const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (patchID == -1)
// Topo change container. Either copy an existing mesh or start
// with empty storage (number of patches only needed for checking)
autoPtr<polyTopoChange> meshMod
(
(
mode == MESH
? new polyTopoChange(mesh)
: new polyTopoChange(patches.size())
)
);
// Extrusion engine. Either adding to existing mesh or
// creating separate mesh.
addPatchCellLayer layerExtrude(mesh, (mode == MESH));
indirectPrimitivePatch extrudePatch
(
IndirectList<face>
(
mesh.faces(),
patchFaces(patches, frontPatchName)
),
mesh.points()
);
// Only used for addPatchCellLayer into new mesh
labelList exposedPatchIDs;
if (mode == PATCH)
{ {
FatalErrorIn(args.executable()) dict.lookup("exposedPatchName") >> backPatchName;
<< "Cannot find patch " << patchName exposedPatchIDs.setSize
<< " in the source mesh.\n" (
<< "Valid patch names are " << mesh.boundaryMesh().names() extrudePatch.size(),
<< exit(FatalError); findPatchID(patches, backPatchName)
);
} }
const polyPatch& pp = mesh.boundaryMesh()[patchID];
fMesh.reset(new faceMesh(pp.localFaces(), pp.localPoints()));
pointField layer0Points(extrudePatch.nPoints());
pointField displacement(extrudePatch.nPoints());
forAll(displacement, pointI)
{ {
fileName surfName(runTime.path()/patchName + ".sMesh"); const vector& patchNormal = extrudePatch.pointNormals()[pointI];
Info<< "Writing patch as surfaceMesh to "
<< surfName << nl << endl; // layer0 point
OFstream os(surfName); layer0Points[pointI] = model()
os << fMesh() << nl; (
extrudePatch.localPoints()[pointI],
patchNormal,
0
);
// layerN point
point extrudePt = model()
(
extrudePatch.localPoints()[pointI],
patchNormal,
model().nLayers()
);
displacement[pointI] = extrudePt - layer0Points[pointI];
} }
if (flipNormals)
{
Info<< "Flipping faces." << nl << endl;
displacement = -displacement;
}
// Check if wedge (has layer0 different from original patch points)
// If so move the mesh to starting position.
if (gMax(mag(layer0Points-extrudePatch.localPoints())) > SMALL)
{
Info<< "Moving mesh to layer0 points since differ from original"
<< " points - this can happen for wedge extrusions." << nl
<< endl;
pointField newPoints(mesh.points());
forAll(extrudePatch.meshPoints(), i)
{
newPoints[extrudePatch.meshPoints()[i]] = layer0Points[i];
}
mesh.movePoints(newPoints);
}
// Layers per face
labelList nFaceLayers(extrudePatch.size(), model().nLayers());
// Layers per point
labelList nPointLayers(extrudePatch.nPoints(), model().nLayers());
// Displacement for first layer
vectorField firstLayerDisp = displacement*model().sumThickness(1);
// Expansion ratio not used.
scalarField ratio(extrudePatch.nPoints(), 1.0);
layerExtrude.setRefinement
(
ratio, // expansion ratio
extrudePatch, // patch faces to extrude
exposedPatchIDs, // if new mesh: patches for exposed faces
nFaceLayers,
nPointLayers,
firstLayerDisp,
meshMod()
);
// Reset points according to extrusion model
forAll(layerExtrude.addedPoints(), pointI)
{
const labelList& pPoints = layerExtrude.addedPoints()[pointI];
forAll(pPoints, pPointI)
{
label meshPointI = pPoints[pPointI];
point modelPt
(
model()
(
extrudePatch.localPoints()[pointI],
extrudePatch.pointNormals()[pointI],
pPointI+1 // layer
)
);
const_cast<DynamicList<point>&>
(
meshMod().points()
)[meshPointI] = modelPt;
}
}
// Store faces on front and exposed patch (if mode=patch there are
// only added faces so cannot used map to old faces)
const labelListList& layerFaces = layerExtrude.layerFaces();
backPatchFaces.setSize(layerFaces.size());
frontPatchFaces.setSize(layerFaces.size());
forAll(backPatchFaces, i)
{
backPatchFaces[i] = layerFaces[i][0];
frontPatchFaces[i] = layerFaces[i][layerFaces[i].size()-1];
}
// Create dummy fvSchemes, fvSolution
createDummyFvMeshFiles(mesh, regionDir);
// Create actual mesh from polyTopoChange container
autoPtr<mapPolyMesh> map = meshMod().makeMesh
(
meshFromMesh,
IOobject
(
regionName,
runTimeExtruded.constant(),
runTimeExtruded,
IOobject::NO_READ,
IOobject::AUTO_WRITE,
false
),
mesh
);
// Calculate face labels for front and back.
frontPatchFaces = renumber
(
map().reverseFaceMap(),
frontPatchFaces
);
backPatchFaces = renumber
(
map().reverseFaceMap(),
backPatchFaces
);
} }
else if (sourceType == "surface") else
{ {
// Read from surface // Read from surface
fileName surfName(dict.lookup("surface")); fileName surfName(dict.lookup("surface"));
@ -126,52 +432,62 @@ int main(int argc, char *argv[])
Info<< "Extruding surfaceMesh read from file " << surfName << nl Info<< "Extruding surfaceMesh read from file " << surfName << nl
<< endl; << endl;
IFstream is(surfName); MeshedSurface<face> fMesh(surfName);
fMesh.reset(new faceMesh(is)); if (flipNormals)
Info<< "Read patch from file " << surfName << nl
<< endl;
}
else
{
FatalErrorIn(args.executable())
<< "Illegal 'constructFrom' specification. Should either be "
<< "patch or surface." << exit(FatalError);
}
Switch flipNormals(dict.lookup("flipNormals"));
if (flipNormals)
{
Info<< "Flipping faces." << nl << endl;
faceList faces(fMesh().size());
forAll(faces, i)
{ {
faces[i] = fMesh()[i].reverseFace(); Info<< "Flipping faces." << nl << endl;
faceList& faces = const_cast<faceList&>(fMesh.faces());
forAll(faces, i)
{
faces[i] = fMesh[i].reverseFace();
}
} }
fMesh.reset(new faceMesh(faces, fMesh().localPoints()));
Info<< "Extruding surface with :" << nl
<< " points : " << fMesh.points().size() << nl
<< " faces : " << fMesh.size() << nl
<< " normals[0] : " << fMesh.faceNormals()[0]
<< nl
<< endl;
meshFromSurface.reset
(
new extrudedMesh
(
IOobject
(
extrudedMesh::defaultRegion,
runTimeExtruded.constant(),
runTimeExtruded
),
fMesh,
model()
)
);
// Get the faces on front and back
frontPatchName = "originalPatch";
frontPatchFaces = patchFaces
(
meshFromSurface().boundaryMesh(),
frontPatchName
);
backPatchName = "otherSide";
backPatchFaces = patchFaces
(
meshFromSurface().boundaryMesh(),
backPatchName
);
} }
Info<< "Extruding patch with :" << nl polyMesh& mesh =
<< " points : " << fMesh().points().size() << nl
<< " faces : " << fMesh().size() << nl
<< " normals[0] : " << fMesh().faceNormals()[0]
<< nl
<< endl;
extrudedMesh mesh
( (
IOobject meshFromMesh.valid()
( ? meshFromMesh()
extrudedMesh::defaultRegion, : meshFromSurface()
runTimeExtruded.constant(),
runTimeExtruded
),
fMesh(),
model()
); );
@ -184,17 +500,6 @@ int main(int argc, char *argv[])
<< "Merge distance : " << mergeDim << nl << "Merge distance : " << mergeDim << nl
<< endl; << endl;
const polyBoundaryMesh& patches = mesh.boundaryMesh();
const label origPatchID = patches.findPatchID("originalPatch");
const label otherPatchID = patches.findPatchID("otherSide");
if (origPatchID == -1 || otherPatchID == -1)
{
FatalErrorIn(args.executable())
<< "Cannot find patch originalPatch or otherSide." << nl
<< "Valid patches are " << patches.names() << exit(FatalError);
}
// Collapse edges // Collapse edges
// ~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~
@ -237,6 +542,10 @@ int main(int argc, char *argv[])
// Update fields // Update fields
mesh.updateMesh(map); mesh.updateMesh(map);
// Update stored data
updateFaceLabels(map(), frontPatchFaces);
updateFaceLabels(map(), backPatchFaces);
// Move mesh (if inflation used) // Move mesh (if inflation used)
if (map().hasMotionPoints()) if (map().hasMotionPoints())
{ {
@ -252,22 +561,33 @@ int main(int argc, char *argv[])
Switch mergeFaces(dict.lookup("mergeFaces")); Switch mergeFaces(dict.lookup("mergeFaces"));
if (mergeFaces) if (mergeFaces)
{ {
if (mode == MESH)
{
FatalErrorIn(args.executable())
<< "Cannot stitch front and back of extrusion since"
<< " in 'mesh' mode (extrusion appended to mesh)."
<< exit(FatalError);
}
Info<< "Assuming full 360 degree axisymmetric case;" Info<< "Assuming full 360 degree axisymmetric case;"
<< " stitching faces on patches " << " stitching faces on patches "
<< patches[origPatchID].name() << " and " << frontPatchName << " and "
<< patches[otherPatchID].name() << " together ..." << nl << endl; << backPatchName << " together ..." << nl << endl;
if (frontPatchFaces.size() != backPatchFaces.size())
{
FatalErrorIn(args.executable())
<< "Differing number of faces on front ("
<< frontPatchFaces.size() << ") and back ("
<< backPatchFaces.size() << ")"
<< exit(FatalError);
}
polyTopoChanger stitcher(mesh); polyTopoChanger stitcher(mesh);
stitcher.setSize(1); stitcher.setSize(1);
// Make list of masterPatch faces
labelList isf(patches[origPatchID].size());
forAll (isf, i)
{
isf[i] = patches[origPatchID].start() + i;
}
const word cutZoneName("originalCutFaceZone"); const word cutZoneName("originalCutFaceZone");
List<faceZone*> fz List<faceZone*> fz
@ -276,8 +596,8 @@ int main(int argc, char *argv[])
new faceZone new faceZone
( (
cutZoneName, cutZoneName,
isf, frontPatchFaces,
boolList(isf.size(), false), boolList(frontPatchFaces.size(), false),
0, 0,
mesh.faceZones() mesh.faceZones()
) )
@ -286,26 +606,58 @@ int main(int argc, char *argv[])
mesh.addZones(List<pointZone*>(0), fz, List<cellZone*>(0)); mesh.addZones(List<pointZone*>(0), fz, List<cellZone*>(0));
// Add the perfect interface mesh modifier // Add the perfect interface mesh modifier
stitcher.set perfectInterface perfectStitcher
( (
"couple",
0, 0,
new perfectInterface stitcher,
( cutZoneName,
"couple", word::null, // dummy patch name
0, word::null // dummy patch name
stitcher,
cutZoneName,
patches[origPatchID].name(),
patches[otherPatchID].name()
)
); );
// Execute all polyMeshModifiers // Topo change container
autoPtr<mapPolyMesh> morphMap = stitcher.changeMesh(true); polyTopoChange meshMod(mesh);
mesh.movePoints(morphMap->preMotionPoints()); perfectStitcher.setRefinement
(
indirectPrimitivePatch
(
IndirectList<face>
(
mesh.faces(),
frontPatchFaces
),
mesh.points()
),
indirectPrimitivePatch
(
IndirectList<face>
(
mesh.faces(),
backPatchFaces
),
mesh.points()
),
meshMod
);
// Construct new mesh from polyTopoChange.
autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
// Update fields
mesh.updateMesh(map);
// Move mesh (if inflation used)
if (map().hasMotionPoints())
{
mesh.movePoints(map().preMotionPoints());
}
} }
mesh.setInstance(runTimeExtruded.constant());
Info<< "Writing mesh to " << mesh.objectPath() << nl << endl;
if (!mesh.write()) if (!mesh.write())
{ {
FatalErrorIn(args.executable()) << "Failed writing mesh" FatalErrorIn(args.executable()) << "Failed writing mesh"

View File

@ -43,6 +43,7 @@ Foam::extrudeModel::extrudeModel
) )
: :
nLayers_(readLabel(dict.lookup("nLayers"))), nLayers_(readLabel(dict.lookup("nLayers"))),
expansionRatio_(readScalar(dict.lookup("expansionRatio"))),
dict_(dict), dict_(dict),
coeffDict_(dict.subDict(modelType + "Coeffs")) coeffDict_(dict.subDict(modelType + "Coeffs"))
{} {}
@ -62,5 +63,28 @@ Foam::label Foam::extrudeModel::nLayers() const
} }
Foam::scalar Foam::extrudeModel::expansionRatio() const
{
return expansionRatio_;
}
Foam::scalar Foam::extrudeModel::sumThickness(const label layer) const
{
// 1+r+r^2+ .. +r^(n-1) = (1-r^n)/(1-r)
if (mag(1.0-expansionRatio_) < SMALL)
{
return scalar(layer)/nLayers_;
}
else
{
return
(1.0-pow(expansionRatio_, layer))
/ (1.0-pow(expansionRatio_, nLayers_));
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -58,6 +58,8 @@ protected:
const label nLayers_; const label nLayers_;
const scalar expansionRatio_;
const dictionary& dict_; const dictionary& dict_;
const dictionary& coeffDict_; const dictionary& coeffDict_;
@ -113,9 +115,15 @@ public:
label nLayers() const; label nLayers() const;
scalar expansionRatio() const;
// Member Operators // Member Operators
//- Helper: calculate cumulative relative thickness for layer.
// (layer=0 -> 0; layer=nLayers -> 1)
scalar sumThickness(const label layer) const;
virtual point operator() virtual point operator()
( (
const point& surfacePoint, const point& surfacePoint,

View File

@ -72,7 +72,8 @@ point linearNormal::operator()
const label layer const label layer
) const ) const
{ {
scalar d = thickness_*layer/nLayers_; //scalar d = thickness_*layer/nLayers_;
scalar d = thickness_*sumThickness(layer);
return surfacePoint + d*surfaceNormal; return surfacePoint + d*surfaceNormal;
} }

View File

@ -64,7 +64,7 @@ public:
// Constructors // Constructors
//- Construct from components //- Construct from dictionary
linearNormal(const dictionary& dict); linearNormal(const dictionary& dict);

View File

@ -67,8 +67,7 @@ point linearRadial::operator()
scalar rs = mag(surfacePoint); scalar rs = mag(surfacePoint);
vector rsHat = surfacePoint/rs; vector rsHat = surfacePoint/rs;
scalar delta = (R_ - rs)/nLayers_; scalar r = rs + (R_ - rs)*sumThickness(layer);
scalar r = rs + layer*delta;
return r*rsHat; return r*rsHat;
} }

View File

@ -61,7 +61,7 @@ public:
// Constructors // Constructors
//- Construct from components //- Construct from dictionary
linearRadial(const dictionary& dict); linearRadial(const dictionary& dict);

View File

@ -49,7 +49,13 @@ sigmaRadial::sigmaRadial(const dictionary& dict)
RTbyg_(readScalar(coeffDict_.lookup("RTbyg"))), RTbyg_(readScalar(coeffDict_.lookup("RTbyg"))),
pRef_(readScalar(coeffDict_.lookup("pRef"))), pRef_(readScalar(coeffDict_.lookup("pRef"))),
pStrat_(readScalar(coeffDict_.lookup("pStrat"))) pStrat_(readScalar(coeffDict_.lookup("pStrat")))
{} {
if (mag(expansionRatio() - 1.0) > SMALL)
{
WarningIn("sigmaRadial::sigmaRadial(const dictionary&)")
<< "Ignoring expansionRatio setting." << endl;
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //

View File

@ -63,7 +63,7 @@ public:
// Constructors // Constructors
//- Construct from components //- Construct from dictionary
sigmaRadial(const dictionary& dict); sigmaRadial(const dictionary& dict);

View File

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

View File

@ -77,7 +77,7 @@ public:
// Constructors // Constructors
//- Construct from components //- Construct from dictionary
wedge(const dictionary& dict); wedge(const dictionary& dict);

View File

@ -14,24 +14,28 @@ FoamFile
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Where to get surface from: either from surface ('surface') or // What to extrude:
// from (flipped) patch of existing case ('patch') // patch : from patch of another case ('sourceCase')
constructFrom patch; //surface; // mesh : as above but with original case included
// surface : from externally read surface
// If construct from (flipped) patch //constructFrom mesh;
sourceCase "$FOAM_RUN/icoFoam/cavity"; constructFrom patch;
//constructFrom surface;
// If construct from patch/mesh:
sourceCase "../cavity";
sourcePatch movingWall; sourcePatch movingWall;
// If construct from patch: patch to use for back (can be same as sourcePatch)
exposedPatchName movingWall;
// If construct from surface:
surface "movingWall.stl";
// Flip surface normals before usage. // Flip surface normals before usage.
flipNormals false; flipNormals false;
// If construct from surface
surface "movingWall.sMesh";
// Do front and back need to be merged? Usually only makes sense for 360
// degree wedges.
mergeFaces true;
//- Linear extrusion in point-normal direction //- Linear extrusion in point-normal direction
@ -46,11 +50,13 @@ extrudeModel wedge;
//- Extrudes into sphere with grading according to pressure (atmospherics) //- Extrudes into sphere with grading according to pressure (atmospherics)
//extrudeModel sigmaRadial; //extrudeModel sigmaRadial;
nLayers 20; nLayers 10;
expansionRatio 1.0; //0.9;
wedgeCoeffs wedgeCoeffs
{ {
axisPt (0 0.1 0); axisPt (0 0.1 -0.05);
axis (-1 0 0); axis (-1 0 0);
angle 360; // For nLayers=1 assume symmetry so angle/2 on each side angle 360; // For nLayers=1 assume symmetry so angle/2 on each side
} }
@ -73,5 +79,10 @@ sigmaRadialCoeffs
} }
// Do front and back need to be merged? Usually only makes sense for 360
// degree wedges.
mergeFaces true;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -208,8 +208,8 @@ void dumpCyclicMatch(const fileName& prefix, const polyMesh& mesh)
// Dump halves // Dump halves
{ {
OFstream str(prefix+cycPatch.name()+"_half0.obj"); OFstream str(prefix+cycPatch.name()+"_half0.obj");
Pout<< "Dumping cycPatch.name() half0 faces to " << str.name() Pout<< "Dumping " << cycPatch.name()
<< endl; << " half0 faces to " << str.name() << endl;
meshTools::writeOBJ meshTools::writeOBJ
( (
str, str,
@ -226,8 +226,8 @@ void dumpCyclicMatch(const fileName& prefix, const polyMesh& mesh)
} }
{ {
OFstream str(prefix+cycPatch.name()+"_half1.obj"); OFstream str(prefix+cycPatch.name()+"_half1.obj");
Pout<< "Dumping cycPatch.name() half1 faces to " << str.name() Pout<< "Dumping " << cycPatch.name()
<< endl; << " half1 faces to " << str.name() << endl;
meshTools::writeOBJ meshTools::writeOBJ
( (
str, str,
@ -563,7 +563,7 @@ int main(int argc, char *argv[])
dumpCyclicMatch("initial_", mesh); dumpCyclicMatch("initial_", mesh);
// Read patch construct info from dictionary // Read patch construct info from dictionary
PtrList<dictionary> patchSources(dict.lookup("patches")); PtrList<dictionary> patchSources(dict.lookup("patchInfo"));

View File

@ -46,7 +46,7 @@ matchTolerance 1E-3;
pointSync true; pointSync true;
// Patches to create. // Patches to create.
patches patchInfo
( (
{ {
// Name of new patch // Name of new patch

View File

@ -105,6 +105,8 @@ int main(int argc, char *argv[])
Foam::argList::validOptions.insert("overwrite", ""); Foam::argList::validOptions.insert("overwrite", "");
Foam::argList::validOptions.insert("toleranceDict", "file with tolerances");
# include "setRootCase.H" # include "setRootCase.H"
# include "createTime.H" # include "createTime.H"
runTime.functionObjects().off(); runTime.functionObjects().off();
@ -168,6 +170,22 @@ int main(int argc, char *argv[])
<< "If this is not the case use the -partial option" << nl << endl; << "If this is not the case use the -partial option" << nl << endl;
} }
// set up the tolerances for the sliding mesh
dictionary slidingTolerances;
if (args.options().found("toleranceDict"))
{
IOdictionary toleranceFile(
IOobject(
args.options()["toleranceDict"],
runTime.constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
slidingTolerances += toleranceFile;
}
// Check for non-empty master and slave patches // Check for non-empty master and slave patches
checkPatch(mesh.boundaryMesh(), masterPatchName); checkPatch(mesh.boundaryMesh(), masterPatchName);
checkPatch(mesh.boundaryMesh(), slavePatchName); checkPatch(mesh.boundaryMesh(), slavePatchName);
@ -320,6 +338,11 @@ int main(int argc, char *argv[])
true // couple/decouple mode true // couple/decouple mode
) )
); );
static_cast<slidingInterface&>(stitcher[0]).setTolerances
(
slidingTolerances,
true
);
} }

View File

@ -5,5 +5,6 @@ EXE_INC = \
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume \ -lfiniteVolume \
-lgenericPatchFields \
-llagrangian -llagrangian

View File

@ -6,4 +6,5 @@ EXE_INC = \
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume \ -lfiniteVolume \
-llagrangian \ -llagrangian \
-lgenericPatchFields \
-lconversion -lconversion

View File

@ -4,4 +4,5 @@ EXE_INC = \
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume \ -lfiniteVolume \
-lgenericPatchFields \
-llagrangian -llagrangian

View File

@ -14,4 +14,5 @@ EXE_INC = \
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume \ -lfiniteVolume \
-lgenericPatchFields \
-llagrangian -llagrangian

View File

@ -6,5 +6,6 @@ EXE_INC = \
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume \ -lfiniteVolume \
-llagrangian \ -llagrangian \
-lgenericPatchFields \
-lmeshTools -lmeshTools

View File

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

View File

@ -22,6 +22,7 @@ FoamFile
// jplot // jplot
// gnuplot // gnuplot
// raw // raw
// vtk
setFormat raw; setFormat raw;
// Surface output format. Choice of // Surface output format. Choice of
@ -62,6 +63,7 @@ fields
// curve specified points, not nessecary on line, uses // curve specified points, not nessecary on line, uses
// tracking // tracking
// cloud specified points, uses findCell // cloud specified points, uses findCell
// triSurfaceMeshPointSet points of triSurface
// //
// axis: how to write point coordinate. Choice of // axis: how to write point coordinate. Choice of
// - x/y/z: x/y/z coordinate only // - x/y/z: x/y/z coordinate only

View File

@ -130,6 +130,22 @@ for i in \
pointLevel \ pointLevel \
refinementHistory \ refinementHistory \
surfaceIndex \ surfaceIndex \
points.gz \
faces.gz \
owner.gz \
neighbour.gz \
cells.gz \
boundary.gz \
pointZones.gz \
faceZones.gz \
cellZones.gz \
meshModifiers.gz \
parallelData.gz \
sets.gz \
cellLevel.gz \
pointLevel.gz \
refinementHistory.gz \
surfaceIndex.gz \
; ;
do do
rm -rf $meshDir/$i rm -rf $meshDir/$i

View File

@ -72,6 +72,7 @@ cleanCase ()
constant/{cellToRegion,cellLevel*,pointLevel*} \ constant/{cellToRegion,cellLevel*,pointLevel*} \
constant/polyMesh/sets/ \ constant/polyMesh/sets/ \
VTK \ VTK \
sets/streamLines \
> /dev/null 2>&1 > /dev/null 2>&1
for f in `find . -name "*Dict"` for f in `find . -name "*Dict"`

View File

@ -117,12 +117,6 @@ public:
const std::streamsize bufSize const std::streamsize bufSize
); );
//- Non-blocking receives: wait until all have finished.
static void waitRequests();
//- Non-blocking receives: has request i finished?
static bool finishedRequest(const label i);
//- Return next token from stream //- Return next token from stream
Istream& read(token&); Istream& read(token&);

View File

@ -115,12 +115,6 @@ public:
const std::streamsize bufSize const std::streamsize bufSize
); );
//- Non-blocking writes: wait until all have finished.
static void waitRequests();
//- Non-blocking writes: has request i finished?
static bool finishedRequest(const label i);
//- Write next token to stream //- Write next token to stream
Ostream& write(const token&); Ostream& write(const token&);

View File

@ -264,6 +264,12 @@ public:
// Spawns slave processes and initialises inter-communication // Spawns slave processes and initialises inter-communication
static bool init(int& argc, char**& argv); static bool init(int& argc, char**& argv);
//- Non-blocking comms: wait until all have finished.
static void waitRequests();
//- Non-blocking comms: has request i finished?
static bool finishedRequest(const label i);
//- Is this a parallel run? //- Is this a parallel run?
static bool parRun() static bool parRun()
{ {

View File

@ -300,8 +300,7 @@ evaluate()
// Block for any outstanding requests // Block for any outstanding requests
if (Pstream::defaultCommsType == Pstream::nonBlocking) if (Pstream::defaultCommsType == Pstream::nonBlocking)
{ {
IPstream::waitRequests(); Pstream::waitRequests();
OPstream::waitRequests();
} }
forAll(*this, patchi) forAll(*this, patchi)

View File

@ -339,8 +339,7 @@ void Foam::mapDistribute::compact(const boolList& elemIsUsed)
// Wait for all to finish // Wait for all to finish
OPstream::waitRequests(); Pstream::waitRequests();
IPstream::waitRequests();
// Compact out all submap entries that are referring to unused elements // Compact out all submap entries that are referring to unused elements

View File

@ -287,8 +287,7 @@ void Foam::mapDistribute::distribute
// Wait till all finished // Wait till all finished
IPstream::waitRequests(); Pstream::waitRequests();
OPstream::waitRequests();
// Consume // Consume
for (label domain = 0; domain < Pstream::nProcs(); domain++) for (label domain = 0; domain < Pstream::nProcs(); domain++)
@ -413,8 +412,7 @@ void Foam::mapDistribute::distribute
// Wait for all to finish // Wait for all to finish
OPstream::waitRequests(); Pstream::waitRequests();
IPstream::waitRequests();
// Collect neighbour fields // Collect neighbour fields
@ -717,8 +715,7 @@ void Foam::mapDistribute::distribute
// Wait till all finished // Wait till all finished
IPstream::waitRequests(); Pstream::waitRequests();
OPstream::waitRequests();
// Consume // Consume
for (label domain = 0; domain < Pstream::nProcs(); domain++) for (label domain = 0; domain < Pstream::nProcs(); domain++)
@ -842,8 +839,7 @@ void Foam::mapDistribute::distribute
// Wait for all to finish // Wait for all to finish
OPstream::waitRequests(); Pstream::waitRequests();
IPstream::waitRequests();
// Collect neighbour fields // Collect neighbour fields

View File

@ -1305,7 +1305,7 @@ bool Foam::cyclicPolyPatch::order
{ {
label baffleI = 0; label baffleI = 0;
forAll(*this, faceI) forAll(pp, faceI)
{ {
const face& f = pp.localFaces()[faceI]; const face& f = pp.localFaces()[faceI];
const labelList& pFaces = pp.pointFaces()[f[0]]; const labelList& pFaces = pp.pointFaces()[f[0]];

View File

@ -86,17 +86,4 @@ int Foam::IPstream::read
} }
void Foam::IPstream::waitRequests()
{}
bool Foam::IPstream::finishedRequest(const label)
{
notImplemented("IPstream::finishedRequest()");
return false;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* // // ************************************************************************* //

View File

@ -65,17 +65,4 @@ bool Foam::OPstream::write
} }
void Foam::OPstream::waitRequests()
{}
bool Foam::OPstream::finishedRequest(const label)
{
notImplemented("OPstream::finishedRequest()");
return false;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* // // ************************************************************************* //

View File

@ -61,6 +61,17 @@ void Foam::Pstream::abort()
void Foam::reduce(scalar&, const sumOp<scalar>&) void Foam::reduce(scalar&, const sumOp<scalar>&)
{} {}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::Pstream::waitRequests()
{}
bool Foam::Pstream::finishedRequest(const label i)
{
notImplemented("Pstream::finishedRequest()");
return false;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -30,6 +30,7 @@ Description
#include "mpi.h" #include "mpi.h"
#include "IPstream.H" #include "IPstream.H"
#include "PstreamGlobals.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -37,7 +38,7 @@ Description
// Outstanding non-blocking operations. // Outstanding non-blocking operations.
//! @cond fileScope //! @cond fileScope
Foam::DynamicList<MPI_Request> IPstream_outstandingRequests_; //Foam::DynamicList<MPI_Request> IPstream_outstandingRequests_;
//! @endcond fileScope //! @endcond fileScope
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
@ -185,7 +186,7 @@ Foam::label Foam::IPstream::read
return 0; return 0;
} }
IPstream_outstandingRequests_.append(request); PstreamGlobals::outstandingRequests_.append(request);
// Assume the message is completely received. // Assume the message is completely received.
return bufSize; return bufSize;
@ -204,52 +205,6 @@ Foam::label Foam::IPstream::read
} }
void Foam::IPstream::waitRequests()
{
if (IPstream_outstandingRequests_.size())
{
if
(
MPI_Waitall
(
IPstream_outstandingRequests_.size(),
IPstream_outstandingRequests_.begin(),
MPI_STATUSES_IGNORE
)
)
{
FatalErrorIn
(
"IPstream::waitRequests()"
) << "MPI_Waitall returned with error" << endl;
}
IPstream_outstandingRequests_.clear();
}
}
bool Foam::IPstream::finishedRequest(const label i)
{
if (i >= IPstream_outstandingRequests_.size())
{
FatalErrorIn
(
"IPstream::finishedRequest(const label)"
) << "There are " << IPstream_outstandingRequests_.size()
<< " outstanding send requests and you are asking for i=" << i
<< nl
<< "Maybe you are mixing blocking/non-blocking comms?"
<< Foam::abort(FatalError);
}
int flag;
MPI_Test(&IPstream_outstandingRequests_[i], &flag, MPI_STATUS_IGNORE);
return flag != 0;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* // // ************************************************************************* //

View File

@ -1,5 +1,6 @@
OPwrite.C OPwrite.C
IPread.C IPread.C
Pstream.C Pstream.C
PstreamGlobals.C
LIB = $(FOAM_MPI_LIBBIN)/libPstream LIB = $(FOAM_MPI_LIBBIN)/libPstream

View File

@ -30,13 +30,7 @@ Description
#include "mpi.h" #include "mpi.h"
#include "OPstream.H" #include "OPstream.H"
#include "PstreamGlobals.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Outstanding non-blocking operations.
//! @cond fileScope
Foam::DynamicList<MPI_Request> OPstream_outstandingRequests_;
//! @endcond fileScope
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
@ -126,7 +120,7 @@ bool Foam::OPstream::write
&request &request
); );
OPstream_outstandingRequests_.append(request); PstreamGlobals::outstandingRequests_.append(request);
} }
else else
{ {
@ -142,52 +136,6 @@ bool Foam::OPstream::write
} }
void Foam::OPstream::waitRequests()
{
if (OPstream_outstandingRequests_.size())
{
if
(
MPI_Waitall
(
OPstream_outstandingRequests_.size(),
OPstream_outstandingRequests_.begin(),
MPI_STATUSES_IGNORE
)
)
{
FatalErrorIn
(
"OPstream::waitRequests()"
) << "MPI_Waitall returned with error" << Foam::endl;
}
OPstream_outstandingRequests_.clear();
}
}
bool Foam::OPstream::finishedRequest(const label i)
{
if (i >= OPstream_outstandingRequests_.size())
{
FatalErrorIn
(
"OPstream::finishedRequest(const label)"
) << "There are " << OPstream_outstandingRequests_.size()
<< " outstanding send requests and you are asking for i=" << i
<< nl
<< "Maybe you are mixing blocking/non-blocking comms?"
<< Foam::abort(FatalError);
}
int flag;
MPI_Test(&OPstream_outstandingRequests_[i], &flag, MPI_STATUS_IGNORE);
return flag != 0;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* // // ************************************************************************* //

View File

@ -29,6 +29,7 @@ License
#include "Pstream.H" #include "Pstream.H"
#include "PstreamReduceOps.H" #include "PstreamReduceOps.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "PstreamGlobals.H"
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
@ -130,6 +131,19 @@ void Foam::Pstream::exit(int errnum)
delete[] buff; delete[] buff;
# endif # endif
if (PstreamGlobals::outstandingRequests_.size())
{
label n = PstreamGlobals::outstandingRequests_.size();
PstreamGlobals::outstandingRequests_.clear();
WarningIn("Pstream::exit(int)")
<< "There are still " << n << " outstanding MPI_Requests." << endl
<< "This means that your code exited before doing a"
<< " Pstream::waitRequests()." << endl
<< "This should not happen for a normal code exit."
<< endl;
}
if (errnum == 0) if (errnum == 0)
{ {
MPI_Finalize(); MPI_Finalize();
@ -422,6 +436,57 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
} }
void Foam::Pstream::waitRequests()
{
if (PstreamGlobals::outstandingRequests_.size())
{
if
(
MPI_Waitall
(
PstreamGlobals::outstandingRequests_.size(),
PstreamGlobals::outstandingRequests_.begin(),
MPI_STATUSES_IGNORE
)
)
{
FatalErrorIn
(
"Pstream::waitRequests()"
) << "MPI_Waitall returned with error" << Foam::endl;
}
PstreamGlobals::outstandingRequests_.clear();
}
}
bool Foam::Pstream::finishedRequest(const label i)
{
if (i >= PstreamGlobals::outstandingRequests_.size())
{
FatalErrorIn
(
"Pstream::finishedRequest(const label)"
) << "There are " << PstreamGlobals::outstandingRequests_.size()
<< " outstanding send requests and you are asking for i=" << i
<< nl
<< "Maybe you are mixing blocking/non-blocking comms?"
<< Foam::abort(FatalError);
}
int flag;
MPI_Test
(
&PstreamGlobals::outstandingRequests_[i],
&flag,
MPI_STATUS_IGNORE
);
return flag != 0;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,45 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "PstreamGlobals.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Outstanding non-blocking operations.
//! @cond fileScope
DynamicList<MPI_Request> PstreamGlobals::outstandingRequests_;
//! @endcond fileScope
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,69 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Namespace
Foam::PstreamGlobals
Description
Global functions and variables for working with parallel streams,
but principally for gamma/mpi
SourceFiles
PstreamGlobals.C
\*---------------------------------------------------------------------------*/
#ifndef PstreamGlobals_H
#define PstreamGlobals_H
#include "mpi.h"
#include "DynamicList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class PstreamGlobals Declaration
\*---------------------------------------------------------------------------*/
namespace PstreamGlobals
{
extern DynamicList<MPI_Request> outstandingRequests_;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2987,6 +2987,7 @@ void Foam::autoLayerDriver::addLayers
( (
invExpansionRatio, invExpansionRatio,
pp, pp,
labelList(0), // exposed patchIDs, not used for adding layers
nPatchFaceLayers, // layers per face nPatchFaceLayers, // layers per face
nPatchPointLayers, // layers per point nPatchPointLayers, // layers per point
firstDisp, // thickness of layer nearest internal mesh firstDisp, // thickness of layer nearest internal mesh

View File

@ -38,6 +38,7 @@ Description
#include "polyModifyFace.H" #include "polyModifyFace.H"
#include "polyRemovePoint.H" #include "polyRemovePoint.H"
#include "polyRemoveFace.H" #include "polyRemoveFace.H"
#include "indirectPrimitivePatch.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -61,7 +62,7 @@ const Foam::scalar Foam::perfectInterface::tol_ = 1E-3;
Foam::pointField Foam::perfectInterface::calcFaceCentres Foam::pointField Foam::perfectInterface::calcFaceCentres
( (
const primitivePatch& pp const indirectPrimitivePatch& pp
) )
{ {
const pointField& points = pp.points(); const pointField& points = pp.points();
@ -155,6 +156,295 @@ bool Foam::perfectInterface::changeTopology() const
} }
void Foam::perfectInterface::setRefinement
(
const indirectPrimitivePatch& pp0,
const indirectPrimitivePatch& pp1,
polyTopoChange& ref
) const
{
const polyMesh& mesh = topoChanger().mesh();
const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Some aliases
const edgeList& edges0 = pp0.edges();
const pointField& pts0 = pp0.localPoints();
const pointField& pts1 = pp1.localPoints();
const labelList& meshPts0 = pp0.meshPoints();
const labelList& meshPts1 = pp1.meshPoints();
// Get local dimension as fraction of minimum edge length
scalar minLen = GREAT;
forAll(edges0, edgeI)
{
minLen = min(minLen, edges0[edgeI].mag(pts0));
}
scalar typDim = tol_*minLen;
if (debug)
{
Pout<< "typDim:" << typDim << " edges0:" << edges0.size()
<< " pts0:" << pts0.size() << " pts1:" << pts1.size()
<< " pp0:" << pp0.size() << " pp1:" << pp1.size() << endl;
}
// Determine pointMapping in mesh point labels. Uses geometric
// comparison to find correspondence between patch points.
labelList renumberPoints(mesh.points().size());
forAll(renumberPoints, i)
{
renumberPoints[i] = i;
}
{
labelList from1To0Points(pts1.size());
bool matchOk = matchPoints
(
pts1,
pts0,
scalarField(pts1.size(), typDim), // tolerance
true, // verbose
from1To0Points
);
if (!matchOk)
{
FatalErrorIn
(
"perfectInterface::setRefinement(polyTopoChange& ref) const"
) << "Points on patch sides do not match to within tolerance "
<< typDim << exit(FatalError);
}
forAll(pts1, i)
{
renumberPoints[meshPts1[i]] = meshPts0[from1To0Points[i]];
}
}
// Calculate correspondence between patch faces
labelList from0To1Faces(pp1.size());
bool matchOk = matchPoints
(
calcFaceCentres(pp0),
calcFaceCentres(pp1),
scalarField(pp0.size(), typDim), // tolerance
true, // verbose
from0To1Faces
);
if (!matchOk)
{
FatalErrorIn
(
"perfectInterface::setRefinement(polyTopoChange& ref) const"
) << "Face centres of patch sides do not match to within tolerance "
<< typDim << exit(FatalError);
}
// Now
// - renumber faces using pts1 (except patch1 faces)
// - remove patch1 faces. Remember cell label on owner side.
// - modify patch0 faces to be internal.
// 1. Get faces to be renumbered
labelHashSet affectedFaces(2*pp1.size());
forAll(meshPts1, i)
{
label meshPointI = meshPts1[i];
if (meshPointI != renumberPoints[meshPointI])
{
const labelList& pFaces = mesh.pointFaces()[meshPointI];
forAll(pFaces, pFaceI)
{
affectedFaces.insert(pFaces[pFaceI]);
}
}
}
forAll(pp1, i)
{
affectedFaces.erase(pp1.addressing()[i]);
}
// Remove patch0 from renumbered faces. Should not be nessecary since
// patch0 and 1 should not share any point (if created by mergeMeshing)
// so affectedFaces should not contain any patch0 faces but you can
// never be sure what the user is doing.
forAll(pp0, i)
{
label faceI = pp0.addressing()[i];
if (affectedFaces.erase(faceI))
{
WarningIn
(
"perfectInterface::setRefinement(polyTopoChange&) const"
) << "Found face " << faceI << " vertices "
<< mesh.faces()[faceI] << " whose points are"
<< " used both by master patch and slave patch" << endl;
}
}
// 2. Renumber (non patch0/1) faces.
for
(
labelHashSet::const_iterator iter = affectedFaces.begin();
iter != affectedFaces.end();
++iter
)
{
label faceI = iter.key();
const face& f = mesh.faces()[faceI];
face newFace(f.size());
forAll(newFace, fp)
{
newFace[fp] = renumberPoints[f[fp]];
}
label nbr = -1;
label patchI = -1;
if (mesh.isInternalFace(faceI))
{
nbr = mesh.faceNeighbour()[faceI];
}
else
{
patchI = patches.whichPatch(faceI);
}
label zoneID = mesh.faceZones().whichZone(faceI);
bool zoneFlip = false;
if (zoneID >= 0)
{
const faceZone& fZone = mesh.faceZones()[zoneID];
zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
}
ref.setAction
(
polyModifyFace
(
newFace, // modified face
faceI, // label of face being modified
mesh.faceOwner()[faceI], // owner
nbr, // neighbour
false, // face flip
patchI, // patch for face
false, // remove from zone
zoneID, // zone for face
zoneFlip // face flip in zone
)
);
}
// 3. Remove patch1 points
forAll(meshPts1, i)
{
label meshPointI = meshPts1[i];
if (meshPointI != renumberPoints[meshPointI])
{
ref.setAction(polyRemovePoint(meshPointI));
}
}
// 4. Remove patch1 faces
forAll(pp1, i)
{
label faceI = pp1.addressing()[i];
ref.setAction(polyRemoveFace(faceI));
}
// 5. Modify patch0 faces for new points (not really nessecary; see
// comment above about patch1 and patch0 never sharing points) and
// becoming internal.
const boolList& mfFlip =
mesh.faceZones()[faceZoneID_.index()].flipMap();
forAll(pp0, i)
{
label faceI = pp0.addressing()[i];
const face& f = mesh.faces()[faceI];
face newFace(f.size());
forAll(newFace, fp)
{
newFace[fp] = renumberPoints[f[fp]];
}
label own = mesh.faceOwner()[faceI];
label pp1FaceI = pp1.addressing()[from0To1Faces[i]];
label nbr = mesh.faceOwner()[pp1FaceI];
if (own < nbr)
{
ref.setAction
(
polyModifyFace
(
newFace, // modified face
faceI, // label of face being modified
own, // owner
nbr, // neighbour
false, // face flip
-1, // patch for face
false, // remove from zone
faceZoneID_.index(), // zone for face
mfFlip[i] // face flip in zone
)
);
}
else
{
ref.setAction
(
polyModifyFace
(
newFace.reverseFace(), // modified face
faceI, // label of face being modified
nbr, // owner
own, // neighbour
true, // face flip
-1, // patch for face
false, // remove from zone
faceZoneID_.index(), // zone for face
!mfFlip[i] // face flip in zone
)
);
}
}
}
void Foam::perfectInterface::setRefinement(polyTopoChange& ref) const void Foam::perfectInterface::setRefinement(polyTopoChange& ref) const
{ {
if (debug) if (debug)
@ -176,286 +466,25 @@ void Foam::perfectInterface::setRefinement(polyTopoChange& ref) const
const polyMesh& mesh = topoChanger().mesh(); const polyMesh& mesh = topoChanger().mesh();
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
const polyPatch& patch0 = patches[masterPatchID_.index()];
const polyPatch& pp0 = patches[masterPatchID_.index()]; const polyPatch& patch1 = patches[slavePatchID_.index()];
const polyPatch& pp1 = patches[slavePatchID_.index()];
// Some aliases
const edgeList& edges0 = pp0.edges();
const pointField& pts0 = pp0.localPoints();
const pointField& pts1 = pp1.localPoints();
const labelList& meshPts0 = pp0.meshPoints();
const labelList& meshPts1 = pp1.meshPoints();
// Get local dimension as fraction of minimum edge length
scalar minLen = GREAT;
forAll(edges0, edgeI)
{
minLen = min(minLen, edges0[edgeI].mag(pts0));
}
scalar typDim = tol_*minLen;
if (debug)
{
Pout<< "typDim:" << typDim << " edges0:" << edges0.size()
<< " pts0:" << pts0.size() << " pts1:" << pts1.size()
<< " pp0:" << pp0.size() << " pp1:" << pp1.size() << endl;
}
// Determine pointMapping in mesh point labels. Uses geometric labelList pp0Labels(identity(patch0.size())+patch0.start());
// comparison to find correspondence between patch points. indirectPrimitivePatch pp0
labelList renumberPoints(mesh.points().size());
forAll(renumberPoints, i)
{
renumberPoints[i] = i;
}
{
labelList from1To0Points(pts1.size());
bool matchOk = matchPoints
(
pts1,
pts0,
scalarField(pts1.size(), typDim), // tolerance
true, // verbose
from1To0Points
);
if (!matchOk)
{
FatalErrorIn
(
"perfectInterface::setRefinement(polyTopoChange& ref) const"
) << "Points on patches " << pp0.name() << " and "
<< pp1.name() << " do not match to within tolerance "
<< typDim << exit(FatalError);
}
forAll(pts1, i)
{
renumberPoints[meshPts1[i]] = meshPts0[from1To0Points[i]];
}
}
// Calculate correspondence between patch faces
labelList from0To1Faces(pp1.size());
bool matchOk = matchPoints
( (
calcFaceCentres(pp0), IndirectList<face>(mesh.faces(), pp0Labels),
calcFaceCentres(pp1), mesh.points()
scalarField(pp0.size(), typDim), // tolerance
true, // verbose
from0To1Faces
); );
if (!matchOk) labelList pp1Labels(identity(patch1.size())+patch1.start());
{ indirectPrimitivePatch pp1
FatalErrorIn
(
"perfectInterface::setRefinement(polyTopoChange& ref) const"
) << "Face centres of patches " << pp0.name() << " and "
<< pp1.name() << " do not match to within tolerance " << typDim
<< exit(FatalError);
}
// Now
// - renumber faces using pts1 (except patch1 faces)
// - remove patch1 faces. Remember cell label on owner side.
// - modify patch0 faces to be internal.
// 1. Get faces to be renumbered
labelHashSet affectedFaces(2*pp1.size());
forAll(meshPts1, i)
{
label meshPointI = meshPts1[i];
if (meshPointI != renumberPoints[meshPointI])
{
const labelList& pFaces = mesh.pointFaces()[meshPointI];
forAll(pFaces, pFaceI)
{
affectedFaces.insert(pFaces[pFaceI]);
}
}
}
forAll(pp1, i)
{
affectedFaces.erase(pp1.start() + i);
}
// Remove patch0 from renumbered faces. Should not be nessecary since
// patch0 and 1 should not share any point (if created by mergeMeshing)
// so affectedFaces should not contain any patch0 faces but you can
// never be sure what the user is doing.
forAll(pp0, i)
{
if (affectedFaces.erase(pp0.start() + i))
{
WarningIn
(
"perfectInterface::setRefinement(polyTopoChange&) const"
) << "Found face " << pp0.start() + i << " vertices "
<< mesh.faces()[pp0.start() + i] << " whose points are"
<< " used both by master patch " << pp0.name()
<< " and slave patch " << pp1.name()
<< endl;
}
}
// 2. Renumber (non patch0/1) faces.
for
( (
labelHashSet::const_iterator iter = affectedFaces.begin(); IndirectList<face>(mesh.faces(), pp1Labels),
iter != affectedFaces.end(); mesh.points()
++iter );
)
{
label faceI = iter.key();
const face& f = mesh.faces()[faceI]; setRefinement(pp0, pp1, ref);
face newFace(f.size());
forAll(newFace, fp)
{
newFace[fp] = renumberPoints[f[fp]];
}
label nbr = -1;
label patchI = -1;
if (mesh.isInternalFace(faceI))
{
nbr = mesh.faceNeighbour()[faceI];
}
else
{
patchI = patches.whichPatch(faceI);
}
label zoneID = mesh.faceZones().whichZone(faceI);
bool zoneFlip = false;
if (zoneID >= 0)
{
const faceZone& fZone = mesh.faceZones()[zoneID];
zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
}
ref.setAction
(
polyModifyFace
(
newFace, // modified face
faceI, // label of face being modified
mesh.faceOwner()[faceI], // owner
nbr, // neighbour
false, // face flip
patchI, // patch for face
false, // remove from zone
zoneID, // zone for face
zoneFlip // face flip in zone
)
);
}
// 3. Remove patch1 points
forAll(meshPts1, i)
{
label meshPointI = meshPts1[i];
if (meshPointI != renumberPoints[meshPointI])
{
ref.setAction(polyRemovePoint(meshPointI));
}
}
// 4. Remove patch1 faces
forAll(pp1, i)
{
ref.setAction(polyRemoveFace(pp1.start() + i));
}
// 5. Modify patch0 faces for new points (not really nessecary; see
// comment above about patch1 and patch0 never sharing points) and
// becoming internal.
const boolList& mfFlip =
mesh.faceZones()[faceZoneID_.index()].flipMap();
forAll(pp0, i)
{
label faceI = pp0.start() + i;
const face& f = mesh.faces()[faceI];
face newFace(f.size());
forAll(newFace, fp)
{
newFace[fp] = renumberPoints[f[fp]];
}
label own = mesh.faceOwner()[faceI];
label pp1FaceI = pp1.start() + from0To1Faces[i];
label nbr = mesh.faceOwner()[pp1FaceI];
if (own < nbr)
{
ref.setAction
(
polyModifyFace
(
newFace, // modified face
faceI, // label of face being modified
own, // owner
nbr, // neighbour
false, // face flip
-1, // patch for face
false, // remove from zone
faceZoneID_.index(), // zone for face
mfFlip[i] // face flip in zone
)
);
}
else
{
ref.setAction
(
polyModifyFace
(
newFace.reverseFace(), // modified face
faceI, // label of face being modified
nbr, // owner
own, // neighbour
false, // face flip
-1, // patch for face
false, // remove from zone
faceZoneID_.index(), // zone for face
!mfFlip[i] // face flip in zone
)
);
}
}
} }
} }

View File

@ -40,6 +40,7 @@ SourceFiles
#include "polyMeshModifier.H" #include "polyMeshModifier.H"
#include "polyPatchID.H" #include "polyPatchID.H"
#include "ZoneIDs.H" #include "ZoneIDs.H"
#include "indirectPrimitivePatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -75,7 +76,7 @@ class perfectInterface
// Private Member Functions // Private Member Functions
//- Calculate face centres on patch //- Calculate face centres on patch
static pointField calcFaceCentres(const primitivePatch&); static pointField calcFaceCentres(const indirectPrimitivePatch&);
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
@ -128,6 +129,17 @@ public:
// into the topological change // into the topological change
virtual void setRefinement(polyTopoChange&) const; virtual void setRefinement(polyTopoChange&) const;
//- Insert the layer addition/removal instructions
// into the topological change. Uses only mesh, not any of the
// patch and zone indices. Bit of a workaround - used in extruding
// a mesh.
virtual void setRefinement
(
const indirectPrimitivePatch& pp0,
const indirectPrimitivePatch& pp1,
polyTopoChange&
) const;
//- Modify motion points to comply with the topological change //- Modify motion points to comply with the topological change
virtual void modifyMotionPoints(pointField& motionPoints) const; virtual void modifyMotionPoints(pointField& motionPoints) const;

View File

@ -335,17 +335,19 @@ Foam::label Foam::addPatchCellLayer::addSideFace
label inflateEdgeI = -1; label inflateEdgeI = -1;
// Check mesh faces using edge // Check mesh faces using edge
forAll(meshFaces, i) if (addToMesh_)
{ {
if (mesh_.isInternalFace(meshFaces[i])) forAll(meshFaces, i)
{ {
// meshEdge uses internal faces so ok to inflate from it if (mesh_.isInternalFace(meshFaces[i]))
inflateEdgeI = meshEdgeI; {
break; // meshEdge uses internal faces so ok to inflate from it
inflateEdgeI = meshEdgeI;
break;
}
} }
} }
// Get my mesh face and its zone. // Get my mesh face and its zone.
label meshFaceI = pp.addressing()[ownFaceI]; label meshFaceI = pp.addressing()[ownFaceI];
label zoneI = mesh_.faceZones().whichZone(meshFaceI); label zoneI = mesh_.faceZones().whichZone(meshFaceI);
@ -504,9 +506,14 @@ Foam::label Foam::addPatchCellLayer::addSideFace
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from mesh // Construct from mesh
Foam::addPatchCellLayer::addPatchCellLayer(const polyMesh& mesh) Foam::addPatchCellLayer::addPatchCellLayer
(
const polyMesh& mesh,
const bool addToMesh
)
: :
mesh_(mesh), mesh_(mesh),
addToMesh_(addToMesh),
addedPoints_(0), addedPoints_(0),
layerFaces_(0) layerFaces_(0)
{} {}
@ -551,6 +558,7 @@ void Foam::addPatchCellLayer::setRefinement
( (
const scalarField& expansionRatio, const scalarField& expansionRatio,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelList& exposedPatchID,
const labelList& nFaceLayers, const labelList& nFaceLayers,
const labelList& nPointLayers, const labelList& nPointLayers,
const vectorField& firstLayerDisp, const vectorField& firstLayerDisp,
@ -827,6 +835,19 @@ void Foam::addPatchCellLayer::setRefinement
} }
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Precalculated patchID for each patch face
labelList patchID(pp.size());
forAll(pp, patchFaceI)
{
label meshFaceI = pp.addressing()[patchFaceI];
patchID[patchFaceI] = patches.whichPatch(meshFaceI);
}
// From master point (in patch point label) to added points (in mesh point // From master point (in patch point label) to added points (in mesh point
// label) // label)
addedPoints_.setSize(pp.nPoints()); addedPoints_.setSize(pp.nPoints());
@ -857,6 +878,33 @@ void Foam::addPatchCellLayer::setRefinement
// Create new points // Create new points
// //
// If creating new mesh: copy existing patch points
labelList copiedPatchPoints;
if (!addToMesh_)
{
copiedPatchPoints.setSize(firstLayerDisp.size());
forAll(firstLayerDisp, patchPointI)
{
if (addedPoints_[patchPointI].size())
{
label meshPointI = meshPoints[patchPointI];
label zoneI = mesh_.pointZones().whichZone(meshPointI);
copiedPatchPoints[patchPointI] = meshMod.setAction
(
polyAddPoint
(
mesh_.points()[meshPointI], // point
-1, // master point
zoneI, // zone for point
true // supports a cell
)
);
}
}
}
// Create points for additional layers
forAll(firstLayerDisp, patchPointI) forAll(firstLayerDisp, patchPointI)
{ {
if (addedPoints_[patchPointI].size()) if (addedPoints_[patchPointI].size())
@ -878,7 +926,7 @@ void Foam::addPatchCellLayer::setRefinement
polyAddPoint polyAddPoint
( (
pt, // point pt, // point
meshPointI, // master point (addToMesh_ ? meshPointI : -1), // master point
zoneI, // zone for point zoneI, // zone for point
true // supports a cell true // supports a cell
) )
@ -922,34 +970,15 @@ void Foam::addPatchCellLayer::setRefinement
-1, // master point -1, // master point
-1, // master edge -1, // master edge
-1, // master face -1, // master face
mesh_.faceOwner()[meshFaceI], // master cell id (addToMesh_ ? mesh_.faceOwner()[meshFaceI] : -1),//master
ownZoneI // zone for cell ownZoneI // zone for cell
) )
); );
//Pout<< "For patchFace:" << patchFaceI
// << " meshFace:" << pp.addressing()[patchFaceI]
// << " layer:" << i << " added cell:"
// << addedCells[patchFaceI][i]
// << endl;
} }
} }
} }
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Precalculated patchID for each patch face
labelList patchID(pp.size());
forAll(pp, patchFaceI)
{
label meshFaceI = pp.addressing()[patchFaceI];
patchID[patchFaceI] = patches.whichPatch(meshFaceI);
}
// Create faces on top of the original patch faces. // Create faces on top of the original patch faces.
// These faces are created from original patch faces outwards so in order // These faces are created from original patch faces outwards so in order
@ -965,7 +994,6 @@ void Foam::addPatchCellLayer::setRefinement
if (addedCells[patchFaceI].size()) if (addedCells[patchFaceI].size())
{ {
layerFaces_[patchFaceI].setSize(addedCells[patchFaceI].size() + 1); layerFaces_[patchFaceI].setSize(addedCells[patchFaceI].size() + 1);
layerFaces_[patchFaceI][0] = meshFaceI;
label zoneI = mesh_.faceZones().whichZone(meshFaceI); label zoneI = mesh_.faceZones().whichZone(meshFaceI);
@ -981,7 +1009,12 @@ void Foam::addPatchCellLayer::setRefinement
if (addedPoints_[f[fp]].empty()) if (addedPoints_[f[fp]].empty())
{ {
// Keep original point // Keep original point
newFace[fp] = meshPoints[f[fp]]; newFace[fp] =
(
addToMesh_
? meshPoints[f[fp]]
: copiedPatchPoints[f[fp]]
);
} }
else else
{ {
@ -1021,18 +1054,13 @@ void Foam::addPatchCellLayer::setRefinement
nei, // neighbour nei, // neighbour
-1, // master point -1, // master point
-1, // master edge -1, // master edge
meshFaceI, // master face for addition (addToMesh_ ? meshFaceI : -1), // master face
false, // flux flip false, // flux flip
patchI, // patch for face patchI, // patch for face
zoneI, // zone for face zoneI, // zone for face
false // face zone flip false // face zone flip
) )
); );
//Pout<< "Added inbetween face " << newFace
// << " own:" << addedCells[patchFaceI][i]
// << " nei:" << nei
// << " patch:" << patchI
// << endl;
} }
} }
} }
@ -1040,35 +1068,81 @@ void Foam::addPatchCellLayer::setRefinement
// //
// Modify old patch faces to be on the inside // Modify old patch faces to be on the inside
// //
forAll(pp, patchFaceI)
if (addToMesh_)
{ {
if (addedCells[patchFaceI].size()) forAll(pp, patchFaceI)
{ {
label meshFaceI = pp.addressing()[patchFaceI]; if (addedCells[patchFaceI].size())
{
label meshFaceI = pp.addressing()[patchFaceI];
label zoneI = mesh_.faceZones().whichZone(meshFaceI); layerFaces_[patchFaceI][0] = meshFaceI;
meshMod.setAction label zoneI = mesh_.faceZones().whichZone(meshFaceI);
(
polyModifyFace meshMod.setAction
( (
pp[patchFaceI], // modified face polyModifyFace
meshFaceI, // label of face (
mesh_.faceOwner()[meshFaceI], // owner pp[patchFaceI], // modified face
addedCells[patchFaceI][0], // neighbour meshFaceI, // label of face
false, // face flip mesh_.faceOwner()[meshFaceI], // owner
-1, // patch for face addedCells[patchFaceI][0], // neighbour
false, // remove from zone false, // face flip
zoneI, // zone for face -1, // patch for face
false // face flip in zone false, // remove from zone
) zoneI, // zone for face
); false // face flip in zone
//Pout<< "Modified old patch face " << meshFaceI )
// << " own:" << mesh_.faceOwner()[meshFaceI] );
// << " nei:" << addedCells[patchFaceI][0] }
// << endl;
} }
} }
else
{
// If creating new mesh: reverse original faces and put them
// in the exposed patch ID.
forAll(pp, patchFaceI)
{
if (nFaceLayers[patchFaceI] > 0)
{
label meshFaceI = pp.addressing()[patchFaceI];
label zoneI = mesh_.faceZones().whichZone(meshFaceI);
bool zoneFlip = false;
if (zoneI != -1)
{
const faceZone& fz = mesh_.faceZones()[zoneI];
zoneFlip = !fz.flipMap()[fz.whichFace(meshFaceI)];
}
// Reverse and renumber old patch face.
face f(pp.localFaces()[patchFaceI].reverseFace());
forAll(f, fp)
{
f[fp] = copiedPatchPoints[f[fp]];
}
layerFaces_[patchFaceI][0] = meshMod.setAction
(
polyAddFace
(
f, // modified face
addedCells[patchFaceI][0], // owner
-1, // neighbour
-1, // masterPoint
-1, // masterEdge
-1, // masterFace
true, // face flip
exposedPatchID[patchFaceI], // patch for face
zoneI, // zone for face
zoneFlip // face flip in zone
)
);
}
}
}
// //
@ -1255,7 +1329,16 @@ void Foam::addPatchCellLayer::setRefinement
forAll(stringedVerts, stringedI) forAll(stringedVerts, stringedI)
{ {
label v = stringedVerts[stringedI]; label v = stringedVerts[stringedI];
addVertex(meshPoints[v], newFace, newFp); addVertex
(
(
addToMesh_
? meshPoints[v]
: copiedPatchPoints[v]
),
newFace,
newFp
);
} }
} }
else else
@ -1276,7 +1359,16 @@ void Foam::addPatchCellLayer::setRefinement
} }
else else
{ {
addVertex(meshPoints[v], newFace, newFp); addVertex
(
(
addToMesh_
? meshPoints[v]
: copiedPatchPoints[v]
),
newFace,
newFp
);
} }
} }
} }
@ -1316,7 +1408,16 @@ void Foam::addPatchCellLayer::setRefinement
} }
else else
{ {
addVertex(meshPoints[v], newFace, newFp); addVertex
(
(
addToMesh_
? meshPoints[v]
: copiedPatchPoints[v]
),
newFace,
newFp
);
} }
} }

View File

@ -26,7 +26,8 @@ Class
Foam::addPatchCellLayer Foam::addPatchCellLayer
Description Description
Adds layers of cells to outside of polyPatch. Adds layers of cells to outside of polyPatch. Can optionally create
stand-alone extruded mesh (addToMesh=false).
Call setRefinement with offset vector for every patch point and number Call setRefinement with offset vector for every patch point and number
of layers per patch face and number of layers per patch point. of layers per patch face and number of layers per patch point.
@ -164,6 +165,9 @@ class addPatchCellLayer
//- Reference to mesh //- Reference to mesh
const polyMesh& mesh_; const polyMesh& mesh_;
//- Add layers to existing mesh or create new mesh
const bool addToMesh_;
//- For all patchpoints: list of added points (size 0 or nLayers) //- For all patchpoints: list of added points (size 0 or nLayers)
// First point in list is one nearest to original point in patch, // First point in list is one nearest to original point in patch,
// last one is the new point on the surface. // last one is the new point on the surface.
@ -253,7 +257,7 @@ public:
// Constructors // Constructors
//- Construct from mesh. //- Construct from mesh.
addPatchCellLayer(const polyMesh& mesh); addPatchCellLayer(const polyMesh& mesh, const bool addToMesh = true);
// Member Functions // Member Functions
@ -291,8 +295,10 @@ public:
//- Play commands into polyTopoChange to create layers on top //- Play commands into polyTopoChange to create layers on top
// of indirectPrimitivePatch (have to be outside faces). // of indirectPrimitivePatch (have to be outside faces).
// Gets displacement per patch point. // Gets displacement per patch point.
// - nPointLayers : number of layers per (patch)point // - exposedPatchID : only used if creating a new mesh (addToMesh=false)
// - nFaceLayers : number of layers per (patch) face // gives per pp face the patch the exposed face should get.
// - nPointLayers : number of layers per (patch)point.
// - nFaceLayers : number of layers per (patch) face.
// - firstDisplacement : displacement per point for first // - firstDisplacement : displacement per point for first
// layer of points (i.e. nearest to original mesh). If zero // layer of points (i.e. nearest to original mesh). If zero
// do not add point. // do not add point.
@ -305,14 +311,15 @@ public:
// get a cell should firstDisplacement be <> 0 // get a cell should firstDisplacement be <> 0
// Note: cells get added from owner cells of patch faces // Note: cells get added from owner cells of patch faces
// (instead of e.g. from patch faces) // (instead of e.g. from patch faces)
void setRefinement void setRefinement
( (
const scalarField& expansionRatio, const scalarField& expansionRatio,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelList& nFaceLayers, const labelList& exposedPatchID,
const labelList& nPointLayers, const labelList& nFaceLayers,
const vectorField& firstLayerDisp, const labelList& nPointLayers,
polyTopoChange& meshMod const vectorField& firstLayerDisp,
polyTopoChange& meshMod
); );
@ -329,6 +336,7 @@ public:
( (
scalarField(pp.nPoints(), 1.0), // expansion ration scalarField(pp.nPoints(), 1.0), // expansion ration
pp, pp,
labelList(0),
labelList(pp.size(), nLayers), labelList(pp.size(), nLayers),
labelList(pp.nPoints(), nLayers), labelList(pp.nPoints(), nLayers),
overallDisplacement / nLayers, overallDisplacement / nLayers,

View File

@ -749,6 +749,11 @@ void Foam::polyTopoChange::getFaceOrder
" const" " const"
) << "Did not determine new position" ) << "Did not determine new position"
<< " for face " << faceI << " for face " << faceI
<< " owner " << faceOwner_[faceI]
<< " neighbour " << faceNeighbour_[faceI]
<< " region " << region_[faceI] << endl
<< "This is usually caused by not specifying a patch for"
<< " a boundary face."
<< abort(FatalError); << abort(FatalError);
} }
} }
@ -3176,7 +3181,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
( (
autoPtr<fvMesh>& newMeshPtr, autoPtr<fvMesh>& newMeshPtr,
const IOobject& io, const IOobject& io,
const fvMesh& mesh, const polyMesh& mesh,
const bool syncParallel, const bool syncParallel,
const bool orderCells, const bool orderCells,
const bool orderPoints const bool orderPoints

View File

@ -585,7 +585,7 @@ public:
( (
autoPtr<fvMesh>& newMesh, autoPtr<fvMesh>& newMesh,
const IOobject& io, const IOobject& io,
const fvMesh& mesh, const polyMesh& mesh,
const bool syncParallel = true, const bool syncParallel = true,
const bool orderCells = false, const bool orderCells = false,
const bool orderPoints = false const bool orderPoints = false

View File

@ -43,7 +43,7 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::scalar Foam::slidingInterface::edgeCoPlanarTol_ = 0.8; const Foam::scalar Foam::slidingInterface::edgeCoPlanarTolDefault_ = 0.8;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //

View File

@ -27,10 +27,8 @@ License
#include "slidingInterface.H" #include "slidingInterface.H"
#include "polyTopoChanger.H" #include "polyTopoChanger.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "primitiveMesh.H"
#include "polyTopoChange.H" #include "polyTopoChange.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "triPointRef.H"
#include "plane.H" #include "plane.H"
// Index of debug signs: // Index of debug signs:
@ -173,6 +171,14 @@ Foam::slidingInterface::slidingInterface
attached_(false), attached_(false),
projectionAlgo_(algo), projectionAlgo_(algo),
trigger_(false), trigger_(false),
pointMergeTol_(pointMergeTolDefault_),
edgeMergeTol_(edgeMergeTolDefault_),
nFacesPerSlaveEdge_(nFacesPerSlaveEdgeDefault_),
edgeFaceEscapeLimit_(edgeFaceEscapeLimitDefault_),
integralAdjTol_(integralAdjTolDefault_),
edgeMasterCatchFraction_(edgeMasterCatchFractionDefault_),
edgeCoPlanarTol_(edgeCoPlanarTolDefault_),
edgeEndCutoffTol_(edgeEndCutoffTolDefault_),
cutFaceMasterPtr_(NULL), cutFaceMasterPtr_(NULL),
cutFaceSlavePtr_(NULL), cutFaceSlavePtr_(NULL),
masterFaceCellsPtr_(NULL), masterFaceCellsPtr_(NULL),
@ -280,6 +286,9 @@ Foam::slidingInterface::slidingInterface
masterPointEdgeHitsPtr_(NULL), masterPointEdgeHitsPtr_(NULL),
projectedSlavePointsPtr_(NULL) projectedSlavePointsPtr_(NULL)
{ {
// Optionally default tolerances from dictionary
setTolerances(dict);
checkDefinition(); checkDefinition();
// If the interface is attached, the master and slave face zone addressing // If the interface is attached, the master and slave face zone addressing
@ -686,6 +695,63 @@ const Foam::pointField& Foam::slidingInterface::pointProjection() const
return *projectedSlavePointsPtr_; return *projectedSlavePointsPtr_;
} }
void Foam::slidingInterface::setTolerances(const dictionary&dict, bool report)
{
pointMergeTol_ = dict.lookupOrDefault<scalar>
(
"pointMergeTol",
pointMergeTol_
);
edgeMergeTol_ = dict.lookupOrDefault<scalar>
(
"edgeMergeTol",
edgeMergeTol_
);
nFacesPerSlaveEdge_ = dict.lookupOrDefault<scalar>
(
"nFacesPerSlaveEdge",
nFacesPerSlaveEdge_
);
edgeFaceEscapeLimit_ = dict.lookupOrDefault<scalar>
(
"edgeFaceEscapeLimit",
edgeFaceEscapeLimit_
);
integralAdjTol_ = dict.lookupOrDefault<scalar>
(
"integralAdjTol",
integralAdjTol_
);
edgeMasterCatchFraction_ = dict.lookupOrDefault<scalar>
(
"edgeMasterCatchFraction",
edgeMasterCatchFraction_
);
edgeCoPlanarTol_ = dict.lookupOrDefault<scalar>
(
"edgeCoPlanarTol",
edgeCoPlanarTol_
);
edgeEndCutoffTol_ = dict.lookupOrDefault<scalar>
(
"edgeEndCutoffTol",
edgeEndCutoffTol_
);
if (report)
{
Info<< "Sliding interface parameters:" << nl
<< "pointMergeTol : " << pointMergeTol_ << nl
<< "edgeMergeTol : " << edgeMergeTol_ << nl
<< "nFacesPerSlaveEdge : " << nFacesPerSlaveEdge_ << nl
<< "edgeFaceEscapeLimit : " << edgeFaceEscapeLimit_ << nl
<< "integralAdjTol : " << integralAdjTol_ << nl
<< "edgeMasterCatchFraction : " << edgeMasterCatchFraction_ << nl
<< "edgeCoPlanarTol : " << edgeCoPlanarTol_ << nl
<< "edgeEndCutoffTol : " << edgeEndCutoffTol_ << endl;
}
}
void Foam::slidingInterface::write(Ostream& os) const void Foam::slidingInterface::write(Ostream& os) const
{ {
@ -703,6 +769,14 @@ void Foam::slidingInterface::write(Ostream& os) const
} }
// To write out all those tolerances
#define WRITE_NON_DEFAULT(name) \
if( name ## _ != name ## Default_ )\
{ \
os << " " #name " " << name ## _ << token::END_STATEMENT << nl; \
}
void Foam::slidingInterface::writeDict(Ostream& os) const void Foam::slidingInterface::writeDict(Ostream& os) const
{ {
os << nl << name() << nl << token::BEGIN_BLOCK << nl os << nl << name() << nl << token::BEGIN_BLOCK << nl
@ -743,6 +817,15 @@ void Foam::slidingInterface::writeDict(Ostream& os) const
<< token::END_STATEMENT << nl; << token::END_STATEMENT << nl;
} }
WRITE_NON_DEFAULT(pointMergeTol)
WRITE_NON_DEFAULT(edgeMergeTol)
WRITE_NON_DEFAULT(nFacesPerSlaveEdge)
WRITE_NON_DEFAULT(edgeFaceEscapeLimit)
WRITE_NON_DEFAULT(integralAdjTol)
WRITE_NON_DEFAULT(edgeMasterCatchFraction)
WRITE_NON_DEFAULT(edgeCoPlanarTol)
WRITE_NON_DEFAULT(edgeEndCutoffTol)
os << token::END_BLOCK << endl; os << token::END_BLOCK << endl;
} }

View File

@ -129,6 +129,32 @@ private:
//- Trigger topological change //- Trigger topological change
mutable bool trigger_; mutable bool trigger_;
// Tolerances. Initialised to static ones below.
//- Point merge tolerance
scalar pointMergeTol_;
//- Edge merge tolerance
scalar edgeMergeTol_;
//- Estimated number of faces an edge goes through
label nFacesPerSlaveEdge_;
//- Edge-face interaction escape limit
label edgeFaceEscapeLimit_;
//- Integral match point adjustment tolerance
scalar integralAdjTol_;
//- Edge intersection master catch fraction
scalar edgeMasterCatchFraction_;
//- Edge intersection co-planar tolerance
scalar edgeCoPlanarTol_;
//- Edge end cut-off tolerance
scalar edgeEndCutoffTol_;
// Private addressing data. // Private addressing data.
@ -256,28 +282,28 @@ private:
// Static data members // Static data members
//- Point merge tolerance //- Point merge tolerance
static const scalar pointMergeTol_; static const scalar pointMergeTolDefault_;
//- Edge merge tolerance //- Edge merge tolerance
static const scalar edgeMergeTol_; static const scalar edgeMergeTolDefault_;
//- Estimated number of faces an edge goes through //- Estimated number of faces an edge goes through
static const label nFacesPerSlaveEdge_; static const label nFacesPerSlaveEdgeDefault_;
//- Edge-face interaction escape limit //- Edge-face interaction escape limit
static const label edgeFaceEscapeLimit_; static const label edgeFaceEscapeLimitDefault_;
//- Integral match point adjustment tolerance //- Integral match point adjustment tolerance
static const scalar integralAdjTol_; static const scalar integralAdjTolDefault_;
//- Edge intersection master catch fraction //- Edge intersection master catch fraction
static const scalar edgeMasterCatchFraction_; static const scalar edgeMasterCatchFractionDefault_;
//- Edge intersection co-planar tolerance //- Edge intersection co-planar tolerance
static const scalar edgeCoPlanarTol_; static const scalar edgeCoPlanarTolDefault_;
//- Edge end cut-off tolerance //- Edge end cut-off tolerance
static const scalar edgeEndCutoffTol_; static const scalar edgeEndCutoffTolDefault_;
public: public:
@ -350,6 +376,8 @@ public:
//- Return projected points for a slave patch //- Return projected points for a slave patch
const pointField& pointProjection() const; const pointField& pointProjection() const;
//- Set the tolerances from the values in a dictionary
void setTolerances(const dictionary&, bool report=false);
//- Write //- Write
virtual void write(Ostream&) const; virtual void write(Ostream&) const;

View File

@ -26,22 +26,19 @@ License
#include "slidingInterface.H" #include "slidingInterface.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "primitiveMesh.H"
#include "line.H" #include "line.H"
#include "triPointRef.H"
#include "plane.H"
#include "polyTopoChanger.H" #include "polyTopoChanger.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::scalar Foam::slidingInterface::pointMergeTol_ = 0.05; const Foam::scalar Foam::slidingInterface::pointMergeTolDefault_ = 0.05;
const Foam::scalar Foam::slidingInterface::edgeMergeTol_ = 0.01; const Foam::scalar Foam::slidingInterface::edgeMergeTolDefault_ = 0.01;
const Foam::label Foam::slidingInterface::nFacesPerSlaveEdge_ = 5; const Foam::label Foam::slidingInterface::nFacesPerSlaveEdgeDefault_ = 5;
const Foam::label Foam::slidingInterface::edgeFaceEscapeLimit_ = 10; const Foam::label Foam::slidingInterface::edgeFaceEscapeLimitDefault_ = 10;
const Foam::scalar Foam::slidingInterface::integralAdjTol_ = 0.05; const Foam::scalar Foam::slidingInterface::integralAdjTolDefault_ = 0.05;
const Foam::scalar Foam::slidingInterface::edgeMasterCatchFraction_ = 0.4; const Foam::scalar Foam::slidingInterface::edgeMasterCatchFractionDefault_ = 0.4;
const Foam::scalar Foam::slidingInterface::edgeEndCutoffTol_ = 0.0001; const Foam::scalar Foam::slidingInterface::edgeEndCutoffTolDefault_ = 0.0001;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //

View File

@ -45,7 +45,7 @@ Foam::linearUpwind<Type>::correction
( (
IOobject IOobject
( (
"linearUpwindCorrection(" + vf.name() + ')', "linearUpwind::correction(" + vf.name() + ')',
mesh.time().timeName(), mesh.time().timeName(),
mesh, mesh,
IOobject::NO_READ, IOobject::NO_READ,

View File

@ -38,93 +38,96 @@ Foam::linearUpwindV<Type>::correction
const GeometricField<Type, fvPatchField, volMesh>& vf const GeometricField<Type, fvPatchField, volMesh>& vf
) const ) const
{ {
const fvMesh& mesh = this->mesh(); const fvMesh& mesh = this->mesh();
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr
( (
new GeometricField<Type, fvsPatchField, surfaceMesh> new GeometricField<Type, fvsPatchField, surfaceMesh>
( (
IOobject IOobject
( (
vf.name(), "linearUpwindV::correction(" + vf.name() + ')',
mesh.time().timeName(), mesh.time().timeName(),
mesh mesh,
), IOobject::NO_READ,
mesh, IOobject::NO_WRITE,
dimensioned<Type> false
( ),
vf.name(), mesh,
vf.dimensions(), dimensioned<Type>
pTraits<Type>::zero (
) vf.name(),
) vf.dimensions(),
); pTraits<Type>::zero
)
)
);
GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr(); GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr();
const surfaceScalarField& faceFlux = this->faceFlux_; const surfaceScalarField& faceFlux = this->faceFlux_;
const surfaceScalarField& w = mesh.weights(); const surfaceScalarField& w = mesh.weights();
const labelList& own = mesh.owner(); const labelList& own = mesh.owner();
const labelList& nei = mesh.neighbour(); const labelList& nei = mesh.neighbour();
const vectorField& C = mesh.C(); const vectorField& C = mesh.C();
const vectorField& Cf = mesh.Cf(); const vectorField& Cf = mesh.Cf();
GeometricField GeometricField
<typename outerProduct<vector, Type>::type, fvPatchField, volMesh> <typename outerProduct<vector, Type>::type, fvPatchField, volMesh>
gradVf = gradScheme_().grad(vf); gradVf = gradScheme_().grad(vf);
forAll(faceFlux, facei) forAll(faceFlux, facei)
{ {
vector maxCorr; vector maxCorr;
if (faceFlux[facei] > 0.0) if (faceFlux[facei] > 0.0)
{ {
maxCorr = maxCorr =
(1.0 - w[facei]) (1.0 - w[facei])
*(vf[nei[facei]] - vf[own[facei]]); *(vf[nei[facei]] - vf[own[facei]]);
sfCorr[facei] = sfCorr[facei] =
(Cf[facei] - C[own[facei]]) & gradVf[own[facei]]; (Cf[facei] - C[own[facei]]) & gradVf[own[facei]];
} }
else else
{ {
maxCorr = maxCorr =
w[facei]*(vf[own[facei]] - vf[nei[facei]]); w[facei]*(vf[own[facei]] - vf[nei[facei]]);
sfCorr[facei] = sfCorr[facei] =
(Cf[facei] - C[nei[facei]]) & gradVf[nei[facei]]; (Cf[facei] - C[nei[facei]]) & gradVf[nei[facei]];
} }
scalar sfCorrs = magSqr(sfCorr[facei]); scalar sfCorrs = magSqr(sfCorr[facei]);
scalar maxCorrs = sfCorr[facei] & maxCorr; scalar maxCorrs = sfCorr[facei] & maxCorr;
if (sfCorrs > 0) if (sfCorrs > 0)
{ {
if (maxCorrs < 0) if (maxCorrs < 0)
{ {
sfCorr[facei] = vector::zero; sfCorr[facei] = vector::zero;
} }
else if (sfCorrs > maxCorrs) else if (sfCorrs > maxCorrs)
{ {
sfCorr[facei] *= maxCorrs/(sfCorrs + VSMALL); sfCorr[facei] *= maxCorrs/(sfCorrs + VSMALL);
} }
} }
else if (sfCorrs < 0) else if (sfCorrs < 0)
{ {
if (maxCorrs > 0) if (maxCorrs > 0)
{ {
sfCorr[facei] = vector::zero; sfCorr[facei] = vector::zero;
} }
else if (sfCorrs < maxCorrs) else if (sfCorrs < maxCorrs)
{ {
sfCorr[facei] *= maxCorrs/(sfCorrs - VSMALL); sfCorr[facei] *= maxCorrs/(sfCorrs - VSMALL);
} }
} }
} }
return tsfCorr; return tsfCorr;
} }

View File

@ -131,9 +131,12 @@ public:
( (
IOobject IOobject
( (
vf.name(), "cubic::correction(" + vf.name() +')',
mesh.time().timeName(), mesh.time().timeName(),
mesh mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
), ),
surfaceInterpolationScheme<Type>::interpolate(vf, kSc, -kSc) surfaceInterpolationScheme<Type>::interpolate(vf, kSc, -kSc)
) )

View File

@ -133,7 +133,7 @@ public:
( (
IOobject IOobject
( (
vf.name(), "localMax::interpolate(" + vf.name() + ')',
mesh.time().timeName(), mesh.time().timeName(),
mesh mesh
), ),

View File

@ -133,7 +133,7 @@ public:
( (
IOobject IOobject
( (
vf.name(), "localMin::interpolate(" + vf.name() + ')',
mesh.time().timeName(), mesh.time().timeName(),
mesh mesh
), ),

View File

@ -144,7 +144,7 @@ public:
( (
IOobject IOobject
( (
vf.name(), "skewCorrected::skewCorrection(" + vf.name() + ')',
mesh.time().timeName(), mesh.time().timeName(),
mesh mesh
), ),

View File

@ -79,7 +79,6 @@ Foam::genericFvPatchField<Type>::genericFvPatchField
<< " (Actual type " << actualTypeName_ << ")" << nl << " (Actual type " << actualTypeName_ << ")" << nl
<< "\n Please add the 'value' entry to the write function " << "\n Please add the 'value' entry to the write function "
"of the user-defined boundary-condition\n" "of the user-defined boundary-condition\n"
" or link the boundary-condition into libfoamUtil.so"
<< exit(FatalIOError); << exit(FatalIOError);
} }

View File

@ -428,7 +428,7 @@ Foam::meshSearch::meshSearch(const polyMesh& mesh, const bool faceDecomp)
: :
mesh_(mesh), mesh_(mesh),
faceDecomp_(faceDecomp), faceDecomp_(faceDecomp),
cloud_(mesh_, IDLList<passiveParticle>()), cloud_(mesh_, "meshSearchCloud", IDLList<passiveParticle>()),
boundaryTreePtr_(NULL), boundaryTreePtr_(NULL),
cellTreePtr_(NULL), cellTreePtr_(NULL),
cellCentreTreePtr_(NULL) cellCentreTreePtr_(NULL)

View File

@ -38,8 +38,7 @@ SourceFiles
#define meshSearch_H #define meshSearch_H
#include "pointIndexHit.H" #include "pointIndexHit.H"
#include "Cloud.H" #include "passiveParticleCloud.H"
#include "passiveParticle.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -68,7 +67,7 @@ class meshSearch
const bool faceDecomp_; const bool faceDecomp_;
//- Dummy cloud to put particles on for tracking. //- Dummy cloud to put particles on for tracking.
Cloud<passiveParticle> cloud_; passiveParticleCloud cloud_;
//- demand driven octrees //- demand driven octrees

View File

@ -2560,7 +2560,7 @@ Foam::triSurface Foam::triSurfaceTools::delaunay2D(const List<vector2D>& pts)
// Triangulate // Triangulate
int nTris = 0; int nTris = 0;
dtris2 int err = dtris2
( (
pts.size(), pts.size(),
geompackVertices.begin(), geompackVertices.begin(),
@ -2569,6 +2569,13 @@ Foam::triSurface Foam::triSurfaceTools::delaunay2D(const List<vector2D>& pts)
triangle_neighbor.begin() triangle_neighbor.begin()
); );
if (err != 0)
{
FatalErrorIn("triSurfaceTools::delaunay2D(const List<vector2D>&)")
<< "Failed dtris2 with vertices:" << pts.size()
<< abort(FatalError);
}
// Trim // Trim
triangle_node.setSize(3*nTris); triangle_node.setSize(3*nTris);
triangle_neighbor.setSize(3*nTris); triangle_neighbor.setSize(3*nTris);

View File

@ -6,4 +6,16 @@ fieldAverage/fieldAverageFunctionObject/fieldAverageFunctionObject.C
fieldMinMax/fieldMinMax.C fieldMinMax/fieldMinMax.C
fieldMinMax/fieldMinMaxFunctionObject.C fieldMinMax/fieldMinMaxFunctionObject.C
fieldValues/fieldValue/fieldValue.C
fieldValues/face/faceSource.C
fieldValues/face/faceSourceFunctionObject.C
fieldValues/cell/cellSource.C
fieldValues/cell/cellSourceFunctionObject.C
streamLine/streamLine.C
streamLine/streamLineParticle.C
streamLine/streamLineParticleCloud.C
streamLine/streamLineFunctionObject.C
LIB = $(FOAM_LIBBIN)/libfieldFunctionObjects LIB = $(FOAM_LIBBIN)/libfieldFunctionObjects

View File

@ -1,9 +1,11 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude -I$(LIB_SRC)/sampling/lnInclude
LIB_LIBS = \ LIB_LIBS = \
-lfiniteVolume \ -lfiniteVolume \
-lmeshTools \ -lmeshTools \
-llagrangian \
-lsampling -lsampling

View File

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-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
Typedef
Foam::IOcellSource
Description
Instance of the generic IOOutputFilter for cellSource.
\*---------------------------------------------------------------------------*/
#ifndef IOcellSource_H
#define IOcellSource_H
#include "cellSource.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<cellSource> IOcellSource;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,257 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "cellSource.H"
#include "fvMesh.H"
#include "volFields.H"
#include "IOList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace fieldValues
{
defineTypeNameAndDebug(cellSource, 0);
}
template<>
const char* NamedEnum<fieldValues::cellSource::sourceType, 1>::
names[] = {"cellZone"};
const NamedEnum<fieldValues::cellSource::sourceType, 1>
fieldValues::cellSource::sourceTypeNames_;
template<>
const char* NamedEnum<fieldValues::cellSource::operationType, 4>::
names[] = {"none", "sum", "volAverage", "volIntegrate"};
const NamedEnum<fieldValues::cellSource::operationType, 4>
fieldValues::cellSource::operationTypeNames_;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::fieldValues::cellSource::setCellZoneCells()
{
label zoneId = mesh().cellZones().findZoneID(sourceName_);
if (zoneId < 0)
{
FatalErrorIn("cellSource::cellSource::setCellZoneCells()")
<< "Unknown cell zone name: " << sourceName_
<< ". Valid cell zones are: " << mesh().cellZones().names()
<< nl << exit(FatalError);
}
const cellZone& cZone = mesh().cellZones()[zoneId];
cellId_.setSize(cZone.size());
label count = 0;
forAll(cZone, i)
{
label cellI = cZone[i];
cellId_[count] = cellI;
count++;
}
cellId_.setSize(count);
if (debug)
{
Info<< "Original cell zone size = " << cZone.size()
<< ", new size = " << count << endl;
}
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::fieldValues::cellSource::initialise()
{
switch (source_)
{
case stCellZone:
{
setCellZoneCells();
break;
}
default:
{
FatalErrorIn("cellSource::constructCellAddressing()")
<< "Unknown source type. Valid source types are:"
<< sourceTypeNames_ << nl << exit(FatalError);
}
}
Info<< type() << " " << name_ << ":" << nl
<< " total cells = " << cellId_.size() << nl
<< " total volume = " << sum(filterField(mesh().V()))
<< nl << endl;
}
void Foam::fieldValues::cellSource::makeFile()
{
// Create the forces file if not already created
if (outputFilePtr_.empty())
{
if (debug)
{
Info<< "Creating output file." << endl;
}
// File update
if (Pstream::master())
{
fileName outputDir;
if (Pstream::parRun())
{
// Put in undecomposed case (Note: gives problems for
// distributed data running)
outputDir =
obr_.time().path()/".."/name_/obr_.time().timeName();
}
else
{
outputDir = obr_.time().path()/name_/obr_.time().timeName();
}
// Create directory if does not exist
mkDir(outputDir);
// Open new file at start up
outputFilePtr_.reset(new OFstream(outputDir/(type() + ".dat")));
// Add headers to output data
writeFileHeader();
}
}
}
void Foam::fieldValues::cellSource::writeFileHeader()
{
if (outputFilePtr_.valid())
{
outputFilePtr_()
<< "# Source : " << sourceTypeNames_[source_] << " "
<< sourceName_ << nl << "# Cells : " << cellId_.size() << nl
<< "# Time" << tab << "sum(V)";
forAll(fields_, i)
{
outputFilePtr_()
<< tab << operationTypeNames_[operation_]
<< "(" << fields_[i] << ")";
}
outputFilePtr_() << endl;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fieldValues::cellSource::cellSource
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
fieldValue(name, obr, dict, loadFromFiles),
source_(sourceTypeNames_.read(dict.lookup("source"))),
operation_(operationTypeNames_.read(dict.lookup("operation"))),
cellId_(),
outputFilePtr_(NULL)
{
initialise();
if (active_)
{
// Create the output file if not already created
makeFile();
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fieldValues::cellSource::~cellSource()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::fieldValues::cellSource::read(const dictionary& dict)
{
if (active_)
{
fieldValue::read(dict);
initialise();
}
}
void Foam::fieldValues::cellSource::write()
{
if (active_)
{
if (log_)
{
Info<< type() << " " << name_ << " output:" << nl;
}
outputFilePtr_()
<< obr_.time().value() << tab
<< sum(filterField(mesh().V()));
forAll(fields_, i)
{
writeValues<scalar>(fields_[i]);
writeValues<vector>(fields_[i]);
writeValues<sphericalTensor>(fields_[i]);
writeValues<symmTensor>(fields_[i]);
writeValues<tensor>(fields_[i]);
}
outputFilePtr_()<< endl;
if (log_)
{
Info<< endl;
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,227 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::fieldValues::cellSource
Description
Cell source variant of field value function object. Values of user-
specified fields reported for collections of cells.
cellObj1 // Name also used to identify output folder
{
type cellSource;
functionObjectLibs ("libfieldValueFunctionObjects.so");
enabled true;
outputControl outputTime;
log true; // log to screen?
valueOutput true; // Write values at run-time output times?
source cellZone; // Type of cell source
sourceName c0;
operation volAverage; // none, sum, volAverage, volIntegrate
fields
(
p
U
);
}
SourceFiles
cellSource.C
\*---------------------------------------------------------------------------*/
#ifndef cellSource_H
#define cellSource_H
#include "NamedEnum.H"
#include "fieldValue.H"
#include "labelList.H"
#include "OFstream.H"
#include "volFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fieldValues
{
/*---------------------------------------------------------------------------*\
Class cellSource Declaration
\*---------------------------------------------------------------------------*/
class cellSource
:
public fieldValue
{
public:
// Public data types
//- Source type enumeration
enum sourceType
{
stCellZone
};
//- Source type names
static const NamedEnum<sourceType, 1> sourceTypeNames_;
//- Operation type enumeration
enum operationType
{
opNone,
opSum,
opVolAverage,
opVolIntegrate
};
//- Operation type names
static const NamedEnum<operationType, 4> operationTypeNames_;
private:
// Private member functions
//- Set cells to evaluate based on a cell zone
void setCellZoneCells();
//- Set cells to evaluate based on a patch
void setPatchCells();
//- Create the output file if not already created
void makeFile();
protected:
// Protected data
//- Source type
sourceType source_;
//- Operation to apply to values
operationType operation_;
//- Local list of cell IDs
labelList cellId_;
//- Output file pointer
autoPtr<OFstream> outputFilePtr_;
// Protected member functions
//- Initialise, e.g. cell addressing
void initialise();
//- Insert field values into values list
template<class Type>
bool setFieldValues
(
const word& fieldName,
List<Type>& values
) const;
//- Apply the 'operation' to the values
template<class Type>
Type processValues(const List<Type>& values) const;
//- Output file header information
virtual void writeFileHeader();
public:
//- Run-time type information
TypeName("cellSource");
//- Construct from components
cellSource
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles = false
);
//- Destructor
virtual ~cellSource();
// Public member functions
// Access
//- Return the source type
inline const sourceType& source() const;
//- Return the local list of cell IDs
inline const labelList& cellId() const;
// Function object functions
//- Read from dictionary
virtual void read(const dictionary&);
//- Calculate and write
virtual void write();
//- Templated helper function to output field values
template<class Type>
bool writeValues(const word& fieldName);
//- Filter a field according to cellIds
template<class Type>
tmp<Field<Type> > filterField(const Field<Type>& field) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fieldValues
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "cellSourceI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "cellSourceTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,47 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "cellSourceFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug
(
cellSourceFunctionObject,
0
);
addToRunTimeSelectionTable
(
functionObject,
cellSourceFunctionObject,
dictionary
);
}
// ************************************************************************* //

View File

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-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
Typedef
Foam::cellSourceFunctionObject
Description
FunctionObject wrapper around cellSource to allow it to be
created via the functions list within controlDict.
SourceFiles
cellSourceFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef cellSourceFunctionObject_H
#define cellSourceFunctionObject_H
#include "cellSource.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef OutputFilterFunctionObject<fieldValues::cellSource>
cellSourceFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "cellSource.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::fieldValues::cellSource::sourceType&
Foam::fieldValues::cellSource::source() const
{
return source_;
}
inline const Foam::labelList&
Foam::fieldValues::cellSource::cellId() const
{
return cellId_;
}
// ************************************************************************* //

View File

@ -0,0 +1,162 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "cellSource.H"
#include "volFields.H"
#include "IOList.H"
#include "ListListOps.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type>
bool Foam::fieldValues::cellSource::setFieldValues
(
const word& fieldName,
List<Type>& values
) const
{
values.setSize(cellId_.size(), pTraits<Type>::zero);
typedef GeometricField<Type, fvPatchField, volMesh> vf;
if (obr_.foundObject<vf>(fieldName))
{
const vf& field = obr_.lookupObject<vf>(fieldName);
values = UIndirectList<Type>(field, cellId_);
return true;
}
return false;
}
template<class Type>
Type Foam::fieldValues::cellSource::processValues
(
const List<Type>& values
) const
{
Type result = pTraits<Type>::zero;
switch (operation_)
{
case opSum:
{
result = sum(values);
break;
}
case opVolAverage:
{
tmp<scalarField> V = filterField(mesh().V());
result = sum(values*V())/sum(V());
break;
}
case opVolIntegrate:
{
result = sum(values*filterField(mesh().V()));
break;
}
default:
{
// Do nothing
}
}
return result;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::fieldValues::cellSource::writeValues(const word& fieldName)
{
List<List<Type> > allValues(Pstream::nProcs());
bool validField =
setFieldValues<Type>(fieldName, allValues[Pstream::myProcNo()]);
if (validField)
{
Pstream::gatherList(allValues);
if (Pstream::master())
{
List<Type> values =
ListListOps::combine<List<Type> >
(
allValues,
accessOp<List<Type> >()
);
Type result = processValues(values);
if (valueOutput_)
{
IOList<Type>
(
IOobject
(
fieldName + "_" + sourceTypeNames_[source_] + "-"
+ sourceName_,
obr_.time().timeName(),
obr_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
values
).write();
}
outputFilePtr_()<< tab << result;
if (log_)
{
Info<< " " << operationTypeNames_[operation_]
<< "(" << sourceName_ << ") for " << fieldName
<< " = " << result << endl;
}
}
}
return validField;
}
template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::fieldValues::cellSource::filterField
(
const Field<Type>& field
) const
{
return tmp<Field<Type> >(new Field<Type>(field, cellId_));
}
// ************************************************************************* //

View File

@ -0,0 +1,108 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: 1.6 |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application icoFoam;
startFrom startTime;
startTime 0;
stopAt endTime;
endTime 0.5;
deltaT 0.005;
writeControl timeStep;
writeInterval 20;
purgeWrite 0;
writeFormat ascii;
writePrecision 6;
writeCompression uncompressed;
timeFormat general;
timePrecision 6;
runTimeModifiable yes;
functions
(
faceObj1
{
type faceSource;
functionObjectLibs ("libfieldFunctionObjects.so");
enabled true;
outputControl outputTime;
log true;
valueOutput true;
source patch;
sourceName movingWall;
// source faceZone;
// sourceName f0;
operation areaAverage;
fields
(
p
phi
U
);
}
faceObj2
{
type faceSource;
functionObjectLibs ("libfieldFunctionObjects.so");
enabled true;
outputControl outputTime;
log true;
valueOutput true;
source faceZone;
sourceName f0;
operation sum;
fields
(
phi
);
}
cellObj1
{
type cellSource;
functionObjectLibs ("libfieldFunctionObjects.so");
enabled true;
outputControl outputTime;
log true;
valueOutput true;
source cellZone;
sourceName c0;
operation volAverage;
fields
(
p
U
);
}
);
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-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
Typedef
Foam::IOfaceSource
Description
Instance of the generic IOOutputFilter for faceSource.
\*---------------------------------------------------------------------------*/
#ifndef IOfaceSource_H
#define IOfaceSource_H
#include "faceSource.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<faceSource> IOfaceSource;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,368 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "faceSource.H"
#include "fvMesh.H"
#include "cyclicPolyPatch.H"
#include "emptyPolyPatch.H"
#include "processorPolyPatch.H"
#include "surfaceFields.H"
#include "volFields.H"
#include "IOList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace fieldValues
{
defineTypeNameAndDebug(faceSource, 0);
}
template<>
const char* NamedEnum<fieldValues::faceSource::sourceType, 2>::
names[] = {"faceZone", "patch"};
const NamedEnum<fieldValues::faceSource::sourceType, 2>
fieldValues::faceSource::sourceTypeNames_;
template<>
const char* NamedEnum<fieldValues::faceSource::operationType, 4>::
names[] = {"none", "sum", "areaAverage", "areaIntegrate"};
const NamedEnum<fieldValues::faceSource::operationType, 4>
fieldValues::faceSource::operationTypeNames_;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::fieldValues::faceSource::setFaceZoneFaces()
{
label zoneId = mesh().faceZones().findZoneID(sourceName_);
if (zoneId < 0)
{
FatalErrorIn("faceSource::faceSource::setFaceZoneFaces()")
<< "Unknown face zone name: " << sourceName_
<< ". Valid face zones are: " << mesh().faceZones().names()
<< nl << exit(FatalError);
}
const faceZone& fZone = mesh().faceZones()[zoneId];
faceId_.setSize(fZone.size());
facePatchId_.setSize(fZone.size());
flipMap_.setSize(fZone.size());
label count = 0;
forAll(fZone, i)
{
label faceI = fZone[i];
label faceId = -1;
label facePatchId = -1;
if (mesh().isInternalFace(faceI))
{
faceId = faceI;
facePatchId = -1;
}
else
{
facePatchId = mesh().boundaryMesh().whichPatch(faceI);
const polyPatch& pp = mesh().boundaryMesh()[facePatchId];
if (isA<processorPolyPatch>(pp))
{
if (refCast<const processorPolyPatch>(pp).owner())
{
faceId = pp.whichFace(faceI);
}
else
{
faceId = -1;
}
}
else if (isA<cyclicPolyPatch>(pp))
{
label patchFaceI = faceI - pp.start();
if (patchFaceI < pp.size()/2)
{
faceId = patchFaceI;
}
else
{
faceId = -1;
}
}
else if (!isA<emptyPolyPatch>(pp))
{
faceId = faceI - pp.start();
}
else
{
faceId = -1;
facePatchId = -1;
}
}
if (faceId >= 0)
{
if (fZone.flipMap()[i])
{
flipMap_[count] = -1;
}
else
{
flipMap_[count] = 1;
}
faceId_[count] = faceId;
facePatchId_[count] = facePatchId;
count++;
}
}
faceId_.setSize(count);
facePatchId_.setSize(count);
flipMap_.setSize(count);
if (debug)
{
Info<< "Original face zone size = " << fZone.size()
<< ", new size = " << count << endl;
}
}
void Foam::fieldValues::faceSource::setPatchFaces()
{
label patchId = mesh().boundaryMesh().findPatchID(sourceName_);
if (patchId < 0)
{
FatalErrorIn("faceSource::constructFaceAddressing()")
<< "Unknown patch name: " << sourceName_
<< ". Valid patch names are: "
<< mesh().boundaryMesh().names() << nl
<< exit(FatalError);
}
const polyPatch& pp = mesh().boundaryMesh()[patchId];
label nFaces = pp.size();
if (isA<cyclicPolyPatch>(pp))
{
nFaces /= 2;
}
else if (isA<emptyPolyPatch>(pp))
{
nFaces = 0;
}
faceId_.setSize(nFaces);
facePatchId_.setSize(nFaces);
flipMap_.setSize(nFaces);
forAll(faceId_, faceI)
{
faceId_[faceI] = faceI;
facePatchId_[faceI] = patchId;
flipMap_[faceI] = 1;
}
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::fieldValues::faceSource::initialise()
{
switch (source_)
{
case stFaceZone:
{
setFaceZoneFaces();
break;
}
case stPatch:
{
setPatchFaces();
break;
}
default:
{
FatalErrorIn("faceSource::constructFaceAddressing()")
<< "Unknown source type. Valid source types are:"
<< sourceTypeNames_ << nl << exit(FatalError);
}
}
Info<< type() << " " << name_ << ":" << nl
<< " total faces = " << faceId_.size() << nl
<< " total area = " << sum(filterField(mesh().magSf()))
<< nl << endl;
}
void Foam::fieldValues::faceSource::makeFile()
{
// Create the forces file if not already created
if (outputFilePtr_.empty())
{
if (debug)
{
Info<< "Creating output file." << endl;
}
// File update
if (Pstream::master())
{
fileName outputDir;
if (Pstream::parRun())
{
// Put in undecomposed case (Note: gives problems for
// distributed data running)
outputDir =
obr_.time().path()/".."/name_/obr_.time().timeName();
}
else
{
outputDir = obr_.time().path()/name_/obr_.time().timeName();
}
// Create directory if does not exist
mkDir(outputDir);
// Open new file at start up
outputFilePtr_.reset(new OFstream(outputDir/(type() + ".dat")));
// Add headers to output data
writeFileHeader();
}
}
}
void Foam::fieldValues::faceSource::writeFileHeader()
{
if (outputFilePtr_.valid())
{
outputFilePtr_()
<< "# Source : " << sourceTypeNames_[source_] << " "
<< sourceName_ << nl << "# Faces : " << faceId_.size() << nl
<< "# Time" << tab << "sum(magSf)";
forAll(fields_, i)
{
outputFilePtr_()
<< tab << operationTypeNames_[operation_]
<< "(" << fields_[i] << ")";
}
outputFilePtr_() << endl;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fieldValues::faceSource::faceSource
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
fieldValue(name, obr, dict, loadFromFiles),
source_(sourceTypeNames_.read(dict.lookup("source"))),
operation_(operationTypeNames_.read(dict.lookup("operation"))),
faceId_(),
facePatchId_(),
flipMap_(),
outputFilePtr_(NULL)
{
initialise();
if (active_)
{
// Create the output file if not already created
makeFile();
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fieldValues::faceSource::~faceSource()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::fieldValues::faceSource::read(const dictionary& dict)
{
if (active_)
{
fieldValue::read(dict);
initialise();
}
}
void Foam::fieldValues::faceSource::write()
{
if (active_)
{
if (log_)
{
Info<< type() << " " << name_ << " output:" << nl;
}
outputFilePtr_()
<< obr_.time().value() << tab
<< sum(filterField(mesh().magSf()));
forAll(fields_, i)
{
writeValues<scalar>(fields_[i]);
writeValues<vector>(fields_[i]);
writeValues<sphericalTensor>(fields_[i]);
writeValues<symmTensor>(fields_[i]);
writeValues<tensor>(fields_[i]);
}
outputFilePtr_()<< endl;
if (log_)
{
Info<< endl;
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,252 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::fieldValues::faceSource
Description
Face source variant of field value function object. Values of user-
specified fields reported for collections of faces.
cellObj1 // Name also used to identify output folder
{
type cellSource;
functionObjectLibs ("libfieldValueFunctionObjects.so");
enabled true;
outputControl outputTime;
log true; // log to screen?
valueOutput true; // Write values at run-time output times?
source faceZone; // Type of face source: faceZone, patch
sourceName f0;
operation sum; // none, sum, areaAverage, areaIntegrate
fields
(
p
phi
U
);
}
SourceFiles
faceSource.C
\*---------------------------------------------------------------------------*/
#ifndef faceSource_H
#define faceSource_H
#include "NamedEnum.H"
#include "fieldValue.H"
#include "labelList.H"
#include "OFstream.H"
#include "surfaceFieldsFwd.H"
#include "volFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fieldValues
{
/*---------------------------------------------------------------------------*\
Class faceSource Declaration
\*---------------------------------------------------------------------------*/
class faceSource
:
public fieldValue
{
public:
// Public data types
//- Source type enumeration
enum sourceType
{
stFaceZone,
stPatch
};
//- Source type names
static const NamedEnum<sourceType, 2> sourceTypeNames_;
//- Operation type enumeration
enum operationType
{
opNone,
opSum,
opAreaAverage,
opAreaIntegrate
};
//- Operation type names
static const NamedEnum<operationType, 4> operationTypeNames_;
private:
// Private member functions
//- Set faces to evaluate based on a face zone
void setFaceZoneFaces();
//- Set faces to evaluate based on a patch
void setPatchFaces();
//- Create the output file if not already created
void makeFile();
protected:
// Protected data
//- Source type
sourceType source_;
//- Operation to apply to values
operationType operation_;
//- Local list of face IDs
labelList faceId_;
//- Local list of patch ID per face
labelList facePatchId_;
//- List of +1/-1 representing face flip map
labelList flipMap_;
//- Output file pointer
autoPtr<OFstream> outputFilePtr_;
// Protected member functions
//- Initialise, e.g. face addressing
void initialise();
//- Insert field values into values list
template<class Type>
bool setFieldValues
(
const word& fieldName,
List<Type>& values
) const;
//- Apply the 'operation' to the values
template<class Type>
Type processValues(const List<Type>& values) const;
//- Output file header information
virtual void writeFileHeader();
public:
//- Run-time type information
TypeName("faceSource");
//- Construct from components
faceSource
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles = false
);
//- Destructor
virtual ~faceSource();
// Public member functions
// Access
//- Return the source type
inline const sourceType& source() const;
//- Return the local list of face IDs
inline const labelList& faceId() const;
//- Return the local list of patch ID per face
inline const labelList& facePatch() const;
//- Return the list of +1/-1 representing face flip map
inline const labelList& flipMap() const;
// Function object functions
//- Read from dictionary
virtual void read(const dictionary&);
//- Calculate and write
virtual void write();
//- Templated helper function to output field values
template<class Type>
bool writeValues(const word& fieldName);
//- Filter a surface field according to faceIds
template<class Type>
tmp<Field<Type> > filterField
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& field
) const;
//- Filter a volume field according to faceIds
template<class Type>
tmp<Field<Type> > filterField
(
const GeometricField<Type, fvPatchField, volMesh>& field
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fieldValues
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "faceSourceI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "faceSourceTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,47 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "faceSourceFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug
(
faceSourceFunctionObject,
0
);
addToRunTimeSelectionTable
(
functionObject,
faceSourceFunctionObject,
dictionary
);
}
// ************************************************************************* //

View File

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-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
Typedef
Foam::faceSourceFunctionObject
Description
FunctionObject wrapper around faceSource to allow it to be
created via the functions list within controlDict.
SourceFiles
faceSourceFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef faceSourceFunctionObject_H
#define faceSourceFunctionObject_H
#include "faceSource.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef OutputFilterFunctionObject<fieldValues::faceSource>
faceSourceFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "faceSource.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::fieldValues::faceSource::sourceType&
Foam::fieldValues::faceSource::source() const
{
return source_;
}
inline const Foam::labelList&
Foam::fieldValues::faceSource::faceId() const
{
return faceId_;
}
inline const Foam::labelList&
Foam::fieldValues::faceSource::facePatch() const
{
return facePatchId_;
}
inline const Foam::labelList&
Foam::fieldValues::faceSource::flipMap() const
{
return flipMap_;
}
// ************************************************************************* //

View File

@ -0,0 +1,269 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "faceSource.H"
#include "surfaceFields.H"
#include "volFields.H"
#include "IOList.H"
#include "ListListOps.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type>
bool Foam::fieldValues::faceSource::setFieldValues
(
const word& fieldName,
List<Type>& values
) const
{
values.setSize(faceId_.size(), pTraits<Type>::zero);
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
typedef GeometricField<Type, fvPatchField, volMesh> vf;
if (obr_.foundObject<sf>(fieldName))
{
const sf& field = obr_.lookupObject<sf>(fieldName);
forAll(values, i)
{
label faceI = faceId_[i];
label patchI = facePatchId_[i];
if (patchI >= 0)
{
values[i] = field.boundaryField()[patchI][faceI];
}
else
{
values[i] = field[faceI];
}
values[i] *= flipMap_[i];
}
return true;
}
else if (obr_.foundObject<vf>(fieldName))
{
const vf& field = obr_.lookupObject<vf>(fieldName);
forAll(values, i)
{
label faceI = faceId_[i];
label patchI = facePatchId_[i];
if (patchI >= 0)
{
values[i] = field.boundaryField()[patchI][faceI];
}
else
{
FatalErrorIn
(
"fieldValues::faceSource::setFieldValues"
"("
"const word&, "
"List<Type>&"
") const"
) << type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):"
<< nl
<< " Unable to process internal faces for volume field "
<< fieldName << nl << abort(FatalError);
}
values[i] *= flipMap_[i];
}
return true;
}
return false;
}
template<class Type>
Type Foam::fieldValues::faceSource::processValues
(
const List<Type>& values
) const
{
Type result = pTraits<Type>::zero;
switch (operation_)
{
case opSum:
{
result = sum(values);
break;
}
case opAreaAverage:
{
tmp<scalarField> magSf = filterField(mesh().magSf());
result = sum(values*magSf())/sum(magSf());
break;
}
case opAreaIntegrate:
{
result = sum(values*filterField(mesh().magSf()));
break;
}
default:
{
// Do nothing
}
}
return result;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::fieldValues::faceSource::writeValues(const word& fieldName)
{
List<List<Type> > allValues(Pstream::nProcs());
bool validField =
setFieldValues<Type>(fieldName, allValues[Pstream::myProcNo()]);
if (validField)
{
Pstream::gatherList(allValues);
if (Pstream::master())
{
List<Type> values =
ListListOps::combine<List<Type> >
(
allValues,
accessOp<List<Type> >()
);
Type result = processValues(values);
if (valueOutput_)
{
IOList<Type>
(
IOobject
(
fieldName + "_" + sourceTypeNames_[source_] + "-"
+ sourceName_,
obr_.time().timeName(),
obr_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
values
).write();
}
outputFilePtr_()<< tab << result;
if (log_)
{
Info<< " " << operationTypeNames_[operation_]
<< "(" << sourceName_ << ") for " << fieldName
<< " = " << result << endl;
}
}
}
return validField;
}
template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::filterField
(
const GeometricField<Type, fvPatchField, volMesh>& field
) const
{
tmp<Field<Type> > tvalues(new Field<Type>(faceId_.size()));
Field<Type>& values = tvalues();
forAll(values, i)
{
label faceI = faceId_[i];
label patchI = facePatchId_[i];
if (patchI >= 0)
{
values[i] = field.boundaryField()[patchI][faceI];
}
else
{
FatalErrorIn
(
"fieldValues::faceSource::filterField"
"("
"const GeometricField<Type, fvPatchField, volMesh>&"
") const"
) << type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):"
<< nl
<< " Unable to process internal faces for volume field "
<< field.name() << nl << abort(FatalError);
}
values[i] *= flipMap_[i];
}
return tvalues;
}
template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::filterField
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& field
) const
{
tmp<Field<Type> > tvalues(new Field<Type>(faceId_.size()));
Field<Type>& values = tvalues();
forAll(values, i)
{
label faceI = faceId_[i];
label patchI = facePatchId_[i];
if (patchI >= 0)
{
values[i] = field.boundaryField()[patchI][faceI];
}
else
{
values[i] = field[faceI];
}
values[i] *= flipMap_[i];
}
return tvalues;
}
// ************************************************************************* //

View File

@ -0,0 +1,177 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "fieldValue.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(fieldValue, 0);
defineTemplateTypeNameAndDebug(IOList<vector>, 0);
defineTemplateTypeNameAndDebug(IOList<sphericalTensor>, 0);
defineTemplateTypeNameAndDebug(IOList<symmTensor>, 0);
defineTemplateTypeNameAndDebug(IOList<tensor>, 0);
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::fieldValue::updateMesh(const mapPolyMesh&)
{
// Do nothing
}
void Foam::fieldValue::movePoints(const Field<point>&)
{
// Do nothing
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fieldValue::fieldValue
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
name_(name),
obr_(obr),
active_(true),
log_(false),
sourceName_(dict.lookup("sourceName")),
fields_(dict.lookup("fields")),
valueOutput_(dict.lookup("valueOutput"))
{
// Only active if obr is an fvMesh
if (isA<fvMesh>(obr_))
{
read(dict);
}
else
{
WarningIn
(
"fieldValue::fieldValue"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"const bool"
")"
) << "No fvMesh available, deactivating."
<< nl << endl;
active_ = false;
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fieldValue::~fieldValue()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::word& Foam::fieldValue::name() const
{
return name_;
}
const Foam::objectRegistry& Foam::fieldValue::obr() const
{
return obr_;
}
bool Foam::fieldValue::active() const
{
return active_;
}
const Foam::Switch& Foam::fieldValue::log() const
{
return log_;
}
const Foam::word& Foam::fieldValue::sourceName() const
{
return sourceName_;
}
const Foam::wordList& Foam::fieldValue::fields() const
{
return fields_;
}
const Foam::Switch& Foam::fieldValue::valueOutput() const
{
return valueOutput_;
}
const Foam::fvMesh& Foam::fieldValue::mesh() const
{
return refCast<const fvMesh>(obr_);
}
void Foam::fieldValue::read(const dictionary& dict)
{
if (active_)
{
log_ = dict.lookupOrDefault<Switch>("log", false);
dict.lookup("fields") >> fields_;
dict.lookup("valueOutput") >> valueOutput_;
}
}
void Foam::fieldValue::execute()
{
// Do nothing
}
void Foam::fieldValue::end()
{
// Do nothing
}
// ************************************************************************* //

View File

@ -0,0 +1,165 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::fieldValue
Description
Base class for field value -based function objects.
SourceFiles
fieldValue.C
\*---------------------------------------------------------------------------*/
#ifndef fieldValue_H
#define fieldValue_H
#include "Switch.H"
#include "pointFieldFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class dictionary;
class objectRegistry;
class fvMesh;
class mapPolyMesh;
/*---------------------------------------------------------------------------*\
Class fieldValue Declaration
\*---------------------------------------------------------------------------*/
class fieldValue
{
protected:
// Protected data
//- Name of this fieldValue object
word name_;
//- Database this class is registered to
const objectRegistry& obr_;
//- Active flag
bool active_;
//- Switch to send output to Info as well as to file
Switch log_;
//- Name of source object
word sourceName_;
//- List of field names to operate on
wordList fields_;
//- Output field values flag
Switch valueOutput_;
// Functions to be over-ridden from IOoutputFilter class
//- Update mesh
virtual void updateMesh(const mapPolyMesh&);
//- Move points
virtual void movePoints(const Field<point>&);
public:
//- Run-time type information
TypeName("fieldValue");
//- Construct from components
fieldValue
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles = false
);
//- Destructor
virtual ~fieldValue();
// Public member functions
// Access
//- Return the name of the geometric source
const word& name() const;
//- Return the reference to the object registry
const objectRegistry& obr() const;
//- Return the active flag
bool active() const;
//- Return the switch to send output to Info as well as to file
const Switch& log() const;
//- Return the source name
const word& sourceName() const;
//- Return the list of field names
const wordList& fields() const;
//- Return the output field values flag
const Switch& valueOutput() const;
//- Helper funvction to return the reference to the mesh
const fvMesh& mesh() const;
// Function object functions
//- Read from dictionary
virtual void read(const dictionary& dict);
//- Execute
virtual void execute();
//- Execute the at the final time-loop, currently does nothing
virtual void end();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,622 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "Pstream.H"
#include "functionObjectList.H"
#include "streamLine.H"
#include "fvMesh.H"
#include "streamLineParticleCloud.H"
#include "ReadFields.H"
#include "meshSearch.H"
#include "sampledSet.H"
#include "globalIndex.H"
#include "mapDistribute.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::streamLine, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::streamLine::track()
{
const Time& runTime = const_cast<Time&>(obr_.time());
const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
IDLList<streamLineParticle> initialParticles;
streamLineParticleCloud particles
(
mesh,
cloudName_,
initialParticles
);
//Pout<< "Seeding particles." << endl;
const sampledSet& seedPoints = sampledSetPtr_();
forAll(seedPoints, i)
{
//Pout<< "Seeded particle at " << seedPoints[i]
// << " at cell:" << seedPoints.cells()[i]
// << endl;
particles.addParticle
(
new streamLineParticle
(
particles,
seedPoints[i],
seedPoints.cells()[i],
lifeTime_ // lifetime
)
);
}
label nSeeds = returnReduce(particles.size(), sumOp<label>());
Info<< "Seeded " << nSeeds
<< " particles." << endl;
// Read or lookup fields
PtrList<volScalarField> vsFlds;
PtrList<interpolationCellPoint<scalar> > vsInterp;
PtrList<volVectorField> vvFlds;
PtrList<interpolationCellPoint<vector> > vvInterp;
label UIndex = -1;
if (loadFromFiles_)
{
IOobjectList allObjects(mesh, runTime.timeName());
IOobjectList objects(2*fields_.size());
forAll(fields_, i)
{
objects.add(*allObjects[fields_[i]]);
}
ReadFields(mesh, objects, vsFlds);
vsInterp.setSize(vsFlds.size());
forAll(vsFlds, i)
{
vsInterp.set(i, new interpolationCellPoint<scalar>(vsFlds[i]));
}
ReadFields(mesh, objects, vvFlds);
vvInterp.setSize(vvFlds.size());
forAll(vvFlds, i)
{
vvInterp.set(i, new interpolationCellPoint<vector>(vvFlds[i]));
}
}
else
{
label nScalar = 0;
label nVector = 0;
forAll(fields_, i)
{
if (mesh.foundObject<volScalarField>(fields_[i]))
{
nScalar++;
}
else if (mesh.foundObject<volVectorField>(fields_[i]))
{
nVector++;
}
else
{
FatalErrorIn("streamLine::execute()")
<< "Cannot find field " << fields_[i] << endl
<< "Valid scalar fields are:"
<< mesh.names(volScalarField::typeName) << endl
<< "Valid vector fields are:"
<< mesh.names(volVectorField::typeName)
<< exit(FatalError);
}
}
vsInterp.setSize(nScalar);
nScalar = 0;
vvInterp.setSize(nVector);
nVector = 0;
forAll(fields_, i)
{
if (mesh.foundObject<volScalarField>(fields_[i]))
{
const volScalarField& f = mesh.lookupObject<volScalarField>
(
fields_[i]
);
vsInterp.set
(
nScalar++,
new interpolationCellPoint<scalar>(f)
);
}
else if (mesh.foundObject<volVectorField>(fields_[i]))
{
const volVectorField& f = mesh.lookupObject<volVectorField>
(
fields_[i]
);
if (f.name() == UName_)
{
UIndex = nVector;
}
vvInterp.set
(
nVector++,
new interpolationCellPoint<vector>(f)
);
}
}
}
// Store the names
scalarNames_.setSize(vsInterp.size());
forAll(vsInterp, i)
{
scalarNames_[i] = vsInterp[i].psi().name();
}
vectorNames_.setSize(vvInterp.size());
forAll(vvInterp, i)
{
vectorNames_[i] = vvInterp[i].psi().name();
}
// Check that we know the index of U in the interpolators.
if (UIndex == -1)
{
FatalErrorIn("streamLine::execute()")
<< "Cannot find field to move particles with : " << UName_
<< endl
<< "This field has to be present in the sampled fields "
<< fields_
<< " and in the objectRegistry." << endl
<< exit(FatalError);
}
// Sampled data
// ~~~~~~~~~~~~
// Size to maximum expected sizes.
allTracks_.clear();
allTracks_.setCapacity(nSeeds);
allScalars_.setSize(vsInterp.size());
forAll(allScalars_, i)
{
allScalars_[i].clear();
allScalars_[i].setCapacity(nSeeds);
}
allVectors_.setSize(vvInterp.size());
forAll(allVectors_, i)
{
allVectors_[i].clear();
allVectors_[i].setCapacity(nSeeds);
}
// additional particle info
streamLineParticle::trackData td
(
particles,
vsInterp,
vvInterp,
UIndex, // index of U in vvInterp
trackForward_, // track in +u direction
allTracks_,
allScalars_,
allVectors_
);
// Track
//Pout<< "Tracking particles." << endl;
particles.move(td);
//Pout<< "Finished tracking particles." << endl;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::streamLine::streamLine
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
dict_(dict),
name_(name),
obr_(obr),
loadFromFiles_(loadFromFiles),
active_(true)
{
// Only active if a fvMesh is available
if (isA<fvMesh>(obr_))
{
read(dict_);
}
else
{
active_ = false;
WarningIn
(
"streamLine::streamLine\n"
"(\n"
"const word&,\n"
"const objectRegistry&,\n"
"const dictionary&,\n"
"const bool\n"
")"
) << "No fvMesh available, deactivating."
<< nl << endl;
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::streamLine::~streamLine()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::streamLine::read(const dictionary& dict)
{
if (active_)
{
//dict_ = dict;
dict.lookup("fields") >> fields_;
UName_ = dict.lookupOrDefault<word>("U", "U");
dict.lookup("trackForward") >> trackForward_;
dict.lookup("lifeTime") >> lifeTime_;
cloudName_ = dict.lookupOrDefault<word>("cloudName", "streamLine");
dict.lookup("seedSampleSet") >> seedSet_;
const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
meshSearchPtr_.reset(new meshSearch(mesh, false));
const dictionary& coeffsDict = dict.subDict(seedSet_ + "Coeffs");
sampledSetPtr_ = sampledSet::New
(
seedSet_,
mesh,
meshSearchPtr_(),
coeffsDict
);
coeffsDict.lookup("axis") >> sampledSetAxis_;
scalarFormatterPtr_ = writer<scalar>::New(dict.lookup("setFormat"));
vectorFormatterPtr_ = writer<vector>::New(dict.lookup("setFormat"));
}
}
void Foam::streamLine::execute()
{
// const Time& runTime = const_cast<Time&>(obr_.time());
// Pout<< "**streamLine::execute : time:" << runTime.timeName() << endl;
// Pout<< "**streamLine::execute : time:" << runTime.timeIndex() << endl;
//
// bool isOutputTime = false;
//
// const functionObjectList& fobs = runTime.functionObjects();
//
// forAll(fobs, i)
// {
// if (isA<streamLineFunctionObject>(fobs[i]))
// {
// const streamLineFunctionObject& fo =
// dynamic_cast<const streamLineFunctionObject&>(fobs[i]);
//
// if (fo.name() == name_)
// {
// Pout<< "found me:" << i << endl;
// if (fo.outputControl().output())
// {
// isOutputTime = true;
// break;
// }
// }
// }
// }
//
//
// if (active_ && isOutputTime)
// {
// track();
// }
}
void Foam::streamLine::end()
{
}
void Foam::streamLine::write()
{
if (active_)
{
const Time& runTime = const_cast<Time&>(obr_.time());
const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
// Do all injection and tracking
track();
if (Pstream::parRun())
{
// Append slave tracks to master ones
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
globalIndex globalTrackIDs(allTracks_.size());
// Construct a distribution map to pull all to the master.
labelListList sendMap(Pstream::nProcs());
labelListList recvMap(Pstream::nProcs());
if (Pstream::master())
{
// Master: receive all. My own first, then consecutive
// processors.
label trackI = 0;
forAll(recvMap, procI)
{
labelList& fromProc = recvMap[procI];
fromProc.setSize(globalTrackIDs.localSize(procI));
forAll(fromProc, i)
{
fromProc[i] = trackI++;
}
}
}
labelList& toMaster = sendMap[0];
toMaster.setSize(globalTrackIDs.localSize());
forAll(toMaster, i)
{
toMaster[i] = i;
}
const mapDistribute distMap
(
globalTrackIDs.size(),
sendMap.xfer(),
recvMap.xfer()
);
// Distribute the track positions
mapDistribute::distribute
(
Pstream::scheduled,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
allTracks_
);
// Distribute the scalars
forAll(allScalars_, scalarI)
{
mapDistribute::distribute
(
Pstream::scheduled,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
allScalars_[scalarI]
);
}
// Distribute the vectors
forAll(allVectors_, vectorI)
{
mapDistribute::distribute
(
Pstream::scheduled,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
allVectors_[vectorI]
);
}
}
label n = 0;
forAll(allTracks_, trackI)
{
n += allTracks_[trackI].size();
}
Info<< "Tracks:" << allTracks_.size()
<< " total samples:" << n << endl;
// Massage into form suitable for writers
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (Pstream::master() && allTracks_.size())
{
// Make output directory
fileName vtkPath
(
Pstream::parRun()
? runTime.path()/".."/"sets"/name()
: runTime.path()/"sets"/name()
);
if (mesh.name() != fvMesh::defaultRegion)
{
vtkPath = vtkPath/mesh.name();
}
vtkPath = vtkPath/mesh.time().timeName();
mkDir(vtkPath);
// Convert track positions
PtrList<coordSet> tracks(allTracks_.size());
forAll(allTracks_, trackI)
{
tracks.set
(
trackI,
new coordSet
(
"track" + Foam::name(trackI),
sampledSetAxis_ //"xyz"
)
);
tracks[trackI].transfer(allTracks_[trackI]);
}
// Convert scalar values
if (allScalars_.size() > 0)
{
List<List<scalarField> > scalarValues(allScalars_.size());
forAll(allScalars_, scalarI)
{
DynamicList<scalarList>& allTrackVals =
allScalars_[scalarI];
scalarValues[scalarI].setSize(allTrackVals.size());
forAll(allTrackVals, trackI)
{
scalarList& trackVals = allTrackVals[trackI];
scalarValues[scalarI][trackI].transfer(trackVals);
}
}
fileName vtkFile
(
vtkPath
/ scalarFormatterPtr_().getFileName
(
tracks[0],
scalarNames_
)
);
Info<< "Writing data to " << vtkFile.path() << endl;
scalarFormatterPtr_().write
(
true, // writeTracks
tracks,
scalarNames_,
scalarValues,
OFstream(vtkFile)()
);
}
// Convert vector values
if (allVectors_.size() > 0)
{
List<List<vectorField> > vectorValues(allVectors_.size());
forAll(allVectors_, vectorI)
{
DynamicList<vectorList>& allTrackVals =
allVectors_[vectorI];
vectorValues[vectorI].setSize(allTrackVals.size());
forAll(allTrackVals, trackI)
{
vectorList& trackVals = allTrackVals[trackI];
vectorValues[vectorI][trackI].transfer(trackVals);
}
}
fileName vtkFile
(
vtkPath
/ vectorFormatterPtr_().getFileName
(
tracks[0],
vectorNames_
)
);
//Info<< "Writing vector data to " << vtkFile << endl;
vectorFormatterPtr_().write
(
true, // writeTracks
tracks,
vectorNames_,
vectorValues,
OFstream(vtkFile)()
);
}
}
}
}
void Foam::streamLine::updateMesh(const mapPolyMesh&)
{
read(dict_);
}
void Foam::streamLine::movePoints(const pointField&)
{
// Moving mesh affects the search tree
read(dict_);
}
//void Foam::streamLine::readUpdate(const polyMesh::readUpdateState state)
//{
// if (state != UNCHANGED)
// {
// read(dict_);
// }
//}
// ************************************************************************* //

View File

@ -0,0 +1,219 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::streamLine
Description
Generation of streamlines. Samples along track of passive particle.
SourceFiles
streamLine.C
\*---------------------------------------------------------------------------*/
#ifndef streamLine_H
#define streamLine_H
#include "volFieldsFwd.H"
#include "pointFieldFwd.H"
#include "Switch.H"
#include "DynamicList.H"
#include "scalarList.H"
#include "vectorList.H"
#include "polyMesh.H"
#include "writer.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class objectRegistry;
class dictionary;
class mapPolyMesh;
class meshSearch;
class sampledSet;
/*---------------------------------------------------------------------------*\
Class streamLine Declaration
\*---------------------------------------------------------------------------*/
class streamLine
{
// Private data
//- Input dictionary
dictionary dict_;
//- Name of this set of field averages.
word name_;
//- Database this class is registered to
const objectRegistry& obr_;
//- Load fields from files (not from objectRegistry)
bool loadFromFiles_;
//- On/off switch
bool active_;
//- List of fields to sample
wordList fields_;
//- Field to transport particle with
word UName_;
//- Whether to use +u or -u
bool trackForward_;
//- Maximum lifetime (= number of cells) of particle
label lifeTime_;
//- Optional specified name of particles
word cloudName_;
//- Type of seed
word seedSet_;
//- Names of scalar fields
wordList scalarNames_;
//- Names of vector fields
wordList vectorNames_;
// Demand driven
//- Mesh searching enigne
autoPtr<meshSearch> meshSearchPtr_;
//- Seed set engine
autoPtr<sampledSet> sampledSetPtr_;
//- Axis of the sampled points to output
word sampledSetAxis_;
//- File output writer
autoPtr<writer<scalar> > scalarFormatterPtr_;
autoPtr<writer<vector> > vectorFormatterPtr_;
// Generated data
//- All tracks. Per particle the points it passed through
DynamicList<List<point> > allTracks_;
//- Per scalarField, per particle, the sampled value.
List<DynamicList<scalarList> > allScalars_;
//- Per scalarField, per particle, the sampled value.
List<DynamicList<vectorList> > allVectors_;
//- Do all seeding and tracking
void track();
//- Disallow default bitwise copy construct
streamLine(const streamLine&);
//- Disallow default bitwise assignment
void operator=(const streamLine&);
public:
//- Runtime type information
TypeName("streamLine");
// Constructors
//- Construct for given objectRegistry and dictionary.
// Allow the possibility to load fields from files
streamLine
(
const word& name,
const objectRegistry&,
const dictionary&,
const bool loadFromFiles = false
);
//- Destructor
virtual ~streamLine();
// Member Functions
//- Return name of the set of field averages
virtual const word& name() const
{
return name_;
}
//- Read the field average data
virtual void read(const dictionary&);
//- Execute the averaging
virtual void execute();
//- Execute the averaging at the final time-loop, currently does nothing
virtual void end();
//- Calculate the field average data and write
virtual void write();
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh&);
//- Update for mesh point-motion
virtual void movePoints(const pointField&);
////- Update for changes of mesh due to readUpdate
//virtual void readUpdate(const polyMesh::readUpdateState state);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//#ifdef NoRepository
//# include "streamLineTemplates.C"
//#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "streamLineFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug(streamLineFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
streamLineFunctionObject,
dictionary
);
}
// ************************************************************************* //

View File

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Typedef
Foam::streamLineFunctionObject
Description
FunctionObject wrapper around streamLines to allow them to be created via
the functions list within controlDict.
SourceFiles
streamLineFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef streamLineFunctionObject_H
#define streamLineFunctionObject_H
#include "streamLine.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef OutputFilterFunctionObject<streamLine>
streamLineFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,486 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*----------------------------------------------------------------------------*/
#include "streamLineParticle.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(streamLineParticle, 0);
defineParticleTypeNameAndDebug(streamLineParticle, 0);
defineTemplateTypeNameAndDebugWithName
(
IOField<vectorField>,
"vectorFieldField",
0
);
};
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::vector Foam::streamLineParticle::interpolateFields
(
const streamLineParticle::trackData& td,
const point& position,
const label cellI
)
{
if (cellI == -1)
{
FatalErrorIn("streamLineParticle::interpolateFields(..)")
<< "Cell:" << cellI << abort(FatalError);
}
sampledScalars_.setSize(td.vsInterp_.size());
forAll(td.vsInterp_, scalarI)
{
sampledScalars_[scalarI].append
(
td.vsInterp_[scalarI].interpolate
(
position,
cellI
)
);
}
sampledVectors_.setSize(td.vvInterp_.size());
forAll(td.vvInterp_, vectorI)
{
sampledVectors_[vectorI].append
(
td.vvInterp_[vectorI].interpolate
(
position,
cellI
)
);
}
const DynamicList<vector>& U = sampledVectors_[td.UIndex_];
return U[U.size()-1];
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct from components
Foam::streamLineParticle::streamLineParticle
(
const Cloud<streamLineParticle>& c,
const vector& position,
const label celli,
const label lifeTime
)
:
Particle<streamLineParticle>(c, position, celli),
lifeTime_(lifeTime)
{}
//- Construct from Istream
Foam::streamLineParticle::streamLineParticle
(
const Cloud<streamLineParticle>& c,
Istream& is,
bool readFields
)
:
Particle<streamLineParticle>(c, is, readFields)
{
if (readFields)
{
//if (is.format() == IOstream::ASCII)
List<scalarList> sampledScalars;
List<vectorList> sampledVectors;
is >> lifeTime_ >> sampledPositions_ >> sampledScalars
>> sampledVectors;
sampledScalars_.setSize(sampledScalars.size());
forAll(sampledScalars, i)
{
sampledScalars_[i].transfer(sampledScalars[i]);
}
sampledVectors_.setSize(sampledVectors.size());
forAll(sampledVectors, i)
{
sampledVectors_[i].transfer(sampledVectors[i]);
}
}
// Check state of Istream
is.check
(
"streamLineParticle::streamLineParticle"
"(const Cloud<streamLineParticle>&, Istream&, bool)"
);
}
// Construct copy
Foam::streamLineParticle::streamLineParticle
(
const streamLineParticle& c
)
:
Particle<streamLineParticle>(c),
lifeTime_(c.lifeTime_),
sampledPositions_(c.sampledPositions_),
sampledScalars_(c.sampledScalars_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::streamLineParticle::move(streamLineParticle::trackData& td)
{
td.switchProcessor = false;
td.keepParticle = true;
scalar deltaT = GREAT; //cloud().pMesh().time().deltaT().value();
scalar tEnd = (1.0 - stepFraction())*deltaT;
scalar dtMax = tEnd;
while
(
td.keepParticle
&& !td.switchProcessor
&& lifeTime_ > 0
&& tEnd > ROOTVSMALL
)
{
// set the lagrangian time-step
scalar dt = min(dtMax, tEnd);
// Store current position and sampled velocity.
--lifeTime_;
sampledPositions_.append(position());
vector U = interpolateFields(td, position(), cell());
if (!td.trackForward_)
{
U = -U;
}
dt *= trackToFace(position()+dt*U, td);
tEnd -= dt;
stepFraction() = 1.0 - tEnd/deltaT;
}
if (!td.keepParticle || lifeTime_ == 0)
{
if (lifeTime_ == 0)
{
if (debug)
{
Pout<< "streamLineParticle : Removing stagnant particle:"
<< static_cast<Particle<streamLineParticle> >(*this)
<< " sampled positions:" << sampledPositions_.size()
<< endl;
}
td.keepParticle = false;
}
else
{
// Normal exit. Store last position and fields
sampledPositions_.append(position());
interpolateFields(td, position(), cell());
if (debug)
{
Pout<< "streamLineParticle : Removing particle:"
<< static_cast<Particle<streamLineParticle> >(*this)
<< " sampled positions:" << sampledPositions_.size()
<< endl;
}
}
// Transfer particle data into trackData.
//td.allPositions_.append(sampledPositions_);
td.allPositions_.append(vectorList());
vectorList& top = td.allPositions_[td.allPositions_.size()-1];
top.transfer(sampledPositions_);
forAll(sampledScalars_, i)
{
//td.allScalars_[i].append(sampledScalars_[i]);
td.allScalars_[i].append(scalarList());
scalarList& top = td.allScalars_[i][td.allScalars_[i].size()-1];
top.transfer(sampledScalars_[i]);
}
forAll(sampledVectors_, i)
{
//td.allVectors_[i].append(sampledVectors_[i]);
td.allVectors_[i].append(vectorList());
vectorList& top = td.allVectors_[i][td.allVectors_[i].size()-1];
top.transfer(sampledVectors_[i]);
}
}
return td.keepParticle;
}
bool Foam::streamLineParticle::hitPatch
(
const polyPatch&,
streamLineParticle::trackData& td,
const label patchI
)
{
// Disable generic patch interaction
return false;
}
bool Foam::streamLineParticle::hitPatch
(
const polyPatch&,
int&,
const label
)
{
// Disable generic patch interaction
return false;
}
void Foam::streamLineParticle::hitWedgePatch
(
const wedgePolyPatch& pp,
streamLineParticle::trackData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::streamLineParticle::hitWedgePatch
(
const wedgePolyPatch&,
int&
)
{}
void Foam::streamLineParticle::hitSymmetryPatch
(
const symmetryPolyPatch& pp,
streamLineParticle::trackData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::streamLineParticle::hitSymmetryPatch
(
const symmetryPolyPatch&,
int&
)
{}
void Foam::streamLineParticle::hitCyclicPatch
(
const cyclicPolyPatch& pp,
streamLineParticle::trackData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::streamLineParticle::hitCyclicPatch
(
const cyclicPolyPatch&,
int&
)
{}
void Foam::streamLineParticle::hitProcessorPatch
(
const processorPolyPatch&,
streamLineParticle::trackData& td
)
{
// Switch particle
td.switchProcessor = true;
}
void Foam::streamLineParticle::hitProcessorPatch
(
const processorPolyPatch&,
int&
)
{}
void Foam::streamLineParticle::hitWallPatch
(
const wallPolyPatch& wpp,
streamLineParticle::trackData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::streamLineParticle::hitWallPatch
(
const wallPolyPatch& wpp,
int&
)
{}
void Foam::streamLineParticle::hitPatch
(
const polyPatch& wpp,
streamLineParticle::trackData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::streamLineParticle::hitPatch
(
const polyPatch& wpp,
int&
)
{}
void Foam::streamLineParticle::readFields
(
Cloud<streamLineParticle>& c
)
{
if (!c.size())
{
return;
}
IOField<label> lifeTime
(
c.fieldIOobject("lifeTime", IOobject::MUST_READ)
);
c.checkFieldIOobject(c, lifeTime);
IOField<pointField> sampledPositions
(
c.fieldIOobject("sampledPositions", IOobject::MUST_READ)
);
c.checkFieldIOobject(c, sampledPositions);
// IOField<pointField> sampleVelocity
// (
// c.fieldIOobject("sampleVelocity", IOobject::MUST_READ)
// );
// c.checkFieldIOobject(c, sampleVelocity);
label i = 0;
forAllIter(Cloud<streamLineParticle>, c, iter)
{
iter().lifeTime_ = lifeTime[i];
iter().sampledPositions_.transfer(sampledPositions[i]);
// iter().sampleVelocity_.transfer(sampleVelocity[i]);
i++;
}
}
void Foam::streamLineParticle::writeFields
(
const Cloud<streamLineParticle>& c
)
{
Particle<streamLineParticle>::writeFields(c);
label np = c.size();
IOField<label> lifeTime
(
c.fieldIOobject("lifeTime", IOobject::NO_READ),
np
);
IOField<pointField> sampledPositions
(
c.fieldIOobject("sampledPositions", IOobject::NO_READ),
np
);
// IOField<pointField> sampleVelocity
// (
// c.fieldIOobject("sampleVelocity", IOobject::NO_READ),
// np
// );
label i = 0;
forAllConstIter(Cloud<streamLineParticle>, c, iter)
{
lifeTime[i] = iter().lifeTime_;
sampledPositions[i] = iter().sampledPositions_;
// sampleVelocity[i] = iter().sampleVelocity_;
i++;
}
lifeTime.write();
sampledPositions.write();
// sampleVelocity.write();
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const streamLineParticle& p)
{
os << static_cast<const Particle<streamLineParticle>&>(p)
<< token::SPACE << p.lifeTime_
<< token::SPACE << p.sampledPositions_
<< token::SPACE << p.sampledScalars_
<< token::SPACE << p.sampledVectors_;
// Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const streamLineParticle&)");
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,300 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::streamLineParticle
Description
Particle class that samples fields as it passes through. Used in streamline
calculation.
SourceFiles
streamLineParticle.C
\*---------------------------------------------------------------------------*/
#ifndef streamLineParticle_H
#define streamLineParticle_H
#include "Particle.H"
#include "autoPtr.H"
#include "interpolationCellPoint.H"
#include "vectorList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class streamLineParticleCloud;
/*---------------------------------------------------------------------------*\
Class streamLineParticle Declaration
\*---------------------------------------------------------------------------*/
class streamLineParticle
:
public Particle<streamLineParticle>
{
public:
//- Class used to pass tracking data to the trackToFace function
class trackData
:
public Particle<streamLineParticle>::trackData
{
public:
const PtrList<interpolationCellPoint<scalar> >& vsInterp_;
const PtrList<interpolationCellPoint<vector> >& vvInterp_;
const label UIndex_;
const bool trackForward_;
DynamicList<vectorList>& allPositions_;
List<DynamicList<scalarList> >& allScalars_;
List<DynamicList<vectorList> >& allVectors_;
// Constructors
trackData
(
Cloud<streamLineParticle>& cloud,
const PtrList<interpolationCellPoint<scalar> >& vsInterp,
const PtrList<interpolationCellPoint<vector> >& vvInterp,
const label UIndex,
const bool trackForward,
DynamicList<List<point> >& allPositions,
List<DynamicList<scalarList> >& allScalars,
List<DynamicList<vectorList> >& allVectors
)
:
Particle<streamLineParticle>::trackData(cloud),
vsInterp_(vsInterp),
vvInterp_(vvInterp),
UIndex_(UIndex),
trackForward_(trackForward),
allPositions_(allPositions),
allScalars_(allScalars),
allVectors_(allVectors)
{}
};
private:
// Private data
//- Lifetime of particle. Particle dies when reaches 0.
label lifeTime_;
//- sampled positions
DynamicList<point> sampledPositions_;
//- sampled scalars
List<DynamicList<scalar> > sampledScalars_;
//- sampled vectors
List<DynamicList<vector> > sampledVectors_;
// Private Member Functions
//- Interpolate all quantities; return interpolated velocity.
vector interpolateFields
(
const streamLineParticle::trackData&,
const point&,
const label cellI
);
public:
//- Run-time type information
TypeName("streamLineParticle");
// Constructors
//- Construct from components
streamLineParticle
(
const Cloud<streamLineParticle>& c,
const vector& position,
const label celli,
const label lifeTime
);
//- Construct from Istream
streamLineParticle
(
const Cloud<streamLineParticle>& c,
Istream& is,
bool readFields = true
);
//- Construct copy
streamLineParticle(const streamLineParticle& c);
//- Construct and return a clone
autoPtr<streamLineParticle> clone() const
{
return autoPtr<streamLineParticle>
(
new streamLineParticle(*this)
);
}
// Member Functions
// Tracking
//- Track all particles to their end point
bool move(trackData&);
//- Overridable function to handle the particle hitting a patch
// Executed before other patch-hitting functions
bool hitPatch
(
const polyPatch&,
streamLineParticle::trackData& td,
const label patchI
);
bool hitPatch
(
const polyPatch&,
int&,
const label patchI
);
//- Overridable function to handle the particle hitting a wedge
void hitWedgePatch
(
const wedgePolyPatch&,
streamLineParticle::trackData& td
);
void hitWedgePatch
(
const wedgePolyPatch&,
int&
);
//- Overridable function to handle the particle hitting a
// symmetryPlane
void hitSymmetryPatch
(
const symmetryPolyPatch&,
streamLineParticle::trackData& td
);
void hitSymmetryPatch
(
const symmetryPolyPatch&,
int&
);
//- Overridable function to handle the particle hitting a cyclic
void hitCyclicPatch
(
const cyclicPolyPatch&,
streamLineParticle::trackData& td
);
void hitCyclicPatch
(
const cyclicPolyPatch&,
int&
);
//- Overridable function to handle the particle hitting a
//- processorPatch
void hitProcessorPatch
(
const processorPolyPatch&,
streamLineParticle::trackData& td
);
void hitProcessorPatch
(
const processorPolyPatch&,
int&
);
//- Overridable function to handle the particle hitting a wallPatch
void hitWallPatch
(
const wallPolyPatch&,
streamLineParticle::trackData& td
);
void hitWallPatch
(
const wallPolyPatch&,
int&
);
//- Overridable function to handle the particle hitting a polyPatch
void hitPatch
(
const polyPatch&,
streamLineParticle::trackData& td
);
void hitPatch
(
const polyPatch&,
int&
);
// I-O
//- Read
static void readFields(Cloud<streamLineParticle>&);
//- Write
static void writeFields(const Cloud<streamLineParticle>&);
// Ostream Operator
friend Ostream& operator<<(Ostream&, const streamLineParticle&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "streamLineParticleCloud.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTemplateTypeNameAndDebug(Cloud<streamLineParticle>, 0);
};
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::streamLineParticleCloud::streamLineParticleCloud
(
const polyMesh& mesh,
const word& cloudName
)
:
Cloud<streamLineParticle>(mesh, cloudName, false)
{
readFields();
}
Foam::streamLineParticleCloud::streamLineParticleCloud
(
const polyMesh& mesh,
const word& cloudName,
const IDLList<streamLineParticle>& particles
)
:
Cloud<streamLineParticle>(mesh, cloudName, particles)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::streamLineParticleCloud::readFields()
{
streamLineParticle::readFields(*this);
}
void Foam::streamLineParticleCloud::writeFields() const
{
streamLineParticle::writeFields(*this);
}
// ************************************************************************* //

View File

@ -23,20 +23,21 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class Class
Foam::faceMesh Foam::streamLineCloud
Description Description
Storage for surface mesh i.e. points and faces. A Cloud of streamLine particles
SourceFiles SourceFiles
streamLineCloud.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef faceMesh_H #ifndef streamLineCloud_H
#define faceMesh_H #define streamLineCloud_H
#include "PrimitivePatch.H" #include "Cloud.H"
#include "faceList.H" #include "streamLineParticle.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -44,62 +45,52 @@ namespace Foam
{ {
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class faceMesh Declaration Class streamLineCloud Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class faceMesh class streamLineParticleCloud
: :
public PrimitivePatch<face, List, pointField> public Cloud<streamLineParticle>
{ {
// Private member functions // Private Member Functions
PrimitivePatch<face, List, pointField> read(Istream& is) //- Disallow default bitwise copy construct
{ streamLineParticleCloud(const streamLineParticleCloud&);
pointField points(is);
faceList faces(is); //- Disallow default bitwise assignment
return PrimitivePatch<face, Foam::List, pointField>(faces, points); void operator=(const streamLineParticleCloud&);
}
public: public:
//- Type of parcel the cloud was instantiated for
typedef streamLineParticle parcelType;
// Constructors // Constructors
//- Construct from components //- Construct given mesh
faceMesh(const faceList& faces, const pointField& points) streamLineParticleCloud
: (
PrimitivePatch<face, Foam::List, pointField>(faces, points) const polyMesh&,
{} const word& cloudName = "defaultCloud"
);
//- Construct from Istream //- Construct from mesh, cloud name, and a list of particles
faceMesh(Istream& is) streamLineParticleCloud
: (
PrimitivePatch<face, Foam::List, pointField>(read(is)) const polyMesh& mesh,
{} const word& cloudName,
const IDLList<streamLineParticle>& particles
);
// Member Functions // Member Functions
void flip() //- Read fields
{ virtual void readFields();
forAll(*this, i)
{
face& f = operator[](i);
f = f.reverseFace();
}
clearOut();
}
// IOstream Operators //- Write fields
virtual void writeFields() const;
friend Ostream& operator<<(Ostream& os, const faceMesh& fm)
{
return os
<< fm.points()
<< token::NL
<< static_cast<PrimitivePatch<face, Foam::List, pointField> >
(fm);
}
}; };

View File

@ -55,8 +55,8 @@ Foam::faceZonesIntegration::faceZonesIntegration
obr_(obr), obr_(obr),
active_(true), active_(true),
log_(false), log_(false),
faceZonesSet_(), zoneNames_(),
fItems_(), fieldNames_(),
filePtr_(NULL) filePtr_(NULL)
{ {
// Check if the available mesh is an fvMesh otherise deactivate // Check if the available mesh is an fvMesh otherise deactivate
@ -94,9 +94,9 @@ void Foam::faceZonesIntegration::read(const dictionary& dict)
{ {
log_ = dict.lookupOrDefault<Switch>("log", false); log_ = dict.lookupOrDefault<Switch>("log", false);
dict.lookup("fields") >> fItems_; dict.lookup("fields") >> fieldNames_;
dict.lookup("faceZones") >> faceZonesSet_; dict.lookup("faceZones") >> zoneNames_;
} }
} }
@ -132,11 +132,11 @@ void Foam::faceZonesIntegration::makeFile()
mkDir(faceZonesIntegrationDir); mkDir(faceZonesIntegrationDir);
// Open new file at start up // Open new file at start up
filePtr_.resize(fItems_.size()); filePtr_.resize(fieldNames_.size());
forAll(fItems_, Ifields) forAll(fieldNames_, fieldI)
{ {
const word& fieldName = fItems_[Ifields]; const word& fieldName = fieldNames_[fieldI];
OFstream* sPtr = new OFstream OFstream* sPtr = new OFstream
( (
@ -163,10 +163,9 @@ void Foam::faceZonesIntegration::writeFileHeader()
os << "#Time " << setw(w); os << "#Time " << setw(w);
forAll (faceZonesSet_, zoneI) forAll (zoneNames_, zoneI)
{ {
const word name = faceZonesSet_[zoneI]; os << zoneNames_[zoneI] << setw(w);
os << name << setw(w);
} }
os << nl << endl; os << nl << endl;
@ -192,9 +191,9 @@ void Foam::faceZonesIntegration::write()
{ {
makeFile(); makeFile();
forAll(fItems_, fieldI) forAll(fieldNames_, fieldI)
{ {
const word& fieldName = fItems_[fieldI]; const word& fieldName = fieldNames_[fieldI];
const surfaceScalarField& sField = const surfaceScalarField& sField =
obr_.lookupObject<surfaceScalarField>(fieldName); obr_.lookupObject<surfaceScalarField>(fieldName);
@ -203,17 +202,17 @@ void Foam::faceZonesIntegration::write()
// 1. integrate over all face zones // 1. integrate over all face zones
scalarField integralVals(faceZonesSet_.size()); scalarField integralVals(zoneNames_.size());
forAll(faceZonesSet_, setI) forAll(integralVals, zoneI)
{ {
const word name = faceZonesSet_[setI]; const word& name = zoneNames_[zoneI];
label zoneID = mesh.faceZones().findZoneID(name); label zoneID = mesh.faceZones().findZoneID(name);
const faceZone& fZone = mesh.faceZones()[zoneID]; const faceZone& fZone = mesh.faceZones()[zoneID];
integralVals[setI] = returnReduce integralVals[zoneI] = returnReduce
( (
calcIntegral(sField, fZone), calcIntegral(sField, fZone),
sumOp<scalar>() sumOp<scalar>()
@ -231,15 +230,15 @@ void Foam::faceZonesIntegration::write()
os << obr_.time().value(); os << obr_.time().value();
forAll(integralVals, setI) forAll(integralVals, zoneI)
{ {
os << ' ' << setw(w) << integralVals[setI]; os << ' ' << setw(w) << integralVals[zoneI];
if (log_) if (log_)
{ {
Info<< "faceZonesIntegration output:" << nl Info<< "faceZonesIntegration output:" << nl
<< " Integration[" << setI << "] " << " Integration[" << zoneI << "] "
<< integralVals[setI] << endl; << integralVals[zoneI] << endl;
} }
} }

View File

@ -82,11 +82,11 @@ protected:
//- Switch to send output to Info as well as to file //- Switch to send output to Info as well as to file
Switch log_; Switch log_;
//- faceZones to integrate over //- List of face zone names to integrate over
wordList faceZonesSet_; wordList zoneNames_;
//- Names of the surface fields //- Names of the surface fields
wordList fItems_; wordList fieldNames_;
//- Current open files //- Current open files

View File

@ -1,16 +1,17 @@
probes/probes.C probes/probes.C
probes/probesFunctionObject.C probes/probesFunctionObject.C
sampledSet/coordSet/coordSet.C
sampledSet/sampledSet/sampledSet.C
sampledSet/cloud/cloudSet.C sampledSet/cloud/cloudSet.C
sampledSet/face/faceOnlySet.C sampledSet/coordSet/coordSet.C
sampledSet/curve/curveSet.C sampledSet/curve/curveSet.C
sampledSet/uniform/uniformSet.C sampledSet/face/faceOnlySet.C
sampledSet/midPoint/midPointSet.C sampledSet/midPoint/midPointSet.C
sampledSet/midPointAndFace/midPointAndFaceSet.C sampledSet/midPointAndFace/midPointAndFaceSet.C
sampledSet/sampledSet/sampledSet.C
sampledSet/sampledSets/sampledSets.C sampledSet/sampledSets/sampledSets.C
sampledSet/sampledSetsFunctionObject/sampledSetsFunctionObject.C sampledSet/sampledSetsFunctionObject/sampledSetsFunctionObject.C
sampledSet/triSurfaceMeshPointSet/triSurfaceMeshPointSet.C
sampledSet/uniform/uniformSet.C
setWriters = sampledSet/writers setWriters = sampledSet/writers
@ -18,6 +19,7 @@ $(setWriters)/writers.C
$(setWriters)/gnuplot/gnuplotSetWriterRunTime.C $(setWriters)/gnuplot/gnuplotSetWriterRunTime.C
$(setWriters)/jplot/jplotSetWriterRunTime.C $(setWriters)/jplot/jplotSetWriterRunTime.C
$(setWriters)/raw/rawSetWriterRunTime.C $(setWriters)/raw/rawSetWriterRunTime.C
$(setWriters)/vtk/vtkSetWriterRunTime.C
$(setWriters)/xmgrace/xmgraceSetWriterRunTime.C $(setWriters)/xmgrace/xmgraceSetWriterRunTime.C
cuttingPlane/cuttingPlane.C cuttingPlane/cuttingPlane.C

View File

@ -0,0 +1,177 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "triSurfaceMeshPointSet.H"
#include "meshSearch.H"
#include "DynamicList.H"
#include "polyMesh.H"
#include "addToRunTimeSelectionTable.H"
#include "triSurfaceMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(triSurfaceMeshPointSet, 0);
addToRunTimeSelectionTable(sampledSet, triSurfaceMeshPointSet, word);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::triSurfaceMeshPointSet::calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
) const
{
forAll(sampleCoords_, sampleI)
{
label cellI = searchEngine().findCell(sampleCoords_[sampleI]);
if (cellI != -1)
{
samplingPts.append(sampleCoords_[sampleI]);
samplingCells.append(cellI);
samplingFaces.append(-1);
samplingSegments.append(0);
samplingCurveDist.append(1.0 * sampleI);
}
}
}
void Foam::triSurfaceMeshPointSet::genSamples()
{
// Storage for sample points
DynamicList<point> samplingPts;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
calcSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingSegments,
samplingCurveDist
);
samplingPts.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingSegments,
samplingCurveDist
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::triSurfaceMeshPointSet::triSurfaceMeshPointSet
(
const word& name,
const polyMesh& mesh,
meshSearch& searchEngine,
const dictionary& dict
)
:
sampledSet(name, mesh, searchEngine, dict),
surface_(dict.lookup("surface"))
{
// Load surface.
if (mesh.time().foundObject<triSurfaceMesh>(surface_))
{
// Note: should use localPoints() instead of points() but assume
// trisurface is compact.
sampleCoords_ = mesh.time().lookupObject<triSurfaceMesh>
(
surface_
).points();
}
else
{
sampleCoords_ = triSurfaceMesh
(
IOobject
(
surface_,
mesh.time().constant(), // instance
"triSurface", // local
mesh.time(),
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
).points();
}
genSamples();
if (debug)
{
write(Info);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::triSurfaceMeshPointSet::~triSurfaceMeshPointSet()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::point Foam::triSurfaceMeshPointSet::getRefPoint(const List<point>& pts)
const
{
if (pts.size())
{
// Use first samplePt as starting point
return pts[0];
}
else
{
return vector::zero;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,119 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::triSurfaceMeshPointSet
Description
sampleSet from all points of a triSurfaceMesh.
SourceFiles
triSurfaceMeshPointSet.C
\*---------------------------------------------------------------------------*/
#ifndef triSurfaceMeshPointSet_H
#define triSurfaceMeshPointSet_H
#include "sampledSet.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
/*---------------------------------------------------------------------------*\
Class triSurfaceMeshPointSet Declaration
\*---------------------------------------------------------------------------*/
class triSurfaceMeshPointSet
:
public sampledSet
{
// Private data
//- Name of triSurfaceMesh
const word surface_;
//- Sampling points
List<point> sampleCoords_;
// Private Member Functions
//- Samples all points in sampleCoords.
void calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
) const;
//- Uses calcSamples to obtain samples. Copies them into *this.
void genSamples();
public:
//- Runtime type information
TypeName("triSurfaceMeshPointSet");
// Constructors
//- Construct from dictionary
triSurfaceMeshPointSet
(
const word& name,
const polyMesh& mesh,
meshSearch& searchEngine,
const dictionary& dict
);
// Destructor
virtual ~triSurfaceMeshPointSet();
// Member Functions
//- Get reference point
virtual point getRefPoint(const List<point>&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -69,29 +69,73 @@ void Foam::gnuplotSetWriter<Type>::write
Ostream& os Ostream& os
) const ) const
{ {
os << "set term postscript color" << endl os << "set term postscript color" << nl
<< "set output \"" << points.name() << ".ps\"" << endl << "set output \"" << points.name() << ".ps\"" << nl
<< "plot"; << "plot";
bool firstField = true;
forAll(valueSets, i) forAll(valueSets, i)
{ {
if (!firstField) if (i != 0)
{ {
os << ','; os << ',';
} }
firstField = false;
os << "'-' title \"" << valueSetNames[i] << "\" with lines"; os << " \"-\" title \"" << valueSetNames[i] << "\" with lines";
} }
os << endl; os << nl;
forAll(valueSets, i) forAll(valueSets, i)
{ {
os << endl;
writeTable(points, *valueSets[i], os); writeTable(points, *valueSets[i], os);
os << "e" << nl;
}
}
template<class Type>
void Foam::gnuplotSetWriter<Type>::write
(
const bool writeTracks,
const PtrList<coordSet>& trackPoints,
const wordList& valueSetNames,
const List<List<Field<Type> > >& valueSets,
Ostream& os
) const
{
if (valueSets.size() != valueSetNames.size())
{
FatalErrorIn("gnuplotSetWriter<Type>::write(..)")
<< "Number of variables:" << valueSetNames.size() << endl
<< "Number of valueSets:" << valueSets.size()
<< exit(FatalError);
}
if (trackPoints.size() > 0)
{
os << "set term postscript color" << nl
<< "set output \"" << trackPoints[0].name() << ".ps\"" << nl;
forAll(trackPoints, trackI)
{
os << "plot";
forAll(valueSets, i)
{
if (i != 0)
{
os << ',';
}
os << " \"-\" title \"" << valueSetNames[i] << "\" with lines";
}
os << nl;
forAll(valueSets, i)
{
writeTable(trackPoints[trackI], valueSets[i][trackI], os);
os << "e" << nl;
}
}
} }
} }

View File

@ -76,13 +76,22 @@ public:
const wordList& const wordList&
) const; ) const;
void write virtual void write
( (
const coordSet&, const coordSet&,
const wordList&, const wordList&,
const List<const Field<Type>*>&, const List<const Field<Type>*>&,
Ostream& Ostream&
) const; ) const;
virtual void write
(
const bool writeTracks,
const PtrList<coordSet>&,
const wordList& valueSetNames,
const List<List<Field<Type> > >&,
Ostream&
) const;
}; };

View File

@ -39,7 +39,7 @@ Foam::Ostream& Foam::jplotSetWriter<Type>::writeHeader(Ostream& os) const
return os return os
<< "# JPlot input file" << nl << "# JPlot input file" << nl
<< "#" << nl << nl << "#" << nl << nl
<< "# Generated by sample on " << clock::date().c_str() << endl; << "# Generated by sample on " << clock::date().c_str() << nl;
} }
@ -82,11 +82,11 @@ void Foam::jplotSetWriter<Type>::write
) const ) const
{ {
os << "# JPlot file" << nl os << "# JPlot file" << nl
<< "# column 1: " << points.name() << endl; << "# column 1: " << points.name() << nl;
forAll(valueSets, i) forAll(valueSets, i)
{ {
os << "# column " << i + 2 << ": " << valueSetNames[i] << endl; os << "# column " << i + 2 << ": " << valueSetNames[i] << nl;
} }
// Collect sets into columns // Collect sets into columns

View File

@ -80,13 +80,35 @@ public:
const wordList& const wordList&
) const; ) const;
void write virtual void write
( (
const coordSet&, const coordSet&,
const wordList&, const wordList&,
const List<const Field<Type>*>&, const List<const Field<Type>*>&,
Ostream& Ostream&
) const; ) const;
virtual void write
(
const bool writeTracks,
const PtrList<coordSet>&,
const wordList& valueSetNames,
const List<List<Field<Type> > >&,
Ostream&
) const
{
notImplemented
(
"jplotSetWriter<Type>::write\n"
"(\n"
" const bool,\n"
" const PtrList<coordSet>&,\n"
" const wordList&,\n"
" const List<List<Field<Type> > >&,\n"
" Ostream&\n"
") const"
);
}
}; };

View File

@ -79,4 +79,38 @@ void Foam::rawSetWriter<Type>::write
} }
template<class Type>
void Foam::rawSetWriter<Type>::write
(
const bool writeTracks,
const PtrList<coordSet>& points,
const wordList& valueSetNames,
const List<List<Field<Type> > >& valueSets,
Ostream& os
) const
{
if (valueSets.size() != valueSetNames.size())
{
FatalErrorIn("rawSetWriter<Type>::write(..)")
<< "Number of variables:" << valueSetNames.size() << endl
<< "Number of valueSets:" << valueSets.size()
<< exit(FatalError);
}
List<const List<Type>*> columns(valueSets.size());
forAll(points, trackI)
{
// Collect sets into columns
forAll(valueSets, i)
{
columns[i] = &valueSets[i][trackI];
}
writeTable(points[trackI], columns, os);
os << nl << nl;
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -83,6 +83,15 @@ public:
const List<const Field<Type>*>&, const List<const Field<Type>*>&,
Ostream& Ostream&
) const; ) const;
virtual void write
(
const bool writeTracks,
const PtrList<coordSet>&,
const wordList& valueSetNames,
const List<List<Field<Type> > >&,
Ostream&
) const;
}; };

Some files were not shown because too many files have changed in this diff Show More