Merge branch 'feature/blockMeshSyntaxBackport' into nextRelease

This commit is contained in:
Henrik Rusche 2014-06-01 12:04:03 +02:00
commit a78b12074e
359 changed files with 57423 additions and 11686 deletions

View file

@ -47,7 +47,6 @@ Description
using namespace Foam;
#include "argList.H"
#include "objectRegistry.H"
#include "Time.H"
#include "polyMesh.H"
#include "emptyPolyPatch.H"
@ -63,11 +62,16 @@ label maxNodei = 0;
SLPtrList<labelList> slCellLabels;
SLList<label> slCellMap;
SLList<label> slCellType;
label maxCelli = 0;
PtrList<SLList<label> > slPatchCells;
PtrList<SLList<label> > slPatchCellFaces;
// Cell types
Map<word> cellTypes;
label currentTypei = -1;
// Dummy yywrap to keep yylex happy at compile time.
// It is called by yylex but is not used as the mechanism to change file.
@ -90,27 +94,26 @@ cspace ","{space}
alpha [_A-Za-z]
digit [0-9]
dec_digit [0-9]
octal_digit [0-7]
hex_digit [0-9a-fA-F]
identifier {alpha}({alpha}|{digit})*
integer {dec_digit}+
label [1-9]{dec_digit}*
integer {digit}+
label [1-9]{digit}*
exponent_part [eE][-+]?{digit}+
fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
double (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
floatNum (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
x {double}
y {double}
z {double}
value {double}
x {floatNum}
y {floatNum}
z {floatNum}
value {floatNum}
node ^{space}"N"{cspace}
element ^{space}"EN"{cspace}
bface ^{space}"SFE"{cspace}
elementTypeName ^{space}"ET"{cspace}
elementType ^{space}"TYPE"{cspace}
%%
@ -163,6 +166,7 @@ bface ^{space}"SFE"{cspace}
slCellMap.append(celli);
slCellLabels.append(new labelList(labels));
slCellType.append(currentTypei);
}
@ -213,6 +217,37 @@ bface ^{space}"SFE"{cspace}
}
{elementTypeName}{label}{cspace}{identifier}{space}\n {
IStringStream elementStream(YYText());
char tag,c;
label cellTypei;
word cellTypeName;
elementStream
>> tag >> tag // skip 'ET'
>> c >> cellTypei
>> c >> cellTypeName;
Info<< "Read typeName " << cellTypeName
<< " for type " << cellTypei << endl;
cellTypes.insert(cellTypei, cellTypeName);
}
{elementType}{label}{space}\n {
IStringStream elementStream(YYText());
char tag,c;
label cellTypei;
elementStream
>> tag >> tag >> tag >> tag // skip 'TYPE'
>> c >> cellTypei;
currentTypei = cellTypei;
}
/* ------------------------------------------------------------------------- *\
------ Ignore remaining space and \n s. Any other characters are errors.
\* ------------------------------------------------------------------------- */
@ -234,6 +269,29 @@ bface ^{space}"SFE"{cspace}
#include <fstream>
using std::ifstream;
label findFace(const polyMesh& mesh, const face& f)
{
const labelList& pFaces = mesh.pointFaces()[f[0]];
forAll(pFaces, i)
{
label faceI = pFaces[i];
if (mesh.faces()[faceI] == f)
{
return faceI;
}
}
FatalErrorIn("findFace(const polyMesh&, const face&)")
<< "Cannot find a face matching " << f
<< exit(FatalError);
return -1;
}
int main(int argc, char *argv[])
{
argList::noParallel();
@ -264,20 +322,15 @@ int main(int argc, char *argv[])
}
yyFlexLexer lexer(&ansysStream);
while(lexer.yylex() != 0)
while (lexer.yylex() != 0)
{}
Info << "Creating points" << endl;
Info<< "Creating points" << endl;
pointField points(slPoints.size());
label i=0;
for
(
SLList<point>::iterator pointIter = slPoints.begin();
pointIter != slPoints.end();
++pointIter
)
label i = 0;
forAllConstIter(SLList<point>, slPoints, pointIter)
{
// Scale points for the given scale factor
points[i++] = scaleFactor * pointIter();
@ -286,28 +339,18 @@ int main(int argc, char *argv[])
labelList pointMap(maxNodei+1);
i=0;
for
(
SLList<label>::iterator pointMapIter = slPointMap.begin();
pointMapIter != slPointMap.end();
++pointMapIter
)
i = 0;
forAllConstIter(SLList<label>, slPointMap, pointMapIter)
{
pointMap[pointMapIter()] = i++;
}
Info << "Creating cells" << endl;
Info<< "Creating cells" << endl;
labelList cellMap(maxCelli+1);
i=0;
for
(
SLList<label>::iterator cellMapIter = slCellMap.begin();
cellMapIter != slCellMap.end();
++cellMapIter
)
i = 0;
forAllConstIter(SLList<label>, slCellMap, cellMapIter)
{
cellMap[cellMapIter()] = i++;
}
@ -326,12 +369,7 @@ int main(int argc, char *argv[])
cellShapeList cellShapes(slCellLabels.size());
label nCells = 0;
for
(
SLPtrList<labelList>::iterator cellIter = slCellLabels.begin();
cellIter != slCellLabels.end();
++cellIter
)
forAllConstIter(SLPtrList<labelList>, slCellLabels, cellIter)
{
if // Tetrahedron
(
@ -396,6 +434,34 @@ int main(int argc, char *argv[])
}
}
const word defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName;
// Create dummy mesh just to find out what are internal/external
// faces
autoPtr<polyMesh> dummyMesh
(
new polyMesh
(
IOobject
(
"dummyMesh",
runTime.constant(),
runTime
),
xferCopy(points),
cellShapes,
faceListList(0),
wordList(0),
wordList(0),
defaultFacesName,
defaultFacesType,
wordList(0)
)
);
// Warning: tet face order has changed between version 1.9.6 and 2.0
//
label faceIndex[7][6] =
@ -404,12 +470,12 @@ int main(int argc, char *argv[])
{-1, -1, -1, -1, -1, -1}, // 1
{-1, -1, -1, -1, -1, -1}, // 2
{-1, -1, -1, -1, -1, -1}, // 3
{-1, 2, 0, 3, 1, -1}, // tet (version 2.0)
{ 3, 2, 0, -1, 1, -1}, // tet (version 2.0)
{ 0, 4, 3, -1, 2, 1}, // prism
{ 4, 2, 1, 3, 0, 5}, // hex
};
Info << "Creating boundary patches" << endl;
Info<< "Creating boundary patches" << endl;
faceListList boundary(slPatchCells.size());
wordList patchNames(slPatchCells.size());
@ -429,12 +495,14 @@ int main(int argc, char *argv[])
++cellIter, ++faceIter
)
{
const cellShape& shape = cellShapes[cellMap[cellIter()]];
patchFaces.append
(
cellShapes[cellMap[cellIter()] ].faces()
shape.faces()
[
faceIndex
[cellShapes[cellMap[cellIter()] ].nFaces()]
[shape.nFaces()]
[faceIter()-1]
]
);
@ -442,34 +510,85 @@ int main(int argc, char *argv[])
boundary[patchI] = patchFaces;
patchNames[patchI] = word("patch") + name(patchI + 1);
Info << "Patch " << patchI << " named " << patchNames[patchI]
}
//
// Lookup the face labels for all the boundary faces
//
labelListList boundaryFaceLabels(boundary.size());
forAll(boundary, patchI)
{
const faceList& bFaces = boundary[patchI];
labelList& bFaceLabels = boundaryFaceLabels[patchI];
bFaceLabels.setSize(bFaces.size());
forAll(bFaces, i)
{
bFaceLabels[i] = findFace(dummyMesh(), bFaces[i]);
}
}
// Now split the boundary faces into external and internal faces. All
// faces go into faceZones and external faces go into patches.
List<faceList> patchFaces(slPatchCells.size());
labelList patchNFaces(slPatchCells.size(), 0);
forAll(boundary, patchI)
{
const faceList& bFaces = boundary[patchI];
const labelList& bFaceLabels = boundaryFaceLabels[patchI];
patchFaces[patchI].setSize(bFaces.size());
forAll(bFaces, i)
{
if (!dummyMesh().isInternalFace(bFaceLabels[i]))
{
patchFaces[patchI][patchNFaces[patchI]++] = bFaces[i];
}
}
patchFaces[patchI].setSize(patchNFaces[patchI]);
Info<< "Patch " << patchI << " named " << patchNames[patchI]
<< ": " << boundary[patchI].size() << " faces" << endl;
}
Info << "ansysToFoam: " << endl
// We no longer need the dummyMesh
dummyMesh.clear();
Info<< "ansysToFoam: " << endl
<< "Ansys file format does not provide information about the type of "
<< "the patch (eg. wall, symmetry plane, cyclic etc)." << endl
<< "All the patches have been created "
<< "as type patch. Please reset after mesh conversion as necessary."
<< endl;
wordList patchTypes(boundary.size(), polyPatch::typeName);
word defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName;
wordList patchPhysicalTypes(boundary.size());
PtrList<dictionary> patchDicts;
preservePatchTypes
(
runTime,
runTime.constant(),
polyMesh::defaultRegion,
polyMesh::meshSubDir,
patchNames,
patchTypes,
patchDicts,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
defaultFacesType
);
// Add information to dictionary
forAll(patchNames, patchI)
{
if (!patchDicts.set(patchI))
{
patchDicts.set(patchI, new dictionary());
}
// Add but not overwrite
patchDicts[patchI].add("type", polyPatch::typeName, false);
}
polyMesh pShapeMesh
(
IOobject
@ -480,18 +599,101 @@ int main(int argc, char *argv[])
),
xferMove(points),
cellShapes,
boundary,
patchFaces,
patchNames,
patchTypes,
patchDicts,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
defaultFacesType
);
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
Info << "Writing polyMesh" << endl;
if (cellTypes.size() > 0 || patchNames.size() > 0)
{
DynamicList<pointZone*> pz;
DynamicList<faceZone*> fz;
DynamicList<cellZone*> cz;
// FaceZones
forAll(boundaryFaceLabels, patchI)
{
if (boundaryFaceLabels[patchI].size())
{
// Re-do the boundaryFaceLabels since the boundary face
// labels will be different on the pShapeMesh.
const faceList& bFaces = boundary[patchI];
labelList& bFaceLabels = boundaryFaceLabels[patchI];
forAll(bFaceLabels, i)
{
bFaceLabels[i] = findFace(pShapeMesh, bFaces[i]);
}
Info<< "Creating faceZone " << patchNames[patchI]
<< " with " << bFaceLabels.size() << " faces" << endl;
fz.append
(
new faceZone
(
patchNames[patchI],
bFaceLabels,
boolList(bFaceLabels.size(), false),
fz.size(),
pShapeMesh.faceZones()
)
);
}
}
// CellZones
labelList types = cellTypes.toc();
forAll(types, j)
{
label cellType = types[j];
// Pick up cells in zone
DynamicList<label> addr;
SLList<label>::iterator cellMapIter = slCellMap.begin();
SLList<label>::iterator typeIter = slCellType.begin();
for
(
;
typeIter != slCellType.end();
++typeIter, ++cellMapIter
)
{
if (typeIter() == cellType)
{
addr.append(cellMap[cellMapIter()]);
}
}
Info<< "Creating cellZone " << cellTypes[cellType]
<< " with " << addr.size() << " cells" << endl;
cz.append
(
new cellZone
(
cellTypes[cellType],
addr,
j,
pShapeMesh.cellZones()
)
);
}
pShapeMesh.addZones(pz, fz, cz);
}
// Set the precision of the points data to 10
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
Info<< "Writing polyMesh" << endl;
pShapeMesh.write();
Info<< nl << "end" << endl;

View file

@ -30,7 +30,6 @@ Description
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "objectRegistry.H"
#include "Time.H"
#include "IFstream.H"
#include "hexBlock.H"
@ -44,7 +43,6 @@ Description
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
@ -73,7 +71,7 @@ int main(int argc, char *argv[])
cfxFile >> nblock >> npatch >> nglue >> nelem >> npoint;
Info << "Reading blocks" << endl;
Info<< "Reading blocks" << endl;
PtrList<hexBlock> blocks(nblock);
@ -81,7 +79,7 @@ int main(int argc, char *argv[])
word blockName;
label nx, ny, nz;
forAll (blocks, blockI)
forAll(blocks, blockI)
{
cfxFile >> blockName;
cfxFile >> nx >> ny >> nz;
@ -90,7 +88,7 @@ int main(int argc, char *argv[])
}
}
Info << "Reading patch definitions" << endl;
Info<< "Reading patch definitions" << endl;
wordList cfxPatchTypes(npatch);
wordList cfxPatchNames(npatch);
@ -101,7 +99,7 @@ int main(int argc, char *argv[])
{
label no, blkNo, patchLabel;
forAll (cfxPatchTypes, patchI)
forAll(cfxPatchTypes, patchI)
{
// Grab patch type and name
cfxFile >> cfxPatchTypes[patchI] >> cfxPatchNames[patchI] >> no;
@ -110,7 +108,7 @@ int main(int argc, char *argv[])
patchRanges[patchI].setSize(6);
labelList& curRange = patchRanges[patchI];
forAll (curRange, rI)
forAll(curRange, rI)
{
cfxFile >> curRange[rI];
}
@ -126,7 +124,7 @@ int main(int argc, char *argv[])
}
}
Info << "Reading block glueing information" << endl;
Info<< "Reading block glueing information" << endl;
labelList glueMasterPatches(nglue, -1);
labelList glueSlavePatches(nglue, -1);
@ -145,15 +143,15 @@ int main(int argc, char *argv[])
}
}
Info << "Reading block points" << endl;
Info<< "Reading block points" << endl;
forAll (blocks, blockI)
forAll(blocks, blockI)
{
Info << "block " << blockI << " is a ";
Info<< "block " << blockI << " is a ";
blocks[blockI].readPoints(cfxFile);
}
Info << "Calculating block offsets" << endl;
Info<< "Calculating block offsets" << endl;
labelList blockOffsets(nblock, -1);
@ -172,11 +170,11 @@ int main(int argc, char *argv[])
+ blocks[blockI - 1].nBlockPoints();
}
Info << "Assembling patches" << endl;
Info<< "Assembling patches" << endl;
faceListList rawPatches(npatch);
forAll (rawPatches, patchI)
forAll(rawPatches, patchI)
{
const word& patchType = cfxPatchTypes[patchI];
@ -203,7 +201,7 @@ int main(int argc, char *argv[])
}
}
Info << "Merging points ";
Info<< "Merging points ";
labelList pointMergeList(nMeshPoints, -1);
@ -214,7 +212,7 @@ int main(int argc, char *argv[])
// For efficiency, create merge pairs in the first pass
labelListListList glueMergePairs(glueMasterPatches.size());
forAll (glueMasterPatches, glueI)
forAll(glueMasterPatches, glueI)
{
const label masterPatch = glueMasterPatches[glueI];
const label slavePatch = glueSlavePatches[glueI];
@ -247,14 +245,14 @@ int main(int argc, char *argv[])
scalar sqrMergeTol = GREAT;
forAll (blockPFaces, blockPFaceLabel)
forAll(blockPFaces, blockPFaceLabel)
{
const labelList& blockPFacePoints =
blockPFaces[blockPFaceLabel];
forAll (blockPFacePoints, blockPFacePointI)
forAll(blockPFacePoints, blockPFacePointI)
{
forAll (blockPFacePoints, blockPFacePointI2)
forAll(blockPFacePoints, blockPFacePointI2)
{
if (blockPFacePointI != blockPFacePointI2)
{
@ -281,7 +279,7 @@ int main(int argc, char *argv[])
// N-squared point search over all points of all faces of
// master block over all point of all faces of slave block
forAll (blockPFaces, blockPFaceLabel)
forAll(blockPFaces, blockPFaceLabel)
{
const labelList& blockPFacePoints =
blockPFaces[blockPFaceLabel];
@ -289,16 +287,16 @@ int main(int argc, char *argv[])
labelList& cp = curPairs[blockPFaceLabel];
cp.setSize(blockPFacePoints.size());
forAll (blockPFacePoints, blockPFacePointI)
forAll(blockPFacePoints, blockPFacePointI)
{
found = false;
forAll (blockNFaces, blockNFaceLabel)
forAll(blockNFaces, blockNFaceLabel)
{
const labelList& blockNFacePoints =
blockNFaces[blockNFaceLabel];
forAll (blockNFacePoints, blockNFacePointI)
forAll(blockNFacePoints, blockNFacePointI)
{
if
(
@ -360,7 +358,7 @@ int main(int argc, char *argv[])
changedPointMerge = false;
nPasses++;
forAll (glueMasterPatches, glueI)
forAll(glueMasterPatches, glueI)
{
const label masterPatch = glueMasterPatches[glueI];
const label slavePatch = glueSlavePatches[glueI];
@ -372,14 +370,14 @@ int main(int argc, char *argv[])
const labelListList& curPairs = glueMergePairs[glueI];
forAll (blockPFaces, blockPFaceLabel)
forAll(blockPFaces, blockPFaceLabel)
{
const labelList& blockPFacePoints =
blockPFaces[blockPFaceLabel];
const labelList& cp = curPairs[blockPFaceLabel];
forAll (cp, blockPFacePointI)
forAll(cp, blockPFacePointI)
{
label PpointLabel =
blockPFacePoints[blockPFacePointI]
@ -408,10 +406,10 @@ int main(int argc, char *argv[])
}
}
}
Info << "." << flush;
Info<< "." << flush;
}
while (changedPointMerge && nPasses < 8);
Info << endl;
Info<< endl;
if (changedPointMerge == true)
{
@ -421,7 +419,7 @@ int main(int argc, char *argv[])
}
forAll (glueMasterPatches, glueI)
forAll(glueMasterPatches, glueI)
{
const label masterPatch = glueMasterPatches[glueI];
const label slavePatch = glueSlavePatches[glueI];
@ -433,12 +431,12 @@ int main(int argc, char *argv[])
const faceList& blockNFaces = rawPatches[slavePatch];
forAll (blockPFaces, blockPFaceLabel)
forAll(blockPFaces, blockPFaceLabel)
{
const labelList& blockPFacePoints
= blockPFaces[blockPFaceLabel];
forAll (blockPFacePoints, blockPFacePointI)
forAll(blockPFacePoints, blockPFacePointI)
{
label PpointLabel =
blockPFacePoints[blockPFacePointI]
@ -455,12 +453,12 @@ int main(int argc, char *argv[])
}
}
forAll (blockNFaces, blockNFaceLabel)
forAll(blockNFaces, blockNFaceLabel)
{
const labelList& blockNFacePoints
= blockNFaces[blockNFaceLabel];
forAll (blockNFacePoints, blockNFacePointI)
forAll(blockNFacePoints, blockNFacePointI)
{
label NpointLabel =
blockNFacePoints[blockNFacePointI]
@ -483,7 +481,7 @@ int main(int argc, char *argv[])
// given old point label
label nNewPoints = 0;
forAll (pointMergeList, pointLabel)
forAll(pointMergeList, pointLabel)
{
if (pointMergeList[pointLabel] > pointLabel)
{
@ -509,15 +507,15 @@ int main(int argc, char *argv[])
nMeshPoints = nNewPoints;
Info << "Creating points" << endl;
Info<< "Creating points" << endl;
pointField points(nMeshPoints);
forAll (blocks, blockI)
forAll(blocks, blockI)
{
const pointField& blockPoints = blocks[blockI].points();
forAll (blockPoints, blockPointLabel)
forAll(blockPoints, blockPointLabel)
{
points
[
@ -536,7 +534,7 @@ int main(int argc, char *argv[])
points *= scaleFactor;
}
Info << "Creating cells" << endl;
Info<< "Creating cells" << endl;
cellShapeList cellShapes(nMeshCells);
@ -544,15 +542,15 @@ int main(int argc, char *argv[])
label nCreatedCells = 0;
forAll (blocks, blockI)
forAll(blocks, blockI)
{
labelListList curBlockCells = blocks[blockI].blockCells();
forAll (curBlockCells, blockCellI)
forAll(curBlockCells, blockCellI)
{
labelList cellPoints(curBlockCells[blockCellI].size());
forAll (cellPoints, pointI)
forAll(cellPoints, pointI)
{
cellPoints[pointI] =
pointMergeList
@ -568,18 +566,17 @@ int main(int argc, char *argv[])
}
}
Info << "Creating boundary patches" << endl;
Info<< "Creating boundary patches" << endl;
faceListList boundary(npatch);
wordList patchNames(npatch);
wordList patchTypes(npatch);
word defaultFacesName = "defaultFaces";
word defaultFacesType = wallPolyPatch::typeName;
wordList patchPhysicalTypes(npatch);
label nCreatedPatches = 0;
forAll (rawPatches, patchI)
forAll(rawPatches, patchI)
{
if (rawPatches[patchI].size() && cfxPatchTypes[patchI] != "BLKBDY")
{
@ -600,7 +597,7 @@ int main(int argc, char *argv[])
if (existingPatch >= 0)
{
Info << "CFX patch " << patchI
Info<< "CFX patch " << patchI
<< ", of type " << cfxPatchTypes[patchI]
<< ", name " << cfxPatchNames[patchI]
<< " already exists as FOAM patch " << existingPatch
@ -610,14 +607,14 @@ int main(int argc, char *argv[])
label oldSize = renumberedPatch.size();
renumberedPatch.setSize(oldSize + curRawPatch.size());
forAll (curRawPatch, faceI)
forAll(curRawPatch, faceI)
{
const face& oldFace = curRawPatch[faceI];
face& newFace = renumberedPatch[oldSize + faceI];
newFace.setSize(oldFace.size());
forAll (oldFace, pointI)
forAll(oldFace, pointI)
{
newFace[pointI] =
pointMergeList
@ -634,14 +631,14 @@ int main(int argc, char *argv[])
faceList& renumberedPatch = boundary[nCreatedPatches];
renumberedPatch.setSize(curRawPatch.size());
forAll (curRawPatch, faceI)
forAll(curRawPatch, faceI)
{
const face& oldFace = curRawPatch[faceI];
face& newFace = renumberedPatch[faceI];
newFace.setSize(oldFace.size());
forAll (oldFace, pointI)
forAll(oldFace, pointI)
{
newFace[pointI] =
pointMergeList
@ -652,7 +649,7 @@ int main(int argc, char *argv[])
}
}
Info << "CFX patch " << patchI
Info<< "CFX patch " << patchI
<< ", of type " << cfxPatchTypes[patchI]
<< ", name " << cfxPatchNames[patchI]
<< " converted into FOAM patch " << nCreatedPatches
@ -660,7 +657,7 @@ int main(int argc, char *argv[])
if (cfxPatchTypes[patchI] == "WALL")
{
Info << "wall." << endl;
Info<< "wall." << endl;
patchTypes[nCreatedPatches] = wallPolyPatch::typeName;
patchNames[nCreatedPatches] = cfxPatchNames[patchI];
@ -668,7 +665,7 @@ int main(int argc, char *argv[])
}
else if (cfxPatchTypes[patchI] == "SYMMET")
{
Info << "symmetryPlane." << endl;
Info<< "symmetryPlane." << endl;
patchTypes[nCreatedPatches] = symmetryPolyPatch::typeName;
patchNames[nCreatedPatches] = cfxPatchNames[patchI];
@ -683,7 +680,7 @@ int main(int argc, char *argv[])
|| cfxPatchTypes[patchI] == "USER2D"
)
{
Info << "generic." << endl;
Info<< "generic." << endl;
patchTypes[nCreatedPatches] = polyPatch::typeName;
patchNames[nCreatedPatches] = cfxPatchNames[patchI];
@ -704,18 +701,30 @@ int main(int argc, char *argv[])
patchTypes.setSize(nCreatedPatches);
patchNames.setSize(nCreatedPatches);
PtrList<dictionary> patchDicts;
preservePatchTypes
(
runTime,
runTime.constant(),
polyMesh::defaultRegion,
polyMesh::meshSubDir,
patchNames,
patchTypes,
patchDicts,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
defaultFacesType
);
// Add information to dictionary
forAll(patchNames, patchI)
{
if (!patchDicts.set(patchI))
{
patchDicts.set(patchI, new dictionary());
}
// Add but not overwrite
patchDicts[patchI].add("type", patchTypes[patchI], false);
}
polyMesh pShapeMesh
(
IOobject
@ -728,19 +737,18 @@ int main(int argc, char *argv[])
cellShapes,
boundary,
patchNames,
patchTypes,
patchDicts,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
defaultFacesType
);
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
Info << "Writing polyMesh" << endl;
Info<< "Writing polyMesh" << endl;
pShapeMesh.write();
Info << "End\n" << endl;
Info<< "End\n" << endl;
return 0;
}

View file

@ -34,19 +34,17 @@ Description
#undef yyFlexLexer
/* ------------------------------------------------------------------------- *\
/* ------------------------------------------------------------------------- *\
------ local definitions
\* ------------------------------------------------------------------------- */
\* ------------------------------------------------------------------------- */
#include "argList.H"
#include "objectRegistry.H"
#include "Time.H"
#include "IStringStream.H"
#include "polyMesh.H"
#include "emptyPolyPatch.H"
#include "wallPolyPatch.H"
#include "symmetryPolyPatch.H"
#include "preservePatchTypes.H"
#include "cellShape.H"
#include "faceSet.H"
#include "cellSet.H"
@ -132,7 +130,7 @@ quote \"
dash "-"
dotColonDash [.:-]
schemeSpecialInitial [!$%&*/\\:<=>?~_^#.@']
schemeSpecialInitial [!$%&*/:<=>?~_^#.]
schemeSpecialSubsequent [.+-]
schemeSymbol (({some_space}|{alpha}|{quote}|{schemeSpecialInitial})({alpha}|{quote}|{digit}|{schemeSpecialInitial}|{schemeSpecialSubsequent})*)
@ -142,7 +140,7 @@ integer {decDigit}+
label [1-9]{decDigit}*
hexLabel {hexDigit}+
zeroLabel {digit}*
signedInteger [-+]?{integer}
word ({alpha}|{digit}|{dotColonDash})*
exponent_part [eE][-+]?{digit}+
@ -252,11 +250,11 @@ endOfSection {space}")"{space}
%}
/* ------------------------------------------------------------------------ *\
/* ------------------------------------------------------------------------- *\
------ Start Lexing ------
\* ------------------------------------------------------------------------ */
\* ------------------------------------------------------------------------- */
/* ------ Reading control header ------ */
/* ------ Reading control header ------ */
{comment} {
yy_push_state(readComment);
@ -491,7 +489,7 @@ endOfSection {space}")"{space}
// set size of label list
curFaceLabels.setSize(readLabel(mixedFaceStream));
forAll (curFaceLabels, i)
forAll(curFaceLabels, i)
{
curFaceLabels[i] = readHexLabel(mixedFaceStream) - 1;
}
@ -512,7 +510,7 @@ endOfSection {space}")"{space}
// for edge is 2, for triangle is 3 and for quad is 4
curFaceLabels.setSize(faceGroupElementType);
forAll (curFaceLabels, i)
forAll(curFaceLabels, i)
{
curFaceLabels[i] = readHexLabel(mixedFaceStream) - 1;
}
@ -766,6 +764,7 @@ endOfSection {space}")"{space}
}
<readZoneBlock>{lbrac} {
Info<< "Found unknown block in zone:" << YYText() << endl;
yy_push_state(unknownBlock);
}
@ -785,6 +784,7 @@ endOfSection {space}")"{space}
{lbrac}{label} {
Info<< "Found unknown block:" << YYText() << endl;
yy_push_state(unknownBlock);
}
@ -792,11 +792,13 @@ endOfSection {space}")"{space}
}
<readComment,unknownBlock,embeddedUnknownBlock>{spaceNl}{lbrac} {
Info<< "Embedded blocks in comment or unknown:" << YYText() << endl;
yy_push_state(embeddedUnknownBlock);
}
<readComment,unknownBlock,embeddedUnknownBlock>{spaceNl}{endOfSection} {
Info<< "Found end of section in unknown:" << YYText() << endl;
yy_pop_state();
}
@ -900,7 +902,7 @@ int main(int argc, char *argv[])
patchNameIDs.setSize(maxZoneID);
yyFlexLexer lexer(&fluentStream);
while(lexer.yylex() != 0)
while (lexer.yylex() != 0)
{}
Info<< "\n\nFINISHED LEXING\n\n\n";
@ -917,14 +919,14 @@ int main(int argc, char *argv[])
labelList nFacesInCell(nCells, 0);
forAll (cellFaces, celli)
forAll(cellFaces, celli)
{
cellFaces[celli].setSize(fluentModelNFaces[fluentCellModelID[celli] ]);
}
// fill in owner and neighbour
forAll (owner, faceI)
forAll(owner, faceI)
{
if (owner[faceI] > -1)
{
@ -946,7 +948,7 @@ int main(int argc, char *argv[])
}
}
forAll (neighbour, faceI)
forAll(neighbour, faceI)
{
if (neighbour[faceI] > -1)
{
@ -999,8 +1001,8 @@ int main(int argc, char *argv[])
// Note: In order for the owner-neighbour rules to be right, the
// points given by Fluent need to represent the FRONT plane of the
// geometry. Therefore, the extrusion will be in -z direction
forAll (oldPoints, pointI)
//
forAll(oldPoints, pointI)
{
points[nNewPoints] = oldPoints[pointI];
@ -1009,7 +1011,7 @@ int main(int argc, char *argv[])
nNewPoints++;
}
forAll (oldPoints, pointI)
forAll(oldPoints, pointI)
{
points[nNewPoints] = oldPoints[pointI];
@ -1024,7 +1026,7 @@ int main(int argc, char *argv[])
// Set the number of empty faces
frontAndBackFaces.setSize(2*nCells);
forAll (fluentCellModelID, celli)
forAll(fluentCellModelID, celli)
{
switch (fluentCellModelID[celli])
{
@ -1068,7 +1070,7 @@ int main(int argc, char *argv[])
default:
{
FatalErrorIn(args.executable())
FatalErrorIn("fluentToFoam::main(int argc, char *argv[])")
<< "unrecognised 2-D cell shape: "
<< fluentCellModelID[celli]
<< abort(FatalError);
@ -1077,12 +1079,12 @@ int main(int argc, char *argv[])
}
// Create new faces
forAll (faces, faceI)
forAll(faces, faceI)
{
if (faces[faceI].size() != 2)
{
FatalErrorIn(args.executable())
FatalErrorIn("fluentToFoam::main(int argc, char *argv[])")
<< "fluentMeshToFoam: a 2-D face defined with "
<< faces[faceI].size() << " points." << endl;
}
@ -1102,7 +1104,7 @@ int main(int argc, char *argv[])
{
// 3-D shape recognition
Info<< "Creating shapes for 3-D cells"<< endl;
forAll (fluentCellModelID, celli)
forAll(fluentCellModelID, celli)
{
if
(
@ -1128,7 +1130,7 @@ int main(int argc, char *argv[])
}
else
{
FatalErrorIn(args.executable())
FatalErrorIn("fluentToFoam::main(int argc, char *argv[])")
<< "unrecognised 3-D cell shape: "
<< fluentCellModelID[celli]
<< abort(FatalError);
@ -1140,7 +1142,7 @@ int main(int argc, char *argv[])
// area vector points into the domain. Turn them round before making patches
// for Foam compatibility
forAll (faces, faceI)
forAll(faces, faceI)
{
if (owner[faceI] == -1)
{
@ -1228,7 +1230,7 @@ int main(int argc, char *argv[])
label nPatches = 0;
// Colate information for all patches (internal and external)
// colate information for all patches (internal and external)
// Create a file listing patch type for each zone
@ -1271,7 +1273,7 @@ int main(int argc, char *argv[])
++faceGroupEndIndexIter
)
{
// Get face type and name
// get face type and name
const word& curPatchType = patchTypeIDs[faceGroupZoneIDIter()];
const word& curPatchName = patchNameIDs[faceGroupZoneIDIter()];
@ -1282,15 +1284,15 @@ int main(int argc, char *argv[])
<< " end: " << faceGroupEndIndexIter()
<< " type: " << curPatchType << " name: " << curPatchName << endl;
// Record zone index
// record zone index
zoneToPatchName[faceGroupZoneIDIter()] = curPatchName;
// Make patch labels
// make patch labels
label faceLabel = faceGroupStartIndexIter() - 1;
faceList patchFaces(faceGroupEndIndexIter() - faceLabel);
forAll (patchFaces, faceI)
forAll(patchFaces, faceI)
{
if
(
@ -1310,7 +1312,7 @@ int main(int argc, char *argv[])
}
}
// Inlets and outlets
//inlets and outlets
if
(
curPatchType == "pressure"
@ -1375,7 +1377,7 @@ int main(int argc, char *argv[])
else if
(
curPatchType == ""
) // Unnamed face regions default to interior patches
) //unnamed face regions default to interior patches
{
Info<< "Patch " << faceGroupZoneIDIter()
<< ": Faces are defined but "
@ -1391,7 +1393,7 @@ int main(int argc, char *argv[])
}
else //unknown face regions are not handled
{
FatalErrorIn(args.executable())
FatalErrorIn("fluentToFoam::main(int argc, char *argv[])")
<< "fluent patch type " << curPatchType << " not recognised."
<< abort(FatalError);
}
@ -1436,25 +1438,12 @@ int main(int argc, char *argv[])
label sz = bFaces.size();
labelList meshFaces(sz,-1);
//make face set and write (seperate from rest for clarity)
//internal and external Fluent boundaries
// Search faces by point matching
forAll(bFaces, j)
{
faceSet pFaceSet(pShapeMesh, patchNames[patchI], sz);
forAll (bFaces, j)
{
const face& f = bFaces[j];
label cMeshFace = findFace(pShapeMesh, f);
meshFaces[j] = cMeshFace;
pFaceSet.insert(cMeshFace);
}
if (writeSets)
{
Info<< "Writing patch " << patchNames[patchI]
<< " of size " << sz << " to faceSet." << endl;
pFaceSet.write();
}
const face& f = bFaces[j];
label cMeshFace = findFace(pShapeMesh, f);
meshFaces[j] = cMeshFace;
}
@ -1471,7 +1460,7 @@ int main(int argc, char *argv[])
&& !pShapeMesh.isInternalFace(meshFaces[0])
)
{
// First face is external and has valid non-internal type
//first face is external and has valid non-internal type
//check all faces for externalness just to be sure
//and mark patch number to global list
@ -1488,7 +1477,7 @@ int main(int argc, char *argv[])
<< exit(FatalError);
}
if(facePatchID[faceI - pShapeMesh.nInternalFaces()]!= -1)
if (facePatchID[faceI - pShapeMesh.nInternalFaces()]!= -1)
{
FatalErrorIn(args.executable())
<< "Face " << faceI << " on new patch "
@ -1501,7 +1490,7 @@ int main(int argc, char *argv[])
facePatchID[faceI - pShapeMesh.nInternalFaces()] = nBoundaries;
}
// Add to boundary patch
//add to boundary patch
Info<< "Adding new patch " << patchNames[patchI]
<< " of type " << patchTypes[patchI]
@ -1540,7 +1529,7 @@ int main(int argc, char *argv[])
DynamicList<label> defaultBoundaryFaces(facePatchID.size());
forAll(facePatchID, idI)
{
if(facePatchID[idI] == -1)
if (facePatchID[idI] == -1)
{
defaultBoundaryFaces.append(idI);
facePatchID[idI] = nBoundaries;
@ -1548,7 +1537,7 @@ int main(int argc, char *argv[])
}
defaultBoundaryFaces.shrink();
if (defaultBoundaryFaces.size() != 0)
if (defaultBoundaryFaces.size())
{
Warning << " fluent mesh has " << defaultBoundaryFaces.size()
<< " undefined boundary faces." << endl
@ -1592,20 +1581,34 @@ int main(int argc, char *argv[])
}
repatcher.repatch();
preservePatchTypes
(
runTime,
runTime.constant(),
polyMesh::defaultRegion,
patchNames,
patchTypes,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
);
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
// Re-do face matching to write sets
if (writeSets)
{
forAll(patches, patchI)
{
const faceList& bFaces = patches[patchI];
label sz = bFaces.size();
faceSet pFaceSet(pShapeMesh, patchNames[patchI], sz);
forAll(bFaces, j)
{
const face& f = bFaces[j];
label cMeshFace = findFace(pShapeMesh, f);
pFaceSet.insert(cMeshFace);
}
Info<< "Writing patch " << patchNames[patchI]
<< " of size " << sz << " to faceSet" << endl;
pFaceSet.instance() = pShapeMesh.instance();
pFaceSet.write();
}
}
// Zones
@ -1616,7 +1619,7 @@ int main(int argc, char *argv[])
// interior boundaries are handled via faceSets
// cell zones will only be written if there is more than one
if (writeZones && cellGroupZoneID.size()>1)
if (writeZones && cellGroupZoneID.size() > 1)
{
Info<< "Adding Zones" << endl;
List<pointZone*> pz(0);
@ -1640,7 +1643,7 @@ int main(int argc, char *argv[])
boundaryZones[pI].append(bPatches[pI].name());
}
label cnt = 0;
label cnt=0;
SLList<label>::iterator cg = cellGroupZoneID.begin();
SLList<label>::iterator start = cellGroupStartIndex.begin();
SLList<label>::iterator end = cellGroupEndIndex.begin();
@ -1659,11 +1662,11 @@ int main(int argc, char *argv[])
// Mark zone cells, used for finding faces
boolList zoneCell(pShapeMesh.nCells(), false);
// Shift cell indices by 1
label nr = 0;
// shift cell indices by 1
label nr=0;
for (label celli = (start() - 1); celli < end(); celli++)
{
cls[nr] = celli;
cls[nr]=celli;
zoneCell[celli] = true;
nr++;
}
@ -1681,9 +1684,9 @@ int main(int argc, char *argv[])
{
label nei = pShapeMesh.faceNeighbour()[faceI];
label own = pShapeMesh.faceOwner()[faceI];
if(nei != -1)
if (nei != -1)
{
if(zoneCell[nei] && zoneCell[own])
if (zoneCell[nei] && zoneCell[own])
{
zoneFaces.append(faceI);
}
@ -1706,7 +1709,7 @@ int main(int argc, char *argv[])
const labelList& faceCells = bPatches[pI].faceCells();
forAll(faceCells, fcI)
{
if(zoneCell[faceCells[fcI] ])
if (zoneCell[faceCells[fcI] ])
{
boundaryZones[pI].append(name);
break;
@ -1731,7 +1734,7 @@ int main(int argc, char *argv[])
);
OFstream boundaryCellZonesFile(bczf);
forAll (boundaryZones, bzI)
forAll(boundaryZones, bzI)
{
forAll(boundaryZones[bzI], bzII)
{
@ -1760,7 +1763,7 @@ int main(int argc, char *argv[])
// soon negating the need for double output
if (writeSets)
{
if (cellGroupZoneID.size() > 1 )
if (cellGroupZoneID.size() > 1)
{
Info<< "Writing cell sets" << endl;
@ -1773,8 +1776,8 @@ int main(int argc, char *argv[])
for (; cg != cellGroupZoneID.end(); ++cg, ++start, ++end)
{
const word& name = patchNameIDs[cg()];
const word& type = patchTypeIDs[cg()];
const word& name=patchNameIDs[cg()];
const word& type=patchTypeIDs[cg()];
Info<< "Writing cell set: " << name
<< " of type " << type << " starting at " << start() - 1
@ -1783,7 +1786,7 @@ int main(int argc, char *argv[])
cellSet internal(pShapeMesh, name, end() - start());
// shift cell indizes by 1
for(label celli=start() - 1; celli<=end() - 1; celli++)
for (label celli = start() - 1; celli <= end() - 1; celli++)
{
internal.insert(celli);
}
@ -1797,11 +1800,11 @@ int main(int argc, char *argv[])
}
}
Info<< nl << "End" << endl;
Info<< "\nEnd\n" << endl;
return 0;
}
/* --------------------------------------------------------------------------*\
/* ------------------------------------------------------------------------- *\
------ End of fluentMeshToFoam.L
\* --------------------------------------------------------------------------*/
\* ------------------------------------------------------------------------- */

View file

@ -40,10 +40,12 @@ Description
#include "scalarList.H"
#include "IStringStream.H"
// For EOF only
#include <cstdio>
using namespace Foam;
#include "argList.H"
#include "objectRegistry.H"
#include "Time.H"
#include "polyMesh.H"
#include "emptyPolyPatch.H"
@ -92,24 +94,14 @@ int yyFlexLexer::yywrap()
one_space [ \t\f\r]
space {one_space}*
some_space {one_space}+
cspace ","{space}
spaceNl ({space}|\n)*
alpha [_[:alpha:]]
digit [[:digit:]]
dec_digit [[:digit:]]
octal_digit [0-7]
hex_digit [[:xdigit:]]
lbrac "("
rbrac ")"
quote \"
dash "-"
dotColonDash [.:-]
dotColonDash [.:-]
identifier {alpha}({alpha}|{digit})*
integer {dec_digit}+
label [0-9]{dec_digit}*
label [0-9]{digit}*
zeroLabel {digit}*
word ({alpha}|{digit}|{dotColonDash})*
@ -117,14 +109,14 @@ word ({alpha}|{digit}|{dotColonDash})*
exponent_part [eE][-+]?{digit}+
fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
double ((({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))|0)
floatNum ((({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))|0)
x {floatNum}
y {floatNum}
z {floatNum}
x {double}
y {double}
z {double}
scalar {double}
labelListElement {space}{zeroLabel}
scalarListElement {space}{double}
scalarListElement {space}{floatNum}
labelList ({labelListElement}+{space})
scalarList ({scalarListElement}+{space})
@ -230,7 +222,7 @@ mtype {space}"MTYPE:"{space}
<readProgramID>{space}{word} {
Info << "Written by " << YYText() << " ";
Info<< "Written by " << YYText() << " ";
BEGIN(controlInfo);
}
@ -242,20 +234,20 @@ mtype {space}"MTYPE:"{space}
<readVersionID>{space}{versionNumber} {
Info << " version " << YYText() << endl;
Info<< " version " << YYText() << endl;
BEGIN(controlInfo);
}
<controlInfo>{space}{dateDDMonYYYY}{space}{time} {
Info << "File written on " << YYText() << endl;
Info<< "File written on " << YYText() << endl;
}
<controlInfo>{space}{dateDDMMYYYY}{space}{time} {
Info << "File written on " << YYText() << endl;
Info<< "File written on " << YYText() << endl;
}
@ -301,7 +293,7 @@ mtype {space}"MTYPE:"{space}
{nodalCoords}{spaceNl} {
curNumberOfNodes = 0;
Info << "Reading nodal coordinates" << endl;
Info<< "Reading nodal coordinates" << endl;
BEGIN(nodalCoords);
}
@ -329,7 +321,7 @@ mtype {space}"MTYPE:"{space}
{cellsAndElements}{spaceNl} {
curNumberOfCells = 0;
Info << "Reading cells" << endl;
Info<< "Reading cells" << endl;
BEGIN(cellsAndElements);
}
@ -419,7 +411,7 @@ mtype {space}"MTYPE:"{space}
/* ------ Reading element group information ------ */
{cellStreams}{spaceNl} {
Info << "Reading cell streams" << endl;
Info<< "Reading cell streams" << endl;
BEGIN(cellStreams);
}
@ -441,7 +433,7 @@ mtype {space}"MTYPE:"{space}
}
else
{
curGroupID = readLabel(groupStream);;
curGroupID = readLabel(groupStream);
}
BEGIN(cellStreams);
@ -501,7 +493,7 @@ mtype {space}"MTYPE:"{space}
<cellStreamFlags>{labelList} {
Info << "Reading cell stream labels" << endl;
Info<< "Reading cell stream labels" << endl;
BEGIN(cellStreamLabels);
}
@ -526,7 +518,7 @@ mtype {space}"MTYPE:"{space}
<cellStreamLabels>{endOfSection}\n {
Info << "Finished reading cell stream labels" << endl;
Info<< "Finished reading cell stream labels" << endl;
// reset current group ID and a number of flags
curGroupID = 0;
@ -538,7 +530,7 @@ mtype {space}"MTYPE:"{space}
{boundaryPatch}{spaceNl} {
curPatchFace = 0;
Info << "Reading patches" << endl;
Info<< "Reading patches" << endl;
BEGIN(boundaryPatchParams);
}
@ -580,7 +572,7 @@ mtype {space}"MTYPE:"{space}
{
scalarList patchFaceValues(nValuesForPatchFaces);
forAll (patchFaceValues, fI)
forAll(patchFaceValues, fI)
{
patchFaceValues[fI] = readScalar(patchFacesStream);
}
@ -662,15 +654,15 @@ int main(int argc, char *argv[])
}
yyFlexLexer lexer(&gambitStream);
while(lexer.yylex() != 0)
while (lexer.yylex() != 0)
{}
Info << "Finished lexing" << endl;
Info<< "Finished lexing" << endl;
// make a point mapping array
label maxPointIndex = 0;
forAll (pointMap, pointI)
forAll(pointMap, pointI)
{
if (pointMap[pointI] > maxPointIndex)
{
@ -681,7 +673,7 @@ int main(int argc, char *argv[])
labelList pointLookup(maxPointIndex + 1, -1);
forAll (pointMap, pointI)
forAll(pointMap, pointI)
{
pointLookup[pointMap[pointI] ] = pointI;
}
@ -689,7 +681,7 @@ int main(int argc, char *argv[])
// make a cell mapping array
label maxCellIndex = 0;
forAll (cellMap, cellI)
forAll(cellMap, cellI)
{
if (cellMap[cellI] > maxCellIndex)
{
@ -699,7 +691,7 @@ int main(int argc, char *argv[])
labelList cellLookup(maxCellIndex + 1);
forAll (cellMap, cellI)
forAll(cellMap, cellI)
{
cellLookup[cellMap[cellI] ] = cellI;
}
@ -716,7 +708,7 @@ int main(int argc, char *argv[])
cellShapeList cells(cellLabels.size());
forAll (cellTypes, cellI)
forAll(cellTypes, cellI)
{
const labelList& curCellLabels = cellLabels[cellI];
@ -795,7 +787,7 @@ int main(int argc, char *argv[])
faceList& patchFaces = boundary[patchI];
patchFaces.setSize(curCells.size());
forAll (curCells, faceI)
forAll(curCells, faceI)
{
patchFaces[faceI] =
cells[cellLookup[curCells[faceI] ] ].faces()
@ -812,7 +804,7 @@ int main(int argc, char *argv[])
}
}
Info << "gambitToFoam: " << endl
Info<< "gambitToFoam: " << endl
<< "Gambit file format does not provide information about the type of "
<< "the patch (eg. wall, symmetry plane, cyclic etc)." << endl
<< "All the patches have been created "
@ -822,24 +814,32 @@ int main(int argc, char *argv[])
// Scale points
points *= scaleFactor;
wordList patchTypes(boundary.size(), polyPatch::typeName);
PtrList<dictionary> patchDicts(boundary.size());
word defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName;
wordList patchPhysicalTypes(boundary.size());
preservePatchTypes
(
runTime,
runTime.constant(),
polyMesh::defaultRegion,
polyMesh::meshSubDir,
patchNames,
patchTypes,
patchDicts,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
defaultFacesType
);
// Mesh will auto-write on construction
// Add information to dictionary
forAll(patchNames, patchI)
{
if (!patchDicts.set(patchI))
{
patchDicts.set(patchI, new dictionary());
}
// Add but not overwrite
patchDicts[patchI].add("type", polyPatch::typeName, false);
}
polyMesh pShapeMesh
(
IOobject
@ -852,19 +852,18 @@ int main(int argc, char *argv[])
cells,
boundary,
patchNames,
patchTypes,
patchDicts,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
defaultFacesType
);
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
Info << "Writing polyMesh" << endl;
Info<< "Writing polyMesh" << endl;
pShapeMesh.write();
Info<< nl << "End" << endl;
Info<< "\nEnd\n" << endl;
return 0;
}

View file

@ -30,7 +30,6 @@ Description
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "objectRegistry.H"
#include "Time.H"
#include "polyMesh.H"
#include "IFstream.H"
@ -43,11 +42,11 @@ Description
#include "symmetryPolyPatch.H"
#include "wedgePolyPatch.H"
#include "cyclicPolyPatch.H"
#include "mathematicalConstants.H"
#include "unitConversion.H"
using namespace Foam;
// Supported KIVA versions
//- Supported KIVA versions
enum kivaVersions
{
kiva3,
@ -55,7 +54,6 @@ enum kivaVersions
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
@ -93,7 +91,6 @@ int main(int argc, char *argv[])
<< exit(FatalError);
args.printUsage();
FatalError.exit(1);
}
}
@ -103,7 +100,7 @@ int main(int argc, char *argv[])
# include "readKivaGrid.H"
Info << "End\n" << endl;
Info<< "End\n" << endl;
return 0;
}

View file

@ -20,7 +20,7 @@ pointField points(nPoints);
label i4;
labelList idface(nPoints), fv(nPoints);
for(label i=0; i<nPoints; i++)
for (label i=0; i<nPoints; i++)
{
scalar ffv;
kivaFile
@ -44,7 +44,7 @@ labelList i1tab(nPoints), i3tab(nPoints), i8tab(nPoints), idreg(nPoints),
label nBfaces = 0;
for(label i=0; i<nPoints; i++)
for (label i=0; i<nPoints; i++)
{
label i1, i3, i8;
scalar ff, fbcl, fbcf, fbcb;
@ -85,7 +85,7 @@ if (mTable == 0)
labelList imtab(nPoints), jmtab(nPoints), kmtab(nPoints);
for(label i=0; i<nPoints; i++)
for (label i=0; i<nPoints; i++)
{
label im, jm, km;
kivaFile >> i4 >> im >> jm >> km;
@ -109,13 +109,13 @@ label activeCells = 0;
// Create and set the collocated point collapse map
labelList pointMap(nPoints);
forAll (pointMap, i)
forAll(pointMap, i)
{
pointMap[i] = i;
}
// Initialise all cells to hex and search and set map for collocated points
for(label i=0; i<nPoints; i++)
for (label i=0; i<nPoints; i++)
{
if (f[i] > 0.0)
{
@ -132,7 +132,7 @@ for(label i=0; i<nPoints; i++)
edgeList edges = cellShapes[activeCells].edges();
forAll (edges, ei)
forAll(edges, ei)
{
if (edges[ei].mag(points) < SMALL)
{
@ -167,11 +167,11 @@ cellZoning.setSize(activeCells);
// Map collocated points to refer to the same point and collapse cell shape
// to the corresponding hex-degenerate.
forAll (cellShapes, celli)
forAll(cellShapes, celli)
{
cellShape& cs = cellShapes[celli];
forAll (cs, i)
forAll(cs, i)
{
cs[i] = pointMap[cs[i]];
}
@ -237,7 +237,7 @@ List<SLList<face> > pFaces[nBCs];
face quadFace(4);
face triFace(3);
for(label i=0; i<nPoints; i++)
for (label i=0; i<nPoints; i++)
{
if (f[i] > 0)
{
@ -315,7 +315,7 @@ for(label i=0; i<nPoints; i++)
}
}
// Tranfer liner faces that are above the minimum cylinder-head z height
// Transfer liner faces that are above the minimum cylinder-head z height
// into the cylinder-head region
if
(
@ -327,16 +327,11 @@ if
{
scalar minz = GREAT;
for
(
SLList<face>::iterator iter = pFaces[CYLINDERHEAD][0].begin();
iter != pFaces[CYLINDERHEAD][0].end();
++iter
)
forAllConstIter(SLList<face>, pFaces[CYLINDERHEAD][0], iter)
{
const face& pf = iter();
forAll (pf, pfi)
forAll(pf, pfi)
{
minz = min(minz, points[pf[pfi]].z());
}
@ -346,17 +341,12 @@ if
SLList<face> newLinerFaces;
for
(
SLList<face>::iterator iter = pFaces[LINER][0].begin();
iter != pFaces[LINER][0].end();
++iter
)
forAllConstIter(SLList<face>, pFaces[LINER][0], iter)
{
const face& pf = iter();
scalar minfz = GREAT;
forAll (pf, pfi)
forAll(pf, pfi)
{
minfz = min(minfz, points[pf[pfi]].z());
}
@ -380,17 +370,12 @@ if
SLList<face> newCylinderHeadFaces;
for
(
SLList<face>::iterator iter = pFaces[CYLINDERHEAD][0].begin();
iter != pFaces[CYLINDERHEAD][0].end();
++iter
)
forAllConstIter(SLList<face>, pFaces[CYLINDERHEAD][0], iter)
{
const face& pf = iter();
scalar minfz = GREAT;
forAll (pf, pfi)
forAll(pf, pfi)
{
minfz = min(minfz, points[pf[pfi]].z());
}
@ -417,7 +402,7 @@ if
label nPatches = 0;
for (int bci=0; bci<nBCs; bci++)
{
forAll (pFaces[bci], rgi)
forAll(pFaces[bci], rgi)
{
if (pFaces[bci][rgi].size())
{
@ -434,7 +419,7 @@ if (pFaces[WEDGE].size() && pFaces[WEDGE][0].size())
{
// Distribute the points to be +/- 2.5deg from the x-z plane
scalar tanTheta = Foam::tan(2.5*mathematicalConstant::pi/180.0);
scalar tanTheta = Foam::tan(degToRad(2.5));
SLList<face>::iterator iterf = pFaces[WEDGE][0].begin();
SLList<face>::iterator iterb = pFaces[WEDGE][1].begin();
@ -456,12 +441,7 @@ if (pFaces[WEDGE].size() && pFaces[WEDGE][0].size())
{
pFaces[CYCLIC].setSize(1);
pFaces[CYCLIC][0] = pFaces[WEDGE][0];
for
(
SLList<face>::iterator iterb = pFaces[WEDGE][1].begin();
iterb != pFaces[WEDGE][1].end();
++iterb
)
forAllIter(SLList<face>, pFaces[WEDGE][1], iterb)
{
pFaces[CYCLIC][0].append(iterb());
}
@ -479,13 +459,12 @@ wordList patchNames(nPatches);
wordList patchTypes(nPatches);
word defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName;
wordList patchPhysicalTypes(nPatches);
label nAddedPatches = 0;
for (int bci=0; bci<nBCs; bci++)
{
forAll (pFaces[bci], rgi)
forAll(pFaces[bci], rgi)
{
if (pFaces[bci][rgi].size())
{
@ -510,9 +489,9 @@ for (int bci=0; bci<nBCs; bci++)
labelList pointLabels(nPoints, -1);
// Scan cells for used points
forAll (cellShapes, celli)
forAll(cellShapes, celli)
{
forAll (cellShapes[celli], i)
forAll(cellShapes[celli], i)
{
pointLabels[cellShapes[celli][i]] = 1;
}
@ -520,7 +499,7 @@ forAll (cellShapes, celli)
// Create addressing for used points and pack points array
label newPointi = 0;
forAll (pointLabels, pointi)
forAll(pointLabels, pointi)
{
if (pointLabels[pointi] != -1)
{
@ -531,41 +510,51 @@ forAll (pointLabels, pointi)
points.setSize(newPointi);
// Reset cell point labels
forAll (cellShapes, celli)
forAll(cellShapes, celli)
{
cellShape& cs = cellShapes[celli];
forAll (cs, i)
forAll(cs, i)
{
cs[i] = pointLabels[cs[i]];
}
}
// Reset boundary-face point labels
forAll (boundary, patchi)
forAll(boundary, patchi)
{
forAll (boundary[patchi], facei)
forAll(boundary[patchi], facei)
{
face& f = boundary[patchi][facei];
forAll (f, i)
forAll(f, i)
{
f[i] = pointLabels[f[i]];
}
}
}
PtrList<dictionary> patchDicts;
preservePatchTypes
(
runTime,
runTime.constant(),
polyMesh::defaultRegion,
polyMesh::meshSubDir,
patchNames,
patchTypes,
patchDicts,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
defaultFacesType
);
// Add information to dictionary
forAll(patchNames, patchI)
{
if (!patchDicts.set(patchI))
{
patchDicts.set(patchI, new dictionary());
}
// Add but not overwrite
patchDicts[patchI].add("type", patchTypes[patchI], false);
}
// Build the mesh and write it out
polyMesh pShapeMesh
@ -580,10 +569,9 @@ polyMesh pShapeMesh
cellShapes,
boundary,
patchNames,
patchTypes,
patchDicts,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
defaultFacesType
);
Info << "Writing polyMesh" << endl;

View file

@ -230,17 +230,28 @@ void sammMesh::readBoundary()
patchPhysicalTypes_.setSize(patchTypes_.size());
PtrList<dictionary> patchDicts;
preservePatchTypes
(
runTime_,
runTime_.constant(),
polyMesh::defaultRegion,
polyMesh::meshSubDir,
patchNames_,
patchTypes_,
patchDicts,
defaultFacesName_,
defaultFacesType_,
patchPhysicalTypes_
defaultFacesType_
);
forAll(patchDicts, patchI)
{
if (patchDicts.set(patchI))
{
const dictionary& dict = patchDicts[patchI];
dict.readIfPresent("type", patchTypes_[patchI]);
dict.readIfPresent("physicalType", patchPhysicalTypes_[patchI]);
}
}
}

View file

@ -228,17 +228,28 @@ void starMesh::readBoundary()
patchPhysicalTypes_.setSize(patchTypes_.size());
PtrList<dictionary> patchDicts;
preservePatchTypes
(
runTime_,
runTime_.constant(),
polyMesh::defaultRegion,
polyMesh::meshSubDir,
patchNames_,
patchTypes_,
patchDicts,
defaultFacesName_,
defaultFacesType_,
patchPhysicalTypes_
defaultFacesType_
);
forAll(patchDicts, patchI)
{
if (patchDicts.set(patchI))
{
const dictionary& dict = patchDicts[patchI];
dict.readIfPresent("type", patchTypes_[patchI]);
dict.readIfPresent("physicalType", patchPhysicalTypes_[patchI]);
}
}
}

View file

@ -1,31 +1,3 @@
curvedEdges = curvedEdges
$(curvedEdges)/curvedEdge.C
$(curvedEdges)/lineEdge.C
$(curvedEdges)/polyLine.C
$(curvedEdges)/polyLineEdge.C
$(curvedEdges)/arcEdge.C
$(curvedEdges)/ellipseEdge.C
$(curvedEdges)/BSpline.C
$(curvedEdges)/lineDivide.C
$(curvedEdges)/CatmullRomSpline.C
$(curvedEdges)/splineEdge.C
blockMesh.C
blockDescriptor.C
setEdge.C
block.C
createTopology.C
checkBlockMesh.C
createBlockOffsets.C
createMergeList.C
createPoints.C
createCells.C
createPatches.C
blockPoints.C
blockCells.C
blockBoundary.C
blockMeshApp.C
EXE = $(FOAM_APPBIN)/blockMesh

View file

@ -1,11 +1,9 @@
EXE_INC = \
-I$(curvedEdges) \
-I$(LIB_SRC)/mesh/blockMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude
EXE_LIBS = \
-lblockMesh \
-lmeshTools \
-lODE \
-lfiniteVolume \
-ldynamicMesh

View file

@ -1,113 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "block.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
label block::vtxLabel(label a, label b, label c)
{
return (a + b*(blockDef_.n().x() + 1)
+ c*(blockDef_.n().x() + 1)*(blockDef_.n().y() + 1));
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from description
block::block(const blockDescriptor& definition)
:
blockDef_(definition),
vertices_
(
((blockDef_.n().x() + 1)*(blockDef_.n().y() + 1)*(blockDef_.n().z() + 1))
),
cells_
(
(blockDef_.n().x()*blockDef_.n().y()*blockDef_.n().z())
),
boundaryPatches_(6)
{
// create points
blockPoints();
// generate internal cells
blockCells();
// generate boundary patches
blockBoundary();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const blockDescriptor& block::blockDef() const
{
return blockDef_;
}
const pointField& block::points() const
{
return vertices_;
}
const labelListList& block::cells() const
{
return cells_;
}
const labelListListList& block::boundaryPatches() const
{
return boundaryPatches_;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Ostream& operator<<(Ostream& os, const block& b)
{
os << b.vertices_ << nl
<< b.cells_ << nl
<< b.boundaryPatches_ << endl;
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,208 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
private member of block. Creates boundary patches for the block
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "block.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::block::blockBoundary()
{
label ni = blockDef_.n().x();
label nj = blockDef_.n().y();
label nk = blockDef_.n().z();
// x-direction
label wallLabel = 0;
label wallCellLabel = 0;
// x-min
boundaryPatches_[wallLabel].setSize(nj*nk);
for (label k = 0; k <= nk - 1; k++)
{
for (label j = 0; j <= nj - 1; j++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(0, j, k);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(0, j, k + 1);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(0, j + 1, k + 1);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(0, j + 1, k);
// update the counter
wallCellLabel++;
}
}
// x-max
wallLabel++;
wallCellLabel = 0;
boundaryPatches_[wallLabel].setSize(nj*nk);
for (label k = 0; k <= nk - 1; k++)
{
for (label j = 0; j <= nj - 1; j++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(ni, j, k);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(ni, j+1, k);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(ni, j+1, k+1);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(ni, j, k+1);
// update the counter
wallCellLabel++;
}
}
// y-direction
// y-min
wallLabel++;
wallCellLabel = 0;
boundaryPatches_[wallLabel].setSize(ni*nk);
for (label i = 0; i <= ni - 1; i++)
{
for (label k = 0; k <= nk - 1; k++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(i, 0, k);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(i + 1, 0, k);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(i + 1, 0, k + 1);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(i, 0, k + 1);
// update the counter
wallCellLabel++;
}
}
// y-max
wallLabel++;
wallCellLabel = 0;
boundaryPatches_[wallLabel].setSize(ni*nk);
for (label i = 0; i <= ni - 1; i++)
{
for (label k = 0; k <= nk - 1; k++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(i, nj, k);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(i, nj, k + 1);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(i + 1, nj, k + 1);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(i + 1, nj, k);
// update the counter
wallCellLabel++;
}
}
// z-direction
// z-min
wallLabel++;
wallCellLabel = 0;
boundaryPatches_[wallLabel].setSize(ni*nj);
for (label i = 0; i <= ni - 1; i++)
{
for (label j = 0; j <= nj - 1; j++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(i, j, 0);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(i, j + 1, 0);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(i + 1, j + 1, 0);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(i + 1, j, 0);
// update the counter
wallCellLabel++;
}
}
// z-max
wallLabel++;
wallCellLabel = 0;
boundaryPatches_[wallLabel].setSize(ni*nj);
for (label i = 0; i <= ni - 1; i++)
{
for (label j = 0; j <= nj - 1; j++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(i, j, nk);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(i + 1, j, nk);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(i + 1, j + 1, nk);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(i, j + 1, nk);
// update the counter
wallCellLabel++;
}
}
}
// ************************************************************************* //

View file

@ -1,64 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
private member of block. Creates cells for the block.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "block.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::block::blockCells()
{
label ni = blockDef_.n().x();
label nj = blockDef_.n().y();
label nk = blockDef_.n().z();
label cellNo = 0;
for (label k = 0; k <= nk - 1; k++)
{
for (label j = 0; j <= nj - 1; j++)
{
for (label i = 0; i <= ni - 1; i++)
{
cells_[cellNo].setSize(8);
cells_[cellNo][0] = vtxLabel(i, j, k);
cells_[cellNo][1] = vtxLabel(i+1, j, k);
cells_[cellNo][2] = vtxLabel(i+1, j+1, k);
cells_[cellNo][3] = vtxLabel(i, j+1, k);
cells_[cellNo][4] = vtxLabel(i, j, k+1);
cells_[cellNo][5] = vtxLabel(i+1, j, k+1);
cells_[cellNo][6] = vtxLabel(i+1, j+1, k+1);
cells_[cellNo][7] = vtxLabel(i, j+1, k+1);
cellNo++;
}
}
}
}
// ************************************************************************* //

View file

@ -1,247 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "blockDescriptor.H"
#include "scalarList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void blockDescriptor::makeBlockEdges()
{
// for all edges check the list of curved edges. If the edge is curved,
// add it to the list. If the edge is not found, create is as a line
setEdge(0, 0, 1, n_.x());
setEdge(1, 3, 2, n_.x());
setEdge(2, 7, 6, n_.x());
setEdge(3, 4, 5, n_.x());
setEdge(4, 0, 3, n_.y());
setEdge(5, 1, 2, n_.y());
setEdge(6, 5, 6, n_.y());
setEdge(7, 4, 7, n_.y());
setEdge(8, 0, 4, n_.z());
setEdge(9, 1, 5, n_.z());
setEdge(10, 2, 6, n_.z());
setEdge(11, 3, 7, n_.z());
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// from components
blockDescriptor::blockDescriptor
(
const cellShape& bshape,
const pointField& blockMeshPoints,
const curvedEdgeList& edges,
const Vector<label>& n,
const scalarList& expand,
const word& zoneName
)
:
blockMeshPoints_(blockMeshPoints),
blockShape_(bshape),
curvedEdges_(edges),
edgePoints_(12),
edgeWeights_(12),
n_(n),
expand_(expand),
zoneName_(zoneName)
{
if (expand_.size() != 12)
{
FatalErrorIn
(
"blockDescriptor::blockDescriptor"
"(const cellShape& bshape, const pointField& blockMeshPoints, "
"const curvedEdgeList& edges, label xnum, label ynum, label znum, "
"const scalarList& expand, const word& zoneName)"
) << "Unknown definition of expansion ratios"
<< exit(FatalError);
}
makeBlockEdges();
}
// from Istream
blockDescriptor::blockDescriptor
(
const pointField& blockMeshPoints,
const curvedEdgeList& edges,
Istream& is
)
:
blockMeshPoints_(blockMeshPoints),
blockShape_(is),
curvedEdges_(edges),
edgePoints_(12),
edgeWeights_(12),
n_(),
expand_(12),
zoneName_()
{
// Look at first token
token t(is);
is.putBack(t);
// Optional zone name
if (t.isWord())
{
zoneName_ = t.wordToken();
// Consume zoneName token
is >> t;
// New look-ahead
is >> t;
is.putBack(t);
}
if (t.isPunctuation())
{
if (t.pToken() == token::BEGIN_LIST)
{
is >> n_;
}
else
{
FatalIOErrorIn
(
"blockDescriptor::blockDescriptor"
"(const pointField&, const curvedEdgeList&, Istream& is)",
is
) << "incorrect token while reading n, expected '(', found "
<< t.info()
<< exit(FatalIOError);
}
}
else
{
is >> n_.x() >> n_.y() >> n_.z();
}
is >> t;
if (!t.isWord())
{
is.putBack(t);
}
scalarList expRatios(is);
if (expRatios.size() == 3)
{
expand_[0] = expRatios[0];
expand_[1] = expRatios[0];
expand_[2] = expRatios[0];
expand_[3] = expRatios[0];
expand_[4] = expRatios[1];
expand_[5] = expRatios[1];
expand_[6] = expRatios[1];
expand_[7] = expRatios[1];
expand_[8] = expRatios[2];
expand_[9] = expRatios[2];
expand_[10] = expRatios[2];
expand_[11] = expRatios[2];
}
else if (expRatios.size() == 12)
{
expand_ = expRatios;
}
else
{
FatalErrorIn
(
"blockDescriptor::blockDescriptor"
"(const pointField& blockMeshPoints, const curvedEdgeList& edges,"
"Istream& is)"
) << "Unknown definition of expansion ratios"
<< exit(FatalError);
}
// create a list of edges
makeBlockEdges();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const pointField& blockDescriptor::points() const
{
return blockMeshPoints_;
}
const cellShape& blockDescriptor::blockShape() const
{
return blockShape_;
}
const List<List<point> >& blockDescriptor::blockEdgePoints() const
{
return edgePoints_;
}
const scalarListList& blockDescriptor::blockEdgeWeights() const
{
return edgeWeights_;
}
const Vector<label>& blockDescriptor::n() const
{
return n_;
}
const word& blockDescriptor::zoneName() const
{
return zoneName_;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void blockDescriptor::operator=(const blockDescriptor&)
{
notImplemented("void blockDescriptor::operator=(const blockDescriptor&)");
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,167 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::blockDescriptor
Description
block descriptor. Takes the description of the block and the list
of curved edges and creates a list of points on edges together
with the weighting factors
SourceFiles
blockDescriptor.C
\*---------------------------------------------------------------------------*/
#ifndef blockDescriptor_H
#define blockDescriptor_H
#include "scalar.H"
#include "label.H"
#include "point.H"
#include "cellShape.H"
#include "scalarList.H"
#include "curvedEdgeList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class Istream;
class Ostream;
/*---------------------------------------------------------------------------*\
Class blockDescriptor Declaration
\*---------------------------------------------------------------------------*/
class blockDescriptor
{
// Private data
//- Block mesh points
const pointField& blockMeshPoints_;
//- block shape
cellShape blockShape_;
// reference to a list of curved edges
const curvedEdgeList& curvedEdges_;
// block edge points
List<List<point> > edgePoints_;
//- block edge weighting factors
scalarListList edgeWeights_;
//- number of point in each direction
Vector<label> n_;
//- expansion ratios in all directions
scalarList expand_;
//- name of the zone (empty string if none)
word zoneName_;
// Private member functions
void makeBlockEdges();
void setEdge(label edge, label start, label end, label dim);
public:
// Constructors
//- Construct from components. Optional cellSet/zone name.
blockDescriptor
(
const cellShape&,
const pointField& blockMeshPoints,
const curvedEdgeList& edges,
const Vector<label>& n,
const scalarList& expand,
const word& zoneName = ""
);
//- Construct from Istream
blockDescriptor
(
const pointField& blockMeshPoints,
const curvedEdgeList& edges,
Istream& is
);
//- Clone
autoPtr<blockDescriptor> clone() const
{
notImplemented("blockDescriptor::clone()");
return autoPtr<blockDescriptor>(NULL);
}
// Member Functions
// Access
const pointField& points() const;
const cellShape& blockShape() const;
const List<List<point> >& blockEdgePoints() const;
const scalarListList& blockEdgeWeights() const;
const Vector<label>& n() const;
const word& zoneName() const;
// Member Operators
void operator=(const blockDescriptor&);
// IOstream Operators
friend Ostream& operator<<(Ostream&, const blockDescriptor&);
};
inline Istream& operator>>(Istream& is, blockDescriptor*)
{
notImplemented("Istream& operator>>(Istream& is, blockDescriptor*)");
return is;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,151 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Application
blockMesh
Description
Mesh generator
\*---------------------------------------------------------------------------*/
#include "blockMesh.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from IOdictionary
Foam::blockMesh::blockMesh(IOdictionary& meshDescription)
:
topologyPtr_(createTopology(meshDescription)),
blockOffsets_(createBlockOffsets()),
mergeList_(createMergeList()),
points_(createPoints(meshDescription)),
cells_(createCells()),
patches_(createPatches())
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::blockMesh::~blockMesh()
{
delete topologyPtr_;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::polyMesh& Foam::blockMesh::topology() const
{
if (!topologyPtr_)
{
FatalErrorIn("blockMesh::topology() const")
<< "topologyPtr_ not allocated"
<< exit(FatalError);
}
return *topologyPtr_;
}
Foam::wordList Foam::blockMesh::patchNames() const
{
const polyPatchList& patchTopologies = topology().boundaryMesh();
wordList names(patchTopologies.size());
forAll (names, patchI)
{
names[patchI] = patchTopologies[patchI].name();
}
return names;
}
Foam::wordList Foam::blockMesh::patchTypes() const
{
const polyPatchList& patchTopologies = topology().boundaryMesh();
wordList types(patchTopologies.size());
forAll (types, patchI)
{
types[patchI] = patchTopologies[patchI].type();
}
return types;
}
Foam::wordList Foam::blockMesh::patchPhysicalTypes() const
{
const polyPatchList& patchTopologies = topology().boundaryMesh();
wordList physicalTypes(patchTopologies.size());
forAll (physicalTypes, patchI)
{
physicalTypes[patchI] = patchTopologies[patchI].physicalType();
}
return physicalTypes;
}
Foam::label Foam::blockMesh::numZonedBlocks() const
{
label num = 0;
forAll(*this, blockI)
{
if (operator[](blockI).blockDef().zoneName().size())
{
num++;
}
}
return num;
}
void Foam::blockMesh::writeTopology(Ostream& os) const
{
const pointField& pts = topology().points();
forAll(pts, pI)
{
const point& pt = pts[pI];
os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
}
const edgeList& edges = topology().edges();
forAll(edges, eI)
{
const edge& e = edges[eI];
os << "l " << e.start() + 1 << ' ' << e.end() + 1 << endl;
}
}
// ************************************************************************* //

View file

@ -1,169 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::blockMesh
Description
SourceFiles
blockMesh.C
\*---------------------------------------------------------------------------*/
#ifndef blockMesh_H
#define blockMesh_H
#include "blockList.H"
#include "polyMesh.H"
#include "IOdictionary.H"
#include "curvedEdgeList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class blockMesh Declaration
\*---------------------------------------------------------------------------*/
class blockMesh
:
public blockList
{
// Private data
label nPoints_;
label nCells_;
curvedEdgeList edges_;
polyMesh* topologyPtr_;
labelList blockOffsets_;
labelList mergeList_;
pointField points_;
cellShapeList cells_;
faceListList patches_;
// Private Member Functions
bool blockLabelsOK
(
const label blockLabel,
const pointField& points,
const cellShape& blockShape
);
bool patchLabelsOK
(
const label patchLabel,
const pointField& points,
const faceList& patchShapes
);
polyMesh* createTopology(IOdictionary&);
void checkBlockMesh(const polyMesh&);
labelList createBlockOffsets();
labelList createMergeList();
pointField createPoints(const dictionary&);
cellShapeList createCells();
faceList createPatchFaces(const polyPatch& patchTopologyFaces);
faceListList createPatches();
//- as copy (not implemented)
blockMesh(const blockMesh&);
public:
// Constructors
//- Construct from IOdictionary
blockMesh(IOdictionary&);
// Destructor
~blockMesh();
// Member Functions
// Access
const polyMesh& topology() const;
const curvedEdgeList& edges() const
{
return edges_;
}
const pointField& points() const
{
return points_;
}
const cellShapeList& cells() const
{
return cells_;
}
const faceListList& patches() const
{
return patches_;
}
wordList patchNames() const;
wordList patchTypes() const;
wordList patchPhysicalTypes() const;
//- Number of blocks with specified zones
label numZonedBlocks() const;
// Write
//- Writes edges of blockMesh in OBJ format.
void writeTopology(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,25 +1,25 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
This file is part of OpenFOAM.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
foam-extend 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.
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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
blockMesh
@ -28,25 +28,24 @@ Description
A multi-block mesh generator.
Uses the block mesh description found in
@a constant/polyMesh/blockMeshDict
(or @a constant/\<region\>/polyMesh/blockMeshDict).
\a constant/polyMesh/blockMeshDict
(or \a constant/\<region\>/polyMesh/blockMeshDict).
Usage
- blockMesh [OPTION]
@param -blockTopology \n
\param -blockTopology \n
Write the topology as a set of edges in OBJ format.
@param -region \<name\> \n
\param -region \<name\> \n
Specify an alternative mesh region.
@param -dict \<dictionary\> \n
Specify an alternative dictionary for the block mesh description.
\param -dict \<filename\> \n
Specify alternative dictionary for the block mesh description.
\*---------------------------------------------------------------------------*/
#include "objectRegistry.H"
#include "Time.H"
#include "IOdictionary.H"
#include "IOPtrList.H"
@ -150,8 +149,10 @@ int main(int argc, char *argv[])
Info<< nl << "Creating block mesh from\n "
<< meshDictIoPtr->objectPath() << nl << endl;
blockMesh::verbose(true);
IOdictionary meshDict(meshDictIoPtr());
blockMesh blocks(meshDict);
blockMesh blocks(meshDict, regionName);
if (args.optionFound("blockTopology"))
@ -196,27 +197,10 @@ int main(int argc, char *argv[])
}
Info<< nl << "Creating polyMesh from blockMesh" << endl;
Info<< nl << "Creating mesh from block mesh" << endl;
wordList patchNames = blocks.patchNames();
wordList patchTypes = blocks.patchTypes();
word defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName;
wordList patchPhysicalTypes = blocks.patchPhysicalTypes();
preservePatchTypes
(
runTime,
runTime.constant(),
polyMeshDir,
patchNames,
patchTypes,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
);
polyMesh mesh
(
IOobject
@ -225,14 +209,13 @@ int main(int argc, char *argv[])
runTime.constant(),
runTime
),
xferCopy(blocks.points()),
xferCopy(blocks.points()), // could we re-use space?
blocks.cells(),
blocks.patches(),
patchNames,
patchTypes,
blocks.patchNames(),
blocks.patchDicts(),
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
defaultFacesType
);
@ -244,157 +227,11 @@ int main(int argc, char *argv[])
meshDict.lookup("mergePatchPairs")
);
if (mergePatchPairs.size() > 0)
{
// Create and add point and face zones and mesh modifiers
List<pointZone*> pz(mergePatchPairs.size());
List<faceZone*> fz(3*mergePatchPairs.size());
List<cellZone*> cz(0);
forAll (mergePatchPairs, pairI)
{
const word mergeName
(
mergePatchPairs[pairI].first()
+ mergePatchPairs[pairI].second()
+ name(pairI)
);
pz[pairI] = new pointZone
(
mergeName + "CutPointZone",
labelList(0),
0,
mesh.pointZones()
);
// Master patch
const word masterPatchName(mergePatchPairs[pairI].first());
const polyPatch& masterPatch =
mesh.boundaryMesh()
[
mesh.boundaryMesh().findPatchID(masterPatchName)
];
labelList isf(masterPatch.size());
forAll (isf, i)
{
isf[i] = masterPatch.start() + i;
}
fz[3*pairI] = new faceZone
(
mergeName + "MasterZone",
isf,
boolList(masterPatch.size(), false),
0,
mesh.faceZones()
);
// Slave patch
const word slavePatchName(mergePatchPairs[pairI].second());
const polyPatch& slavePatch =
mesh.boundaryMesh()
[
mesh.boundaryMesh().findPatchID(slavePatchName)
];
labelList osf(slavePatch.size());
forAll (osf, i)
{
osf[i] = slavePatch.start() + i;
}
fz[3*pairI + 1] = new faceZone
(
mergeName + "SlaveZone",
osf,
boolList(slavePatch.size(), false),
1,
mesh.faceZones()
);
// Add empty zone for cut faces
fz[3*pairI + 2] = new faceZone
(
mergeName + "CutFaceZone",
labelList(0),
boolList(0, false),
2,
mesh.faceZones()
);
} // end of all merge pairs
Info << "Adding point and face zones" << endl;
mesh.addZones(pz, fz, cz);
Info << "Creating topo change" << endl;
polyTopoChanger attacher(mesh);
attacher.setSize(mergePatchPairs.size());
forAll (mergePatchPairs, pairI)
{
const word mergeName
(
mergePatchPairs[pairI].first()
+ mergePatchPairs[pairI].second()
+ name(pairI)
);
// Add the sliding interface mesh modifier
attacher.set
(
pairI,
new slidingInterface
(
"couple" + name(pairI),
pairI,
attacher,
mergeName + "MasterZone",
mergeName + "SlaveZone",
mergeName + "CutPointZone",
mergeName + "CutFaceZone",
mergePatchPairs[pairI].first(),
mergePatchPairs[pairI].second(),
slidingInterface::INTEGRAL, // always integral
false, // attach-detach action
intersection::VISIBLE
)
);
}
attacher.changeMesh();
// Clean the mesh after attach
labelList patchSizes(mesh.boundaryMesh().size());
labelList patchStarts(mesh.boundaryMesh().size());
forAll (mesh.boundaryMesh(), patchI)
{
patchSizes[patchI] = mesh.boundaryMesh()[patchI].size();
patchStarts[patchI] = mesh.boundaryMesh()[patchI].start();
}
mesh.resetPrimitives
(
xferCopy<pointField>(mesh.points()),
xferCopy<faceList>(mesh.faces()),
xferCopy<labelList>(mesh.faceOwner()),
xferCopy<labelList>(mesh.faceNeighbour()),
patchSizes,
patchStarts
);
mesh.setInstance(runTime.constant());
mesh.removeZones();
}
# include "mergePatchPairs.H"
}
else
{
Info<< nl << "There are no merge patch pairs" << endl;
Info<< nl << "There are no merge patch pairs edges" << endl;
}
@ -464,7 +301,7 @@ int main(int argc, char *argv[])
{
label zoneI = iter();
cz[zoneI]= new cellZone
cz[zoneI] = new cellZone
(
iter.key(),
zoneCells[zoneI].shrink(),
@ -489,9 +326,9 @@ int main(int argc, char *argv[])
}
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
Info << nl << "Writing polyMesh" << endl;
Info<< nl << "Writing polyMesh" << endl;
mesh.removeFiles();
if (!mesh.write())
{
@ -500,7 +337,39 @@ int main(int argc, char *argv[])
<< exit(FatalError);
}
Info<< nl << "End" << endl;
//
// write some information
//
{
const polyPatchList& patches = mesh.boundaryMesh();
Info<< "----------------" << nl
<< "Mesh Information" << nl
<< "----------------" << nl
<< " " << "boundingBox: " << boundBox(mesh.points()) << nl
<< " " << "nPoints: " << mesh.nPoints() << nl
<< " " << "nCells: " << mesh.nCells() << nl
<< " " << "nFaces: " << mesh.nFaces() << nl
<< " " << "nInternalFaces: " << mesh.nInternalFaces() << nl;
Info<< "----------------" << nl
<< "Patches" << nl
<< "----------------" << nl;
forAll(patches, patchI)
{
const polyPatch& p = patches[patchI];
Info<< " " << "patch " << patchI
<< " (start: " << p.start()
<< " size: " << p.size()
<< ") name: " << p.name()
<< nl;
}
}
Info<< "\nEnd\n" << endl;
return 0;
}

View file

@ -1,231 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
private member of block. Creates vertices for cells filling the block.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "block.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::block::blockPoints()
{
// set local variables for mesh specification
const label ni = blockDef_.n().x();
const label nj = blockDef_.n().y();
const label nk = blockDef_.n().z();
const point p000 = blockDef_.points()[blockDef_.blockShape()[0]];
const point p100 = blockDef_.points()[blockDef_.blockShape()[1]];
const point p110 = blockDef_.points()[blockDef_.blockShape()[2]];
const point p010 = blockDef_.points()[blockDef_.blockShape()[3]];
const point p001 = blockDef_.points()[blockDef_.blockShape()[4]];
const point p101 = blockDef_.points()[blockDef_.blockShape()[5]];
const point p111 = blockDef_.points()[blockDef_.blockShape()[6]];
const point p011 = blockDef_.points()[blockDef_.blockShape()[7]];
// list of edge point and weighting factors
const List<List<point> >& p = blockDef_.blockEdgePoints();
const scalarListList& w = blockDef_.blockEdgeWeights();
// generate vertices
for (label k = 0; k <= nk; k++)
{
for (label j = 0; j <= nj; j++)
{
for (label i = 0; i <= ni; i++)
{
label vertexNo = vtxLabel(i, j, k);
// points on edges
vector edgex1 = p000 + (p100 - p000)*w[0][i];
vector edgex2 = p010 + (p110 - p010)*w[1][i];
vector edgex3 = p011 + (p111 - p011)*w[2][i];
vector edgex4 = p001 + (p101 - p001)*w[3][i];
vector edgey1 = p000 + (p010 - p000)*w[4][j];
vector edgey2 = p100 + (p110 - p100)*w[5][j];
vector edgey3 = p101 + (p111 - p101)*w[6][j];
vector edgey4 = p001 + (p011 - p001)*w[7][j];
vector edgez1 = p000 + (p001 - p000)*w[8][k];
vector edgez2 = p100 + (p101 - p100)*w[9][k];
vector edgez3 = p110 + (p111 - p110)*w[10][k];
vector edgez4 = p010 + (p011 - p010)*w[11][k];
// calculate the importance factors for all edges
// x - direction
scalar impx1 =
(
(1.0 - w[0][i])*(1.0 - w[4][j])*(1.0 - w[8][k])
+ w[0][i]*(1.0 - w[5][j])*(1.0 - w[9][k])
);
scalar impx2 =
(
(1.0 - w[1][i])*w[4][j]*(1.0 - w[11][k])
+ w[1][i]*w[5][j]*(1.0 - w[10][k])
);
scalar impx3 =
(
(1.0 - w[2][i])*w[7][j]*w[11][k]
+ w[2][i]*w[6][j]*w[10][k]
);
scalar impx4 =
(
(1.0 - w[3][i])*(1.0 - w[7][j])*w[8][k]
+ w[3][i]*(1.0 - w[6][j])*w[9][k]
);
scalar magImpx = impx1 + impx2 + impx3 + impx4;
impx1 /= magImpx;
impx2 /= magImpx;
impx3 /= magImpx;
impx4 /= magImpx;
// y - direction
scalar impy1 =
(
(1.0 - w[4][j])*(1.0 - w[0][i])*(1.0 - w[8][k])
+ w[4][j]*(1.0 - w[1][i])*(1.0 - w[11][k])
);
scalar impy2 =
(
(1.0 - w[5][j])*w[0][i]*(1.0 - w[9][k])
+ w[5][j]*w[1][i]*(1.0 - w[10][k])
);
scalar impy3 =
(
(1.0 - w[6][j])*w[3][i]*w[9][k]
+ w[6][j]*w[2][i]*w[10][k]
);
scalar impy4 =
(
(1.0 - w[7][j])*(1.0 - w[3][i])*w[8][k]
+ w[7][j]*(1.0 - w[2][i])*w[11][k]
);
scalar magImpy = impy1 + impy2 + impy3 + impy4;
impy1 /= magImpy;
impy2 /= magImpy;
impy3 /= magImpy;
impy4 /= magImpy;
// z - direction
scalar impz1 =
(
(1.0 - w[8][k])*(1.0 - w[0][i])*(1.0 - w[4][j])
+ w[8][k]*(1.0 - w[3][i])*(1.0 - w[7][j])
);
scalar impz2 =
(
(1.0 - w[9][k])*w[0][i]*(1.0 - w[5][j])
+ w[9][k]*w[3][i]*(1.0 - w[6][j])
);
scalar impz3 =
(
(1.0 - w[10][k])*w[1][i]*w[5][j]
+ w[10][k]*w[2][i]*w[6][j]
);
scalar impz4 =
(
(1.0 - w[11][k])*(1.0 - w[1][i])*w[4][j]
+ w[11][k]*(1.0 - w[2][i])*w[7][j]
);
scalar magImpz = impz1 + impz2 + impz3 + impz4;
impz1 /= magImpz;
impz2 /= magImpz;
impz3 /= magImpz;
impz4 /= magImpz;
// calculate the correction vectors
vector corx1 = impx1*(p[0][i] - edgex1);
vector corx2 = impx2*(p[1][i] - edgex2);
vector corx3 = impx3*(p[2][i] - edgex3);
vector corx4 = impx4*(p[3][i] - edgex4);
vector cory1 = impy1*(p[4][j] - edgey1);
vector cory2 = impy2*(p[5][j] - edgey2);
vector cory3 = impy3*(p[6][j] - edgey3);
vector cory4 = impy4*(p[7][j] - edgey4);
vector corz1 = impz1*(p[8][k] - edgez1);
vector corz2 = impz2*(p[9][k] - edgez2);
vector corz3 = impz3*(p[10][k] - edgez3);
vector corz4 = impz4*(p[11][k] - edgez4);
// multiply by the importance factor
// x - direction
edgex1 *= impx1;
edgex2 *= impx2;
edgex3 *= impx3;
edgex4 *= impx4;
// y - direction
edgey1 *= impy1;
edgey2 *= impy2;
edgey3 *= impy3;
edgey4 *= impy4;
// z - direction
edgez1 *= impz1;
edgez2 *= impz2;
edgez3 *= impz3;
edgez4 *= impz4;
// add the contributions
vertices_[vertexNo] = edgex1 + edgex2 + edgex3 + edgex4;
vertices_[vertexNo] += edgey1 + edgey2 + edgey3 + edgey4;
vertices_[vertexNo] += edgez1 + edgez2 + edgez3 + edgez4;
vertices_[vertexNo] /= 3.0;
vertices_[vertexNo] += corx1 + corx2 + corx3 + corx4;
vertices_[vertexNo] += cory1 + cory2 + cory3 + cory4;
vertices_[vertexNo] += corz1 + corz2 + corz3 + corz4;
}
}
}
}
// ************************************************************************* //

View file

@ -1,144 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/
#include "blockMesh.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Check the blockMesh topology
void Foam::blockMesh::checkBlockMesh(const polyMesh& bm)
{
Info<< nl << "Check block mesh topology" << endl;
bool blockMeshOK = true;
const pointField& points = bm.points();
const faceList& faces = bm.faces();
const cellList& cells = bm.cells();
const polyPatchList& patches = bm.boundaryMesh();
label nBoundaryFaces=0;
forAll(cells, celli)
{
nBoundaryFaces += cells[celli].nFaces();
}
nBoundaryFaces -= 2*bm.nInternalFaces();
label nDefinedBoundaryFaces=0;
forAll(patches, patchi)
{
nDefinedBoundaryFaces += patches[patchi].size();
}
Info<< nl << tab << "Basic statistics" << endl;
Info<< tab << tab << "Number of internal faces : "
<< bm.nInternalFaces() << endl;
Info<< tab << tab << "Number of boundary faces : "
<< nBoundaryFaces << endl;
Info<< tab << tab << "Number of defined boundary faces : "
<< nDefinedBoundaryFaces << endl;
Info<< tab << tab << "Number of undefined boundary faces : "
<< nBoundaryFaces - nDefinedBoundaryFaces << endl;
if ((nBoundaryFaces - nDefinedBoundaryFaces) > 0)
{
Info<< tab << tab << tab
<< "(Warning : only leave undefined the front and back planes "
<< "of 2D planar geometries!)" << endl;
}
Info<< nl << tab << "Checking patch -> block consistency" << endl;
forAll(patches, patchi)
{
const faceList& Patch = patches[patchi];
forAll(Patch, patchFacei)
{
const face& patchFace = Patch[patchFacei];
bool patchFaceOK = false;
forAll(cells, celli)
{
const labelList& cellFaces = cells[celli];
forAll(cellFaces, cellFacei)
{
if (patchFace == faces[cellFaces[cellFacei]])
{
patchFaceOK = true;
if
(
(
patchFace.normal(points)
& faces[cellFaces[cellFacei]].normal(points)
) < 0.0
)
{
Info<< tab << tab
<< "Face " << patchFacei
<< " of patch " << patchi
<< " (" << patches[patchi].name() << ")"
<< " points inwards"
<< endl;
blockMeshOK = false;
}
}
}
}
if (!patchFaceOK)
{
Info<< tab << tab
<< "Face " << patchFacei
<< " of patch " << patchi
<< " (" << patches[patchi].name() << ")"
<< " does not match any block faces" << endl;
blockMeshOK = false;
}
}
}
if (!blockMeshOK)
{
FatalErrorIn("blockMesh::checkBlockMesh(const polyMesh& bm)")
<< "Block mesh topology incorrect, stopping mesh generation!"
<< exit(FatalError);
}
}
// ************************************************************************* //

View file

@ -1,73 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "blockMesh.H"
#include "cellModeller.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::cellShapeList Foam::blockMesh::createCells()
{
Info<< nl << "Creating cells" << endl;
PtrList<cellShape> cells(nCells_);
blockMesh& blocks = *this;
const cellModel& hex = *(cellModeller::lookup("hex"));
label cellLabel = 0;
forAll(blocks, blockLabel)
{
const labelListList& blockCells = blocks[blockLabel].cells();
forAll(blockCells, blockCellLabel)
{
labelList cellPoints(blockCells[blockCellLabel].size());
forAll(cellPoints, cellPointLabel)
{
cellPoints[cellPointLabel] =
mergeList_
[
blockCells[blockCellLabel][cellPointLabel]
+ blockOffsets_[blockLabel]
];
}
// Construct collapsed cell and all to list
cells.set(cellLabel, new cellShape(hex, cellPoints, true));
cellLabel++;
}
}
return cells;
}
// ************************************************************************* //

View file

@ -1,170 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/
#include "blockMesh.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::faceList Foam::blockMesh::createPatchFaces
(
const polyPatch& patchTopologyFaces
)
{
blockMesh& blocks = *this;
labelList blockLabels = patchTopologyFaces.polyPatch::faceCells();
label nFaces=0;
forAll(patchTopologyFaces, patchTopologyFaceLabel)
{
label blockLabel = blockLabels[patchTopologyFaceLabel];
faceList blockFaces
(
blocks[blockLabel].blockDef().blockShape().faces()
);
forAll(blockFaces, blockFaceLabel)
{
if
(
blockFaces[blockFaceLabel]
== patchTopologyFaces[patchTopologyFaceLabel]
)
{
nFaces +=
blocks[blockLabel].boundaryPatches()[blockFaceLabel].size();
}
}
}
faceList patchFaces(nFaces);
face quadFace(4);
label faceLabel = 0;
forAll(patchTopologyFaces, patchTopologyFaceLabel)
{
label blockLabel = blockLabels[patchTopologyFaceLabel];
faceList blockFaces
(
blocks[blockLabel].blockDef().blockShape().faces()
);
forAll(blockFaces, blockFaceLabel)
{
if
(
blockFaces[blockFaceLabel]
== patchTopologyFaces[patchTopologyFaceLabel]
)
{
const labelListList& blockPatchFaces =
blocks[blockLabel].boundaryPatches()[blockFaceLabel];
forAll(blockPatchFaces, blockFaceLabel)
{
// Lookup the face points
// and collapse duplicate point labels
quadFace[0] =
mergeList_
[
blockPatchFaces[blockFaceLabel][0]
+ blockOffsets_[blockLabel]
];
label nUnique = 1;
for
(
label facePointLabel = 1;
facePointLabel < 4;
facePointLabel++
)
{
quadFace[nUnique] =
mergeList_
[
blockPatchFaces[blockFaceLabel][facePointLabel]
+ blockOffsets_[blockLabel]
];
if (quadFace[nUnique] != quadFace[nUnique-1])
{
nUnique++;
}
}
if (quadFace[nUnique-1] == quadFace[0])
{
nUnique--;
}
if (nUnique == 4)
{
patchFaces[faceLabel++] = quadFace;
}
else if (nUnique == 3)
{
patchFaces[faceLabel++] = face
(
labelList::subList(quadFace, 3)
);
}
// else the face has collapsed to an edge or point
}
}
}
}
patchFaces.setSize(faceLabel);
return patchFaces;
}
Foam::faceListList Foam::blockMesh::createPatches()
{
Info<< "\nCreating patches\n";
const polyPatchList& patchTopologies = topology().boundaryMesh();
faceListList patches(patchTopologies.size());
forAll(patchTopologies, patchLabel)
{
patches[patchLabel] =
createPatchFaces(patchTopologies[patchLabel]);
}
return patches;
}
// ************************************************************************* //

View file

@ -1,443 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "blockMesh.H"
#include "Time.H"
#include "preservePatchTypes.H"
#include "emptyPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
bool Foam::blockMesh::blockLabelsOK
(
const label blockLabel,
const pointField& points,
const cellShape& blockShape
)
{
bool ok = true;
forAll(blockShape, blockI)
{
if (blockShape[blockI] < 0)
{
ok = false;
WarningIn
(
"bool Foam::blockMesh::blockLabelsOK"
"(const label blockLabel, const pointField& points, "
"const cellShape& blockShape)"
) << "block " << blockLabel
<< " point label " << blockShape[blockI]
<< " less than zero" << endl;
}
else if (blockShape[blockI] >= points.size())
{
ok = false;
WarningIn
(
"bool Foam::blockMesh::blockLabelsOK"
"(const label blockLabel, const pointField& points, "
"const cellShape& blockShape)"
) << "block " << blockLabel
<< " point label " << blockShape[blockI]
<< " larger than " << points.size() - 1
<< " the largest defined point label" << endl;
}
}
return ok;
}
bool Foam::blockMesh::patchLabelsOK
(
const label patchLabel,
const pointField& points,
const faceList& patchFaces
)
{
bool ok = true;
forAll(patchFaces, faceI)
{
const labelList& f = patchFaces[faceI];
forAll(f, fp)
{
if (f[fp] < 0)
{
ok = false;
WarningIn
(
"bool Foam::blockMesh::patchLabelsOK(...)"
) << "patch " << patchLabel
<< " face " << faceI
<< " point label " << f[fp]
<< " less than zero" << endl;
}
else if (f[fp] >= points.size())
{
ok = false;
WarningIn
(
"bool Foam::blockMesh::patchLabelsOK(...)"
) << "patch " << patchLabel
<< " face " << faceI
<< " point label " << f[fp]
<< " larger than " << points.size() - 1
<< " the largest defined point label" << endl;
}
}
}
return ok;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& meshDescription)
{
bool topologyOK = true;
blockMesh& blocks = *this;
word defaultPatchName = "defaultFaces";
word defaultPatchType = emptyPolyPatch::typeName;
// get names/types for the unassigned patch faces
// this is a bit heavy handed (and ugly), but there is currently
// no easy way to rename polyMesh patches subsequently
if (const dictionary* dictPtr = meshDescription.subDictPtr("defaultPatch"))
{
dictPtr->readIfPresent("name", defaultPatchName);
dictPtr->readIfPresent("type", defaultPatchType);
}
Info<< nl << "Creating blockCorners" << endl;
// create blockCorners
pointField tmpBlockPoints(meshDescription.lookup("vertices"));
if (meshDescription.found("edges"))
{
// read number of non-linear edges in mesh
Info<< nl << "Creating curved edges" << endl;
ITstream& edgesStream(meshDescription.lookup("edges"));
label nEdges = 0;
token firstToken(edgesStream);
if (firstToken.isLabel())
{
nEdges = firstToken.labelToken();
edges_.setSize(nEdges);
}
else
{
edgesStream.putBack(firstToken);
}
// Read beginning of edges
edgesStream.readBegin("edges");
nEdges = 0;
token lastToken(edgesStream);
while
(
!(
lastToken.isPunctuation()
&& lastToken.pToken() == token::END_LIST
)
)
{
if (edges_.size() <= nEdges)
{
edges_.setSize(nEdges + 1);
}
edgesStream.putBack(lastToken);
edges_.set
(
nEdges,
curvedEdge::New(tmpBlockPoints, edgesStream)
);
nEdges++;
edgesStream >> lastToken;
}
edgesStream.putBack(lastToken);
// Read end of edges
edgesStream.readEnd("edges");
}
else
{
Info<< nl << "There are no non-linear edges" << endl;
}
Info<< nl << "Creating blocks" << endl;
{
ITstream& blockDescriptorStream(meshDescription.lookup("blocks"));
// read number of blocks in mesh
label nBlocks = 0;
token firstToken(blockDescriptorStream);
if (firstToken.isLabel())
{
nBlocks = firstToken.labelToken();
blocks.setSize(nBlocks);
}
else
{
blockDescriptorStream.putBack(firstToken);
}
// Read beginning of blocks
blockDescriptorStream.readBegin("blocks");
nBlocks = 0;
token lastToken(blockDescriptorStream);
while
(
!(
lastToken.isPunctuation()
&& lastToken.pToken() == token::END_LIST
)
)
{
if (blocks.size() <= nBlocks)
{
blocks.setSize(nBlocks + 1);
}
blockDescriptorStream.putBack(lastToken);
blocks.set
(
nBlocks,
new block
(
blockDescriptor
(
tmpBlockPoints,
edges_,
blockDescriptorStream
)
)
);
topologyOK = topologyOK && blockLabelsOK
(
nBlocks,
tmpBlockPoints,
blocks[nBlocks].blockDef().blockShape()
);
nBlocks++;
blockDescriptorStream >> lastToken;
}
blockDescriptorStream.putBack(lastToken);
// Read end of blocks
blockDescriptorStream.readEnd("blocks");
}
Info<< nl << "Creating patches" << endl;
faceListList tmpBlocksPatches;
wordList patchNames;
wordList patchTypes;
{
ITstream& patchStream(meshDescription.lookup("patches"));
// read number of patches in mesh
label nPatches = 0;
token firstToken(patchStream);
if (firstToken.isLabel())
{
nPatches = firstToken.labelToken();
tmpBlocksPatches.setSize(nPatches);
patchNames.setSize(nPatches);
patchTypes.setSize(nPatches);
}
else
{
patchStream.putBack(firstToken);
}
// Read beginning of blocks
patchStream.readBegin("patches");
nPatches = 0;
token lastToken(patchStream);
while
(
!(
lastToken.isPunctuation()
&& lastToken.pToken() == token::END_LIST
)
)
{
if (tmpBlocksPatches.size() <= nPatches)
{
tmpBlocksPatches.setSize(nPatches + 1);
patchNames.setSize(nPatches + 1);
patchTypes.setSize(nPatches + 1);
}
patchStream.putBack(lastToken);
patchStream
>> patchTypes[nPatches]
>> patchNames[nPatches]
>> tmpBlocksPatches[nPatches];
// Catch multiple patches asap.
for (label i = 0; i < nPatches; i++)
{
if (patchNames[nPatches] == patchNames[i])
{
FatalErrorIn
(
"blockMesh::createTopology(IOdictionary&)"
) << "Duplicate patch " << patchNames[nPatches]
<< " at line " << patchStream.lineNumber()
<< ". Exiting !" << nl
<< exit(FatalError);
}
}
topologyOK = topologyOK && patchLabelsOK
(
nPatches,
tmpBlockPoints,
tmpBlocksPatches[nPatches]
);
nPatches++;
patchStream >> lastToken;
}
patchStream.putBack(lastToken);
// Read end of blocks
patchStream.readEnd("patches");
}
if (!topologyOK)
{
FatalErrorIn("blockMesh::createTopology(IOdictionary&)")
<< "Cannot create mesh due to errors in topology, exiting !" << nl
<< exit(FatalError);
}
Info<< nl << "Creating block mesh topology" << endl;
PtrList<cellShape> tmpBlockCells(blocks.size());
forAll(blocks, blockLabel)
{
tmpBlockCells.set
(
blockLabel,
new cellShape(blocks[blockLabel].blockDef().blockShape())
);
if (tmpBlockCells[blockLabel].mag(tmpBlockPoints) < 0.0)
{
WarningIn
(
"blockMesh::createTopology(IOdictionary&)"
) << "negative volume block : " << blockLabel
<< ", probably defined inside-out" << endl;
}
}
wordList patchPhysicalTypes(tmpBlocksPatches.size());
preservePatchTypes
(
meshDescription.time(),
meshDescription.time().constant(),
polyMesh::meshSubDir,
patchNames,
patchTypes,
defaultPatchName,
defaultPatchType,
patchPhysicalTypes
);
polyMesh* blockMeshPtr = new polyMesh
(
IOobject
(
"blockMesh",
meshDescription.time().constant(),
meshDescription.time(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
xferMove(tmpBlockPoints),
tmpBlockCells,
tmpBlocksPatches,
patchNames,
patchTypes,
defaultPatchName,
defaultPatchType,
patchPhysicalTypes
);
checkBlockMesh(*blockMeshPtr);
return blockMeshPtr;
}
// ************************************************************************* //

View file

@ -1,148 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "polySplineEdge.H"
#include "BSpline.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(polySplineEdge, 0);
// Add the curvedEdge constructor functions to the hash tables
curvedEdge::addIstreamConstructorToTable<polySplineEdge>
addPolySplineEdgeIstreamConstructorToTable_;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// intervening : returns a list of the points making up the polyLineEdge
// which describes the spline. nbetweenKnots is the number of points
// placed between each knot : this ensures that the knot locations
// are retained as a subset of the polyLine points.
// note that the points are evenly spaced in the parameter mu, not
// in real space
Foam::pointField Foam::polySplineEdge::intervening
(
const pointField& otherknots,
const label nbetweenKnots,
const vector& fstend,
const vector& sndend
)
{
BSpline spl(knotlist(points_, start_, end_, otherknots), fstend, sndend);
label nSize(nsize(otherknots.size(), nbetweenKnots));
pointField ans(nSize);
label N = spl.nKnots();
scalar init = 1.0/(N - 1);
scalar interval = (N - scalar(3))/N;
interval /= otherknots.size() + 1;
interval /= nbetweenKnots + 1;
ans[0] = points_[start_];
register scalar index(init);
for (register label i=1; i<nSize-1; i++)
{
index += interval;
ans[i] = spl.realPosition(index);
}
ans[nSize-1] = points_[end_];
return ans;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::polySplineEdge::polySplineEdge
(
const pointField& points,
const label start,
const label end,
const pointField& otherknots,
const label nInterKnots
)
:
curvedEdge(points, start, end),
polyLine
(
intervening
(
otherknots,
nInterKnots,
vector::zero,
vector::zero
)
),
otherKnots_(otherknots)
{}
Foam::polySplineEdge::polySplineEdge
(
const pointField& points,
Istream& is
)
:
curvedEdge(points, is),
polyLine(pointField(0)),
otherKnots_(is)
{
label nInterKnots(20);
vector fstend(is);
vector sndend(is);
controlPoints_.setSize(nsize(otherKnots_.size(), nInterKnots));
distances_.setSize(controlPoints_.size());
controlPoints_ = intervening(otherKnots_, nInterKnots, fstend, sndend);
calcDistances();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::vector Foam::polySplineEdge::position(const scalar mu) const
{
return polyLine::position(mu);
}
Foam::scalar Foam::polySplineEdge::length() const
{
return polyLine::length();
}
// ************************************************************************* //

View file

@ -0,0 +1,120 @@
if (mergePatchPairs.size())
{
Info<< "Creating merge patch pairs" << nl << endl;
// Create and add point and face zones and mesh modifiers
List<pointZone*> pz(mergePatchPairs.size());
List<faceZone*> fz(3*mergePatchPairs.size());
List<cellZone*> cz(0);
forAll(mergePatchPairs, pairI)
{
const word mergeName
(
mergePatchPairs[pairI].first()
+ mergePatchPairs[pairI].second()
+ name(pairI)
);
pz[pairI] = new pointZone
(
mergeName + "CutPointZone",
labelList(0),
0,
mesh.pointZones()
);
// Master patch
const word masterPatchName(mergePatchPairs[pairI].first());
const polyPatch& masterPatch =
mesh.boundaryMesh()[masterPatchName];
labelList isf(masterPatch.size());
forAll(isf, i)
{
isf[i] = masterPatch.start() + i;
}
fz[3*pairI] = new faceZone
(
mergeName + "MasterZone",
isf,
boolList(masterPatch.size(), false),
0,
mesh.faceZones()
);
// Slave patch
const word slavePatchName(mergePatchPairs[pairI].second());
const polyPatch& slavePatch =
mesh.boundaryMesh()[slavePatchName];
labelList osf(slavePatch.size());
forAll(osf, i)
{
osf[i] = slavePatch.start() + i;
}
fz[3*pairI + 1] = new faceZone
(
mergeName + "SlaveZone",
osf,
boolList(slavePatch.size(), false),
1,
mesh.faceZones()
);
// Add empty zone for cut faces
fz[3*pairI + 2] = new faceZone
(
mergeName + "CutFaceZone",
labelList(0),
boolList(0, false),
2,
mesh.faceZones()
);
} // end of all merge pairs
Info<< "Adding point and face zones" << endl;
mesh.addZones(pz, fz, cz);
Info<< "Creating attachPolyTopoChanger" << endl;
polyTopoChanger polyMeshAttacher(mesh);
polyMeshAttacher.setSize(mergePatchPairs.size());
forAll(mergePatchPairs, pairI)
{
const word mergeName
(
mergePatchPairs[pairI].first()
+ mergePatchPairs[pairI].second()
+ name(pairI)
);
// Add the sliding interface mesh modifier
polyMeshAttacher.set
(
pairI,
new slidingInterface
(
"couple" + name(pairI),
pairI,
polyMeshAttacher,
mergeName + "MasterZone",
mergeName + "SlaveZone",
mergeName + "CutPointZone",
mergeName + "CutFaceZone",
mergePatchPairs[pairI].first(),
mergePatchPairs[pairI].second(),
slidingInterface::INTEGRAL, // always integral
false,
intersection::VISIBLE
)
);
}
polyMeshAttacher.changeMesh();
}

View file

@ -0,0 +1,271 @@
// Read in a list of dictionaries for the merge patch pairs
if (meshDict.found("mergePatchPairs"))
{
List<Pair<word> > mergePatchPairs
(
meshDict.lookup("mergePatchPairs")
);
if (mergePatchPairs.size() > 0)
{
// Create and add point and face zones and mesh modifiers
List<pointZone*> pz(mergePatchPairs.size());
List<faceZone*> fz(3*mergePatchPairs.size());
List<cellZone*> cz(0);
forAll (mergePatchPairs, pairI)
{
const word mergeName
(
mergePatchPairs[pairI].first()
+ mergePatchPairs[pairI].second()
+ name(pairI)
);
pz[pairI] = new pointZone
(
mergeName + "CutPointZone",
labelList(0),
0,
mesh.pointZones()
);
// Master patch
const word masterPatchName(mergePatchPairs[pairI].first());
const polyPatch& masterPatch =
mesh.boundaryMesh()
[
mesh.boundaryMesh().findPatchID(masterPatchName)
];
labelList isf(masterPatch.size());
forAll (isf, i)
{
isf[i] = masterPatch.start() + i;
}
fz[3*pairI] = new faceZone
(
mergeName + "MasterZone",
isf,
boolList(masterPatch.size(), false),
0,
mesh.faceZones()
);
// Slave patch
const word slavePatchName(mergePatchPairs[pairI].second());
const polyPatch& slavePatch =
mesh.boundaryMesh()
[
mesh.boundaryMesh().findPatchID(slavePatchName)
];
labelList osf(slavePatch.size());
forAll (osf, i)
{
osf[i] = slavePatch.start() + i;
}
fz[3*pairI + 1] = new faceZone
(
mergeName + "SlaveZone",
osf,
boolList(slavePatch.size(), false),
1,
mesh.faceZones()
);
// Add empty zone for cut faces
fz[3*pairI + 2] = new faceZone
(
mergeName + "CutFaceZone",
labelList(0),
boolList(0, false),
2,
mesh.faceZones()
);
} // end of all merge pairs
Info << "Adding point and face zones" << endl;
mesh.addZones(pz, fz, cz);
Info << "Creating topo change" << endl;
polyTopoChanger attacher(mesh);
attacher.setSize(mergePatchPairs.size());
forAll (mergePatchPairs, pairI)
{
const word mergeName
(
mergePatchPairs[pairI].first()
+ mergePatchPairs[pairI].second()
+ name(pairI)
);
// Add the sliding interface mesh modifier
attacher.set
(
pairI,
new slidingInterface
(
"couple" + name(pairI),
pairI,
attacher,
mergeName + "MasterZone",
mergeName + "SlaveZone",
mergeName + "CutPointZone",
mergeName + "CutFaceZone",
mergePatchPairs[pairI].first(),
mergePatchPairs[pairI].second(),
slidingInterface::INTEGRAL, // always integral
intersection::VISIBLE
)
);
}
attacher.changeMesh();
// Clean the mesh after attach
labelList patchSizes(mesh.boundaryMesh().size());
labelList patchStarts(mesh.boundaryMesh().size());
forAll (mesh.boundaryMesh(), patchI)
{
patchSizes[patchI] = mesh.boundaryMesh()[patchI].size();
patchStarts[patchI] = mesh.boundaryMesh()[patchI].start();
}
mesh.resetPrimitives
(
xferCopy<pointField>(mesh.points()),
xferCopy<faceList>(mesh.faces()),
xferCopy<labelList>(mesh.faceOwner()),
xferCopy<labelList>(mesh.faceNeighbour()),
patchSizes,
patchStarts
);
mesh.setInstance(runTime.constant());
mesh.removeZones();
}
}
else
{
Info<< nl << "There are no merge patch pairs" << endl;
}
// Set any cellZones (note: cell labelling unaffected by above
// mergePatchPairs)
label nZones = blocks.numZonedBlocks();
if (nZones > 0)
{
Info<< nl << "Adding cell zones" << endl;
// Map from zoneName to cellZone index
HashTable<label> zoneMap(nZones);
// Cells per zone.
List<DynamicList<label> > zoneCells(nZones);
// Running cell counter
label cellI = 0;
// Largest zone so far
label freeZoneI = 0;
forAll(blocks, blockI)
{
const block& b = blocks[blockI];
const labelListList& blockCells = b.cells();
const word& zoneName = b.blockDef().zoneName();
if (zoneName.size())
{
HashTable<label>::const_iterator iter = zoneMap.find(zoneName);
label zoneI;
if (iter == zoneMap.end())
{
zoneI = freeZoneI++;
Info<< " " << zoneI << '\t' << zoneName << endl;
zoneMap.insert(zoneName, zoneI);
}
else
{
zoneI = iter();
}
forAll(blockCells, i)
{
zoneCells[zoneI].append(cellI++);
}
}
else
{
cellI += b.cells().size();
}
}
List<cellZone*> cz(zoneMap.size());
Info<< nl << "Writing cell zones as cellSets" << endl;
forAllConstIter(HashTable<label>, zoneMap, iter)
{
label zoneI = iter();
cz[zoneI]= new cellZone
(
iter.key(),
zoneCells[zoneI].shrink(),
zoneI,
mesh.cellZones()
);
// Write as cellSet for ease of processing
cellSet cset
(
mesh,
iter.key(),
labelHashSet(zoneCells[zoneI].shrink())
);
cset.write();
}
mesh.pointZones().setSize(0);
mesh.faceZones().setSize(0);
mesh.cellZones().setSize(0);
mesh.addZones(List<pointZone*>(0), List<faceZone*>(0), cz);
}
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
Info << nl << "Writing polyMesh" << endl;
mesh.removeFiles();
if (!mesh.write())
{
FatalErrorIn(args.executable())
<< "Failed writing polyMesh."
<< exit(FatalError);
}
Info<< nl << "End" << endl;
return 0;
}
// ************************************************************************* //

View file

@ -1,147 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
from the list of curved edges creates a list
of edges that are not curved. It is assumed
that all other edges are straight lines
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "blockDescriptor.H"
#include "lineEdge.H"
#include "lineDivide.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scalar calcGexp(const scalar expRatio, const label dim)
{
if (dim == 1)
{
return 0.0;
}
else
{
return pow(expRatio, 1.0/(dim - 1));
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void blockDescriptor::setEdge(label edgeI, label start, label end, label dim)
{
// for all edges check the list of curved edges. If the edge is curved,
// add it to the list. If the edge is not found, create is as a line
bool found = false;
// set reference to the list of labels defining the block
const labelList& blockLabels = blockShape_;
// set reference to global list of points
const pointField blockPoints = blockShape_.points(blockMeshPoints_);
// x1
found = false;
forAll (curvedEdges_, nCEI)
{
if (curvedEdges_[nCEI].compare(blockLabels[start], blockLabels[end]))
{
found = true;
// check the orientation:
// if the starting point of the curve is the same as the starting
// point of the edge, do the parametrisation and pick up the points
if (blockLabels[start] == curvedEdges_[nCEI].start())
{
// calculate the geometric expension factor out of the
// expansion ratio
scalar gExp = calcGexp(expand_[edgeI], dim);
// divide the line
lineDivide divEdge(curvedEdges_[nCEI], dim, gExp);
edgePoints_[edgeI] = divEdge.points();
edgeWeights_[edgeI] = divEdge.lambdaDivisions();
}
else
{
// the curve has got the opposite orientation
scalar gExp = calcGexp(expand_[edgeI], dim);
// divide the line
lineDivide divEdge(curvedEdges_[nCEI], dim, 1.0/(gExp + SMALL));
pointField p = divEdge.points();
scalarList d = divEdge.lambdaDivisions();
edgePoints_[edgeI].setSize(p.size());
edgeWeights_[edgeI].setSize(d.size());
label pMax = p.size() - 1;
forAll (p, pI)
{
edgePoints_[edgeI][pI] = p[pMax - pI];
edgeWeights_[edgeI][pI] = 1.0 - d[pMax - pI];
}
}
break;
}
}
if (!found)
{
// edge is a straight line
scalar gExp = calcGexp(expand_[edgeI], dim);
// Divide the line
lineEdge le(blockPoints, start, end);
lineDivide divEdge
(
le,
dim,
gExp
);
edgePoints_[edgeI] = divEdge.points();
edgeWeights_[edgeI] = divEdge.lambdaDivisions();
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -51,6 +51,7 @@ wmake libso sampling
wmake libso ODE
wmake libso POD
wmake libso randomProcesses
mesh/Allwmake
thermophysicalModels/Allwmake
transportModels/Allwmake

View file

@ -1017,4 +1017,34 @@ int Foam::system(const string& command)
}
void Foam::osRandomSeed(const label seed)
{
#ifdef USE_RANDOM
srandom((unsigned int)seed);
#else
srand48(seed);
#endif
}
Foam::label Foam::osRandomInteger()
{
#ifdef USE_RANDOM
return random();
#else
return lrand48();
#endif
}
Foam::scalar Foam::osRandomDouble()
{
#ifdef USE_RANDOM
return (scalar)random()/INT_MAX;
#else
return drand48();
#endif
}
// ************************************************************************* //

View file

@ -303,15 +303,13 @@ void Foam::meshReader::createPolyBoundary()
Info<< "Added " << nMissingFaces << " unmatched faces" << endl;
// Add missing faces to last patch ('Default_Empty' etc.)
if (nMissingFaces > 0)
{
patchSizes_[patchSizes_.size() - 1] = nMissingFaces;
}
else
{
patchStarts_.setSize(patchStarts_.size() - 1);
patchSizes_.last() = nMissingFaces;
}
// reset the size of the face list
meshFaces_.setSize(nCreatedFaces);
@ -412,6 +410,8 @@ Foam::meshReader::polyBoundaryPatches(const polyMesh& mesh)
List<polyPatch*> p(nPatches);
// All patch dictionaries
PtrList<dictionary> patchDicts(patchNames_.size());
// Default boundary patch types
word defaultFacesType(emptyPolyPatch::typeName);
@ -422,20 +422,37 @@ Foam::meshReader::polyBoundaryPatches(const polyMesh& mesh)
mesh.instance(),
mesh.meshDir(),
patchNames_,
patchTypes_,
patchDicts,
"defaultFaces",
defaultFacesType,
patchPhysicalTypes_
defaultFacesType
);
forAll(patchDicts, patchI)
{
if (!patchDicts.set(patchI))
{
patchDicts.set(patchI, new dictionary());
}
dictionary& patchDict = patchDicts[patchI];
// add but not overwrite type
patchDict.add("type", patchTypes_[patchI], false);
if (patchPhysicalTypes_.size() && patchPhysicalTypes_[patchI].size())
{
patchDict.add("startFace", patchPhysicalTypes_[patchI], false);
}
// overwrite sizes and start
patchDict.add("nFaces", patchSizes_[patchI], true);
patchDict.add("startFace", patchStarts_[patchI], true);
}
forAll(patchStarts_, patchI)
{
p[patchI] = polyPatch::New
(
patchTypes_[patchI],
patchNames_[patchI],
patchSizes_[patchI],
patchStarts_[patchI],
patchDicts[patchI],
patchI,
mesh.boundaryMesh()
).ptr();

View file

@ -167,6 +167,18 @@ public:
// This can be used (with caution) when interfacing with C code.
inline T* data();
//- Return the first element of the list.
inline T& first();
//- Return first element of the list.
inline const T& first() const;
//- Return the last element of the list.
inline T& last();
//- Return the last element of the list.
inline const T& last() const;
// Check

View file

@ -128,6 +128,34 @@ inline void Foam::UList<T>::checkIndex(const label i) const
}
template<class T>
inline T& Foam::UList<T>::first()
{
return this->operator[](0);
}
template<class T>
inline const T& Foam::UList<T>::first() const
{
return this->operator[](0);
}
template<class T>
inline T& Foam::UList<T>::last()
{
return this->operator[](this->size()-1);
}
template<class T>
inline const T& Foam::UList<T>::last() const
{
return this->operator[](this->size()-1);
}
template<class T>
inline const T* Foam::UList<T>::cdata() const
{

View file

@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InNamespace
Foam
Description
Unit conversion functions
\*---------------------------------------------------------------------------*/
#ifndef unitConversion_H
#define unitConversion_H
#include "mathematicalConstants.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Conversion from degrees to radians
inline scalar degToRad(const scalar deg)
{
return (deg*mathematicalConstant::pi/180.0);
}
//- Conversion from radians to degrees
inline scalar radToDeg(const scalar rad)
{
return (rad*180.0/mathematicalConstant::pi);
}
//- Conversion from atm to Pa
inline scalar atmToPa(const scalar atm)
{
return (atm*101325.0);
}
//- Conversion from atm to Pa
inline scalar paToAtm(const scalar pa)
{
return (pa/101325.0);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -171,6 +171,17 @@ bool ping(const word&, const label timeOut = 10);
//- Execute the specified command
int system(const string& command);
// Low level random numbers. Use Random class instead.
//- Seed random number generator.
void osRandomSeed(const label seed);
//- Return random integer (uniform distribution between 0 and 2^31)
label osRandomInteger();
//- Return random double precision (uniform distribution between 0 and 1)
scalar osRandomDouble();
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View file

@ -699,6 +699,49 @@ bool Foam::polyBoundaryMesh::writeObject
return regIOobject::writeObject(fmt, ver, IOstream::UNCOMPRESSED);
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
const Foam::polyPatch& Foam::polyBoundaryMesh::operator[]
(
const word& patchName
) const
{
const label patchI = findPatchID(patchName);
if (patchI < 0)
{
FatalErrorIn
(
"polyBoundaryMesh::operator[](const word&) const"
) << "Patch named " << patchName << " not found." << nl
<< "Available patch names: " << names() << endl
<< abort(FatalError);
}
return operator[](patchI);
}
Foam::polyPatch& Foam::polyBoundaryMesh::operator[]
(
const word& patchName
)
{
const label patchI = findPatchID(patchName);
if (patchI < 0)
{
FatalErrorIn
(
"polyBoundaryMesh::operator[](const word&)"
) << "Patch named " << patchName << " not found." << nl
<< "Available patch names: " << names() << endl
<< abort(FatalError);
}
return operator[](patchI);
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //

View file

@ -197,6 +197,18 @@ public:
) const;
// Member Operators
//- Return const and non-const reference to polyPatch by index.
using polyPatchList::operator[];
//- Return const reference to polyPatch by name.
const polyPatch& operator[](const word&) const;
//- Return reference to polyPatch by name.
polyPatch& operator[](const word&);
// Ostream operator
friend Ostream& operator<<(Ostream&, const polyBoundaryMesh&);

View file

@ -30,8 +30,10 @@ License
#include "emptyPolyPatch.H"
#include "globalMeshData.H"
#include "processorPolyPatch.H"
#include "meshObjectBase.H"
#include "demandDrivenData.H"
#include "indexedOctree.H"
#include "treeDataCell.H"
#include "MeshObject.H"
#include "pointMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -1337,4 +1339,36 @@ void Foam::polyMesh::removeFiles() const
}
Foam::label Foam::polyMesh::findCell
(
const point& location
) const
{
if (nCells() == 0)
{
return -1;
}
// Find the nearest cell centre to this location
label cellI = findNearestCell(location);
// If point is in the nearest cell return
if (pointInCell(location, cellI))
{
return cellI;
}
else // point is not in the nearest cell so search all cells
{
for (label cellI = 0; cellI < nCells(); cellI++)
{
if (pointInCell(location, cellI))
{
return cellI;
}
}
return -1;
}
}
// ************************************************************************* //

View file

@ -60,6 +60,7 @@ SourceFiles
namespace Foam
{
// Forward declaration of classes
class globalMeshData;
class mapPolyMesh;
@ -202,6 +203,17 @@ private:
const label patchID
) const;
void setTopology
(
const cellShapeList& cellsAsShapes,
const faceListList& boundaryFaces,
const wordList& boundaryPatchNames,
labelList& patchSizes,
labelList& patchStarts,
label& defaultPatchStart,
label& nFaces,
cellList& cells
);
public:
@ -264,6 +276,20 @@ public:
const bool syncPar = true
);
//- Construct from cell shapes with patch information in dictionary
// format.
polyMesh
(
const IOobject& io,
const Xfer<pointField>& points,
const cellShapeList& shapes,
const faceListList& boundaryFaces,
const wordList& boundaryPatchNames,
const PtrList<dictionary>& boundaryDicts,
const word& defaultBoundaryPatchName,
const word& defaultBoundaryPatchType,
const bool syncPar = true
);
// Destructor
@ -521,6 +547,14 @@ public:
//- Remove all files from mesh instance()
void removeFiles() const;
// Helper functions
//- Find cell enclosing this location (-1 if not in mesh)
label findCell
(
const point&
) const;
};

View file

@ -132,6 +132,292 @@ Foam::labelList Foam::polyMesh::facePatchFaceCells
}
//- Set faces_, calculate cells and patchStarts.
void Foam::polyMesh::setTopology
(
const cellShapeList& cellsAsShapes,
const faceListList& boundaryFaces,
const wordList& boundaryPatchNames,
labelList& patchSizes,
labelList& patchStarts,
label& defaultPatchStart,
label& nFaces,
cellList& cells
)
{
// Calculate the faces of all cells
// Initialise maximum possible numer of mesh faces to 0
label maxFaces = 0;
// Set up a list of face shapes for each cell
faceListList cellsFaceShapes(cellsAsShapes.size());
cells.setSize(cellsAsShapes.size());
forAll(cellsFaceShapes, cellI)
{
cellsFaceShapes[cellI] = cellsAsShapes[cellI].faces();
cells[cellI].setSize(cellsFaceShapes[cellI].size());
// Initialise cells to -1 to flag undefined faces
static_cast<labelList&>(cells[cellI]) = -1;
// Count maximum possible numer of mesh faces
maxFaces += cellsFaceShapes[cellI].size();
}
// Set size of faces array to maximum possible number of mesh faces
allFaces_.setSize(maxFaces);
// Initialise number of faces to 0
nFaces = 0;
// set reference to point-cell addressing
labelListList PointCells = cellShapePointCells(cellsAsShapes);
bool found = false;
forAll(cells, cellI)
{
// Note:
// Insertion cannot be done in one go as the faces need to be
// added into the list in the increasing order of neighbour
// cells. Therefore, all neighbours will be detected first
// and then added in the correct order.
const faceList& curFaces = cellsFaceShapes[cellI];
// Record the neighbour cell
labelList neiCells(curFaces.size(), -1);
// Record the face of neighbour cell
labelList faceOfNeiCell(curFaces.size(), -1);
label nNeighbours = 0;
// For all faces ...
forAll(curFaces, faceI)
{
// Skip faces that have already been matched
if (cells[cellI][faceI] >= 0) continue;
found = false;
const face& curFace = curFaces[faceI];
// Get the list of labels
const labelList& curPoints = curFace;
// For all points
forAll(curPoints, pointI)
{
// Get the list of cells sharing this point
const labelList& curNeighbours =
PointCells[curPoints[pointI]];
// For all neighbours
forAll(curNeighbours, neiI)
{
label curNei = curNeighbours[neiI];
// Reject neighbours with the lower label
if (curNei > cellI)
{
// Get the list of search faces
const faceList& searchFaces = cellsFaceShapes[curNei];
forAll(searchFaces, neiFaceI)
{
if (searchFaces[neiFaceI] == curFace)
{
// Match!!
found = true;
// Record the neighbour cell and face
neiCells[faceI] = curNei;
faceOfNeiCell[faceI] = neiFaceI;
nNeighbours++;
break;
}
}
if (found) break;
}
// if (found) break; HJ, not needed. Never true
}
if (found) break;
} // End of current points
} // End of current faces
// Add the faces in the increasing order of neighbours
for (label neiSearch = 0; neiSearch < nNeighbours; neiSearch++)
{
// Find the lowest neighbour which is still valid
label nextNei = -1;
label minNei = cells.size();
forAll (neiCells, ncI)
{
if (neiCells[ncI] > -1 && neiCells[ncI] < minNei)
{
nextNei = ncI;
minNei = neiCells[ncI];
}
}
if (nextNei > -1)
{
// Add the face to the list of faces
allFaces_[nFaces] = curFaces[nextNei];
// Set cell-face and cell-neighbour-face to current face label
cells[cellI][nextNei] = nFaces;
cells[neiCells[nextNei]][faceOfNeiCell[nextNei]] = nFaces;
// Stop the neighbour from being used again
neiCells[nextNei] = -1;
// Increment number of faces counter
nFaces++;
}
else
{
FatalErrorIn
(
"polyMesh::setTopology\n"
"(\n"
" const cellShapeList& cellsAsShapes,\n"
" const faceListList& boundaryFaces,\n"
" const wordList& boundaryPatchNames,\n"
" labelList& patchSizes,\n"
" labelList& patchStarts,\n"
" label& defaultPatchStart,\n"
" label& nFaces,\n"
" cellList& cells\n"
")"
) << "Error in internal face insertion"
<< abort(FatalError);
}
}
}
// Do boundary faces
patchSizes.setSize(boundaryFaces.size(), -1);
patchStarts.setSize(boundaryFaces.size(), -1);
forAll (boundaryFaces, patchI)
{
const faceList& patchFaces = boundaryFaces[patchI];
labelList curPatchFaceCells =
facePatchFaceCells
(
patchFaces,
PointCells,
cellsFaceShapes,
patchI
);
// Grab the start label
label curPatchStart = nFaces;
forAll (patchFaces, faceI)
{
const face& curFace = patchFaces[faceI];
const label cellInside = curPatchFaceCells[faceI];
allFaces_[nFaces] = curFace;
// get faces of the cell inside
const faceList& facesOfCellInside = cellsFaceShapes[cellInside];
bool found = false;
forAll (facesOfCellInside, cellFaceI)
{
if (facesOfCellInside[cellFaceI] == curFace)
{
if (cells[cellInside][cellFaceI] >= 0)
{
FatalErrorIn
(
"polyMesh::setTopology\n"
"(\n"
" const cellShapeList& cellsAsShapes,\n"
" const faceListList& boundaryFaces,\n"
" const wordList& boundaryPatchNames,\n"
" labelList& patchSizes,\n"
" labelList& patchStarts,\n"
" label& defaultPatchStart,\n"
" label& nFaces,\n"
" cellList& cells\n"
")"
) << "Trying to specify a boundary face " << curFace
<< " on the face on cell " << cellInside
<< " which is either an internal face or already "
<< "belongs to some other patch. This is face "
<< faceI << " of patch "
<< patchI << " named "
<< boundaryPatchNames[patchI] << "."
<< abort(FatalError);
}
found = true;
cells[cellInside][cellFaceI] = nFaces;
break;
}
}
if (!found)
{
FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
<< "face " << faceI << " of patch " << patchI
<< " does not seem to belong to cell " << cellInside
<< " which, according to the addressing, "
<< "should be next to it."
<< abort(FatalError);
}
// increment the counter of faces
nFaces++;
}
patchSizes[patchI] = nFaces - curPatchStart;
patchStarts[patchI] = curPatchStart;
}
// Grab "non-existing" faces and put them into a default patch
defaultPatchStart = nFaces;
forAll(cells, cellI)
{
labelList& curCellFaces = cells[cellI];
forAll(curCellFaces, faceI)
{
if (curCellFaces[faceI] == -1) // "non-existent" face
{
curCellFaces[faceI] = nFaces;
allFaces_[nFaces] = cellsFaceShapes[cellI][faceI];
nFaces++;
}
}
}
// Reset the size of the face list
allFaces_.setSize(nFaces);
faces_.reset(allFaces_, nFaces);
return ;
}
Foam::polyMesh::polyMesh
(
const IOobject& io,
@ -278,278 +564,27 @@ Foam::polyMesh::polyMesh
// Remove all of the old mesh files if they exist
removeFiles(instance());
// Calculate the faces of all cells
// Initialise maximum possible numer of mesh faces to 0
label maxFaces = 0;
// Set up a list of face shapes for each cell
faceListList cellsFaceShapes(cellsAsShapes.size());
cellList cells(cellsAsShapes.size());
forAll(cellsFaceShapes, cellI)
{
cellsFaceShapes[cellI] = cellsAsShapes[cellI].faces();
cells[cellI].setSize(cellsFaceShapes[cellI].size());
// Initialise cells to -1 to flag undefined faces
static_cast<labelList&>(cells[cellI]) = -1;
// Count maximum possible numer of mesh faces
maxFaces += cellsFaceShapes[cellI].size();
}
// Set size of faces array to maximum possible number of mesh faces
allFaces_.setSize(maxFaces);
// Initialise number of faces to 0
label nFaces = 0;
// set reference to point-cell addressing
labelListList PointCells = cellShapePointCells(cellsAsShapes);
bool found = false;
forAll(cells, cellI)
{
// Note:
// Insertion cannot be done in one go as the faces need to be
// added into the list in the increasing order of neighbour
// cells. Therefore, all neighbours will be detected first
// and then added in the correct order.
const faceList& curFaces = cellsFaceShapes[cellI];
// Record the neighbour cell
labelList neiCells(curFaces.size(), -1);
// Record the face of neighbour cell
labelList faceOfNeiCell(curFaces.size(), -1);
label nNeighbours = 0;
// For all faces ...
forAll(curFaces, faceI)
{
// Skip faces that have already been matched
if (cells[cellI][faceI] >= 0) continue;
found = false;
const face& curFace = curFaces[faceI];
// Get the list of labels
const labelList& curPoints = curFace;
// For all points
forAll(curPoints, pointI)
{
// Get the list of cells sharing this point
const labelList& curNeighbours =
PointCells[curPoints[pointI]];
// For all neighbours
forAll(curNeighbours, neiI)
{
label curNei = curNeighbours[neiI];
// Reject neighbours with the lower label
if (curNei > cellI)
{
// Get the list of search faces
const faceList& searchFaces = cellsFaceShapes[curNei];
forAll(searchFaces, neiFaceI)
{
if (searchFaces[neiFaceI] == curFace)
{
// Match!!
found = true;
// Record the neighbour cell and face
neiCells[faceI] = curNei;
faceOfNeiCell[faceI] = neiFaceI;
nNeighbours++;
break;
}
}
if (found) break;
}
// if (found) break; HJ, not needed. Never true
}
if (found) break;
} // End of current points
} // End of current faces
// Add the faces in the increasing order of neighbours
for (label neiSearch = 0; neiSearch < nNeighbours; neiSearch++)
{
// Find the lowest neighbour which is still valid
label nextNei = -1;
label minNei = cells.size();
forAll (neiCells, ncI)
{
if (neiCells[ncI] > -1 && neiCells[ncI] < minNei)
{
nextNei = ncI;
minNei = neiCells[ncI];
}
}
if (nextNei > -1)
{
// Add the face to the list of faces
allFaces_[nFaces] = curFaces[nextNei];
// Set cell-face and cell-neighbour-face to current face label
cells[cellI][nextNei] = nFaces;
cells[neiCells[nextNei]][faceOfNeiCell[nextNei]] = nFaces;
// Stop the neighbour from being used again
neiCells[nextNei] = -1;
// Increment number of faces counter
nFaces++;
}
else
{
FatalErrorIn
(
"polyMesh::polyMesh\n"
"(\n"
" const IOobject&,\n"
" const Xfer<pointField>&,\n"
" const cellShapeList& cellsAsShapes,\n"
" const faceListList& boundaryFaces,\n"
" const wordList& boundaryPatchTypes,\n"
" const wordList& boundaryPatchNames,\n"
" const word& defaultBoundaryPatchType\n"
")"
) << "Error in internal face insertion"
<< abort(FatalError);
}
}
}
// Do boundary faces
labelList patchSizes(boundaryFaces.size(), -1);
labelList patchStarts(boundaryFaces.size(), -1);
forAll (boundaryFaces, patchI)
{
const faceList& patchFaces = boundaryFaces[patchI];
labelList curPatchFaceCells =
facePatchFaceCells
(
patchFaces,
PointCells,
cellsFaceShapes,
patchI
);
// Grab the start label
label curPatchStart = nFaces;
forAll (patchFaces, faceI)
{
const face& curFace = patchFaces[faceI];
const label cellInside = curPatchFaceCells[faceI];
allFaces_[nFaces] = curFace;
// get faces of the cell inside
const faceList& facesOfCellInside = cellsFaceShapes[cellInside];
bool found = false;
forAll (facesOfCellInside, cellFaceI)
{
if (facesOfCellInside[cellFaceI] == curFace)
{
if (cells[cellInside][cellFaceI] >= 0)
{
FatalErrorIn
(
"polyMesh::polyMesh\n"
"(\n"
" const IOobject&,\n"
" const Xfer<pointField>&,\n"
" const cellShapeList& cellsAsShapes,\n"
" const faceListList& boundaryFaces,\n"
" const wordList& boundaryPatchTypes,\n"
" const wordList& boundaryPatchNames,\n"
" const word& defaultBoundaryPatchType\n"
")"
) << "Trying to specify a boundary face " << curFace
<< " on the face on cell " << cellInside
<< " which is either an internal face or already "
<< "belongs to some other patch. This is face "
<< faceI << " of patch "
<< patchI << " named "
<< boundaryPatchNames[patchI] << "."
<< abort(FatalError);
}
found = true;
cells[cellInside][cellFaceI] = nFaces;
break;
}
}
if (!found)
{
FatalErrorIn
(
"polyMesh::polyMesh(... construct from shapes...)"
) << "face " << faceI << " of patch " << patchI
<< " does not seem to belong to cell " << cellInside
<< " which, according to the addressing, "
<< "should be next to it."
<< abort(FatalError);
}
// increment the counter of faces
nFaces++;
}
patchSizes[patchI] = nFaces - curPatchStart;
patchStarts[patchI] = curPatchStart;
}
// Grab "non-existing" faces and put them into a default patch
label defaultPatchStart = nFaces;
forAll(cells, cellI)
{
labelList& curCellFaces = cells[cellI];
forAll(curCellFaces, faceI)
{
if (curCellFaces[faceI] == -1) // "non-existent" face
{
curCellFaces[faceI] = nFaces;
allFaces_[nFaces] = cellsFaceShapes[cellI][faceI];
nFaces++;
}
}
}
// Reset the size of the face list
allFaces_.setSize(nFaces);
faces_.reset(allFaces_, nFaces);
// Calculate faces and cells
labelList patchSizes;
labelList patchStarts;
label defaultPatchStart;
label nFaces;
cellList cells;
setTopology
(
cellsAsShapes,
boundaryFaces,
boundaryPatchNames,
patchSizes,
patchStarts,
defaultPatchStart,
nFaces,
cells
);
// Warning: Patches can only be added once the face list is
// completed, as they hold a subList of the face list
forAll (boundaryFaces, patchI)
forAll(boundaryFaces, patchI)
{
// add the patch to the list
boundary_.set
@ -579,27 +614,346 @@ Foam::polyMesh::polyMesh
label nAllPatches = boundaryFaces.size();
if (nFaces > defaultPatchStart)
label nDefaultFaces = nFaces - defaultPatchStart;
if (syncPar)
{
reduce(nDefaultFaces, sumOp<label>());
}
if (nDefaultFaces > 0)
{
WarningIn("polyMesh::polyMesh(... construct from shapes...)")
<< "Found " << nFaces - defaultPatchStart
<< "Found " << nDefaultFaces
<< " undefined faces in mesh; adding to default patch." << endl;
// Check if there already exists a defaultFaces patch as last patch
// and reuse it.
label patchI = findIndex(boundaryPatchNames, defaultBoundaryPatchName);
if (patchI != -1)
{
if (patchI != boundaryFaces.size()-1 || boundary_[patchI].size())
{
FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
<< "Default patch " << boundary_[patchI].name()
<< " already has faces in it or is not"
<< " last in list of patches." << exit(FatalError);
}
WarningIn("polyMesh::polyMesh(... construct from shapes...)")
<< "Reusing existing patch " << patchI
<< " for undefined faces." << endl;
boundary_.set
(
patchI,
polyPatch::New
(
boundary_[patchI].type(),
boundary_[patchI].name(),
nFaces - defaultPatchStart,
defaultPatchStart,
patchI,
boundary_
)
);
}
else
{
boundary_.set
(
nAllPatches,
polyPatch::New
(
defaultBoundaryPatchType,
defaultBoundaryPatchName,
nFaces - defaultPatchStart,
defaultPatchStart,
boundary_.size() - 1,
boundary_
)
);
nAllPatches++;
}
}
// Reset the size of the boundary
boundary_.setSize(nAllPatches);
// Set the primitive mesh
initMesh(cells);
if (syncPar)
{
// Calculate topology for the patches (processor-processor comms etc.)
boundary_.updateMesh();
// Calculate the geometry for the patches (transformation tensors etc.)
boundary_.calcGeometry();
}
if (debug)
{
if (checkMesh())
{
Info << "Mesh OK" << endl;
}
}
}
Foam::polyMesh::polyMesh
(
const IOobject& io,
const Xfer<pointField>& points,
const cellShapeList& cellsAsShapes,
const faceListList& boundaryFaces,
const wordList& boundaryPatchNames,
const PtrList<dictionary>& boundaryDicts,
const word& defaultBoundaryPatchName,
const word& defaultBoundaryPatchType,
const bool syncPar
)
:
objectRegistry(io),
primitiveMesh(),
allPoints_
(
IOobject
(
"points",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
points
),
// To be re-sliced later. HJ, 19/oct/2008
points_(allPoints_, allPoints_.size()),
allFaces_
(
IOobject
(
"faces",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
0
),
faces_(allFaces_, allFaces_.size()),
owner_
(
IOobject
(
"owner",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
0
),
neighbour_
(
IOobject
(
"neighbour",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
0
),
clearedPrimitives_(false),
boundary_
(
IOobject
(
"boundary",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
*this,
boundaryFaces.size() + 1 // add room for a default patch
),
bounds_(allPoints_, syncPar),
geometricD_(Vector<label>::zero),
solutionD_(Vector<label>::zero),
pointZones_
(
IOobject
(
"pointZones",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::NO_WRITE
),
*this,
0
),
faceZones_
(
IOobject
(
"faceZones",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::NO_WRITE
),
*this,
0
),
cellZones_
(
IOobject
(
"cellZones",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::NO_WRITE
),
*this,
0
),
globalMeshDataPtr_(NULL),
moving_(false),
changing_(false),
curMotionTimeIndex_(time().timeIndex()),
oldAllPointsPtr_(NULL),
oldPointsPtr_(NULL)
{
if (debug)
{
Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
}
// Remove all of the old mesh files if they exist
removeFiles(instance());
// Calculate faces and cells
labelList patchSizes;
labelList patchStarts;
label defaultPatchStart;
label nFaces;
cellList cells;
setTopology
(
cellsAsShapes,
boundaryFaces,
boundaryPatchNames,
patchSizes,
patchStarts,
defaultPatchStart,
nFaces,
cells
);
// Warning: Patches can only be added once the face list is
// completed, as they hold a subList of the face list
forAll(boundaryDicts, patchI)
{
dictionary patchDict(boundaryDicts[patchI]);
patchDict.set("nFaces", patchSizes[patchI]);
patchDict.set("startFace", patchStarts[patchI]);
// add the patch to the list
boundary_.set
(
nAllPatches,
patchI,
polyPatch::New
(
defaultBoundaryPatchType,
defaultBoundaryPatchName,
nFaces - defaultPatchStart,
defaultPatchStart,
boundary_.size() - 1,
boundaryPatchNames[patchI],
patchDict,
patchI,
boundary_
)
);
}
nAllPatches++;
label nAllPatches = boundaryFaces.size();
label nDefaultFaces = nFaces - defaultPatchStart;
if (syncPar)
{
reduce(nDefaultFaces, sumOp<label>());
}
if (nDefaultFaces > 0)
{
WarningIn("polyMesh::polyMesh(... construct from shapes...)")
<< "Found " << nDefaultFaces
<< " undefined faces in mesh; adding to default patch." << endl;
// Check if there already exists a defaultFaces patch as last patch
// and reuse it.
label patchI = findIndex(boundaryPatchNames, defaultBoundaryPatchName);
if (patchI != -1)
{
if (patchI != boundaryFaces.size()-1 || boundary_[patchI].size())
{
FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
<< "Default patch " << boundary_[patchI].name()
<< " already has faces in it or is not"
<< " last in list of patches." << exit(FatalError);
}
WarningIn("polyMesh::polyMesh(... construct from shapes...)")
<< "Reusing existing patch " << patchI
<< " for undefined faces." << endl;
boundary_.set
(
patchI,
polyPatch::New
(
boundary_[patchI].type(),
boundary_[patchI].name(),
nFaces - defaultPatchStart,
defaultPatchStart,
patchI,
boundary_
)
);
}
else
{
boundary_.set
(
nAllPatches,
polyPatch::New
(
defaultBoundaryPatchType,
defaultBoundaryPatchName,
nFaces - defaultPatchStart,
defaultPatchStart,
boundary_.size() - 1,
boundary_
)
);
nAllPatches++;
}
}
// Reset the size of the boundary

View file

@ -25,7 +25,6 @@ License
#include "preservePatchTypes.H"
#include "polyBoundaryMeshEntries.H"
#include "dictionary.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
@ -35,14 +34,16 @@ void Foam::preservePatchTypes
const word& meshInstance,
const fileName& meshDir,
const wordList& patchNames,
wordList& patchTypes,
PtrList<dictionary>& patchDicts,
const word& defaultFacesName,
word& defaultFacesType,
wordList& patchPhysicalTypes
word& defaultFacesType
)
{
patchDicts.setSize(patchNames.size());
dictionary patchDictionary;
// Read boundary file as single dictionary
{
IOobject patchEntriesHeader
(
@ -67,36 +68,28 @@ void Foam::preservePatchTypes
}
}
if (patchDictionary.size())
forAll(patchNames, patchi)
{
forAll(patchNames, patchi)
{
if (patchDictionary.found(patchNames[patchi]))
{
const dictionary& patchDict =
patchDictionary.subDict(patchNames[patchi]);
patchDict.lookup("type") >> patchTypes[patchi];
patchDict.readIfPresent("geometricType", patchTypes[patchi]);
patchDict.readIfPresent
(
"physicalType",
patchPhysicalTypes[patchi]
);
}
}
if (patchDictionary.found(defaultFacesName))
if (patchDictionary.found(patchNames[patchi]))
{
const dictionary& patchDict =
patchDictionary.subDict(defaultFacesName);
patchDictionary.subDict(patchNames[patchi]);
patchDict.readIfPresent("geometricType", defaultFacesType);
patchDicts.set(patchi, patchDict.clone());
patchDicts[patchi].remove("nFaces");
patchDicts[patchi].remove("startFace");
}
}
Info << nl << "Default patch type set to " << defaultFacesType << endl;
if (patchDictionary.found(defaultFacesName))
{
const dictionary& patchDict =
patchDictionary.subDict(defaultFacesName);
patchDict.readIfPresent("geometricType", defaultFacesType);
}
Info<< nl << "Default patch type set to " << defaultFacesType << endl;
}

View file

@ -37,6 +37,7 @@ SourceFiles
#include "fileName.H"
#include "wordList.H"
#include "dictionary.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -52,10 +53,9 @@ void preservePatchTypes
const word& meshInstance,
const fileName& meshDir,
const wordList& patchNames,
wordList& patchTypes,
PtrList<dictionary>& patchDicts,
const word& defaultFacesName,
word& defaultFacesType,
wordList& patchPhysicalTypes
word& defaultFacesType
);
} // End namespace Foam

10
src/mesh/Allwmake Executable file
View file

@ -0,0 +1,10 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
makeType=${1:-libso}
set -x
wmake $makeType autoMesh
wmake $makeType blockMesh
wmake $makeType extrudeModel
# ----------------------------------------------------------------- end-of-file

View file

@ -0,0 +1,26 @@
autoHexMesh = autoHexMesh
autoHexMeshDriver = $(autoHexMesh)/autoHexMeshDriver
$(autoHexMeshDriver)/autoLayerDriver.C
$(autoHexMeshDriver)/autoLayerDriverShrink.C
$(autoHexMeshDriver)/autoSnapDriver.C
$(autoHexMeshDriver)/autoRefineDriver.C
$(autoHexMeshDriver)/autoHexMeshDriver.C
$(autoHexMeshDriver)/layerParameters/layerParameters.C
$(autoHexMeshDriver)/refinementParameters/refinementParameters.C
$(autoHexMeshDriver)/snapParameters/snapParameters.C
$(autoHexMeshDriver)/pointData/pointData.C
$(autoHexMesh)/meshRefinement/meshRefinementBaffles.C
$(autoHexMesh)/meshRefinement/meshRefinement.C
$(autoHexMesh)/meshRefinement/meshRefinementMerge.C
$(autoHexMesh)/meshRefinement/meshRefinementProblemCells.C
$(autoHexMesh)/meshRefinement/meshRefinementRefine.C
$(autoHexMesh)/refinementSurfaces/refinementSurfaces.C
$(autoHexMesh)/shellSurfaces/shellSurfaces.C
$(autoHexMesh)/trackedParticle/trackedParticle.C
$(autoHexMesh)/trackedParticle/trackedParticleCloud.C
LIB = $(FOAM_LIBBIN)/libautoMesh

View file

@ -0,0 +1,19 @@
EXE_INC = \
-I$(LIB_SRC)/decompositionMethods/decompositionMethods/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/edgeMesh/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude
LIB_LIBS = \
-ldecompositionMethods \
-ldynamicMesh \
-ldynamicFvMesh \
-lfiniteVolume \
-llagrangian \
-lmeshTools \
-ledgeMesh \
-ltriSurface

View file

@ -0,0 +1,552 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*----------------------------------------------------------------------------*/
#include "autoHexMeshDriver.H"
#include "fvMesh.H"
#include "Time.H"
#include "boundBox.H"
#include "wallPolyPatch.H"
#include "cellSet.H"
#include "syncTools.H"
#include "refinementParameters.H"
#include "snapParameters.H"
#include "layerParameters.H"
#include "autoRefineDriver.H"
#include "autoSnapDriver.H"
#include "autoLayerDriver.H"
#include "triSurfaceMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(autoHexMeshDriver, 0);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Check writing tolerance before doing any serious work
Foam::scalar Foam::autoHexMeshDriver::getMergeDistance(const scalar mergeTol)
const
{
const boundBox& meshBb = mesh_.bounds();
scalar mergeDist = mergeTol * meshBb.mag();
scalar writeTol = std::pow
(
scalar(10.0),
-scalar(IOstream::defaultPrecision())
);
Info<< nl
<< "Overall mesh bounding box : " << meshBb << nl
<< "Relative tolerance : " << mergeTol << nl
<< "Absolute matching distance : " << mergeDist << nl
<< endl;
if (mesh_.time().writeFormat() == IOstream::ASCII && mergeTol < writeTol)
{
FatalErrorIn("autoHexMeshDriver::getMergeDistance(const scalar) const")
<< "Your current settings specify ASCII writing with "
<< IOstream::defaultPrecision() << " digits precision." << endl
<< "Your merging tolerance (" << mergeTol << ") is finer than this."
<< endl
<< "Please change your writeFormat to binary"
<< " or increase the writePrecision" << endl
<< "or adjust the merge tolerance (-mergeTol)."
<< exit(FatalError);
}
return mergeDist;
}
//// Specifically orient using a calculated point outside
//void Foam::autoHexMeshDriver::orientOutside
//(
// PtrList<searchableSurface>& shells
//)
//{
// // Determine outside point.
// boundBox overallBb = boundBox::invertedBox;
//
// bool hasSurface = false;
//
// forAll(shells, shellI)
// {
// if (isA<triSurfaceMesh>(shells[shellI]))
// {
// const triSurfaceMesh& shell =
// refCast<const triSurfaceMesh>(shells[shellI]);
//
// hasSurface = true;
//
// boundBox shellBb(shell.localPoints(), false);
//
// overallBb.min() = min(overallBb.min(), shellBb.min());
// overallBb.max() = max(overallBb.max(), shellBb.max());
// }
// }
//
// if (hasSurface)
// {
// const point outsidePt = 2 * overallBb.span();
//
// //Info<< "Using point " << outsidePt << " to orient shells" << endl;
//
// forAll(shells, shellI)
// {
// if (isA<triSurfaceMesh>(shells[shellI]))
// {
// triSurfaceMesh& shell =
// refCast<triSurfaceMesh>(shells[shellI]);
//
// if (!refinementSurfaces::isSurfaceClosed(shell))
// {
// FatalErrorIn("orientOutside(PtrList<searchableSurface>&)")
// << "Refinement shell "
// << shell.searchableSurface::name()
// << " is not closed." << exit(FatalError);
// }
//
// refinementSurfaces::orientSurface(outsidePt, shell);
// }
// }
// }
//}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::autoHexMeshDriver::autoHexMeshDriver
(
fvMesh& mesh,
const bool overwrite,
const dictionary& dict,
const dictionary& decomposeDict
)
:
mesh_(mesh),
dict_(dict),
debug_(readLabel(dict_.lookup("debug"))),
mergeDist_(getMergeDistance(readScalar(dict_.lookup("mergeTolerance"))))
{
if (debug_ > 0)
{
meshRefinement::debug = debug_;
autoHexMeshDriver::debug = debug_;
autoRefineDriver::debug = debug;
autoSnapDriver::debug = debug;
autoLayerDriver::debug = debug;
}
refinementParameters refineParams(dict, 1);
Info<< "Overall cell limit : "
<< refineParams.maxGlobalCells() << endl;
Info<< "Per processor cell limit : "
<< refineParams.maxLocalCells() << endl;
Info<< "Minimum number of cells to refine : "
<< refineParams.minRefineCells() << endl;
Info<< "Curvature : "
<< refineParams.curvature() << nl << endl;
Info<< "Layers between different refinement levels : "
<< refineParams.nBufferLayers() << endl;
PtrList<dictionary> shellDicts(dict_.lookup("refinementShells"));
PtrList<dictionary> surfaceDicts(dict_.lookup("surfaces"));
// Read geometry
// ~~~~~~~~~~~~~
{
Info<< "Reading all geometry." << endl;
// Construct dictionary with all shells and all refinement surfaces
dictionary geometryDict;
forAll(shellDicts, shellI)
{
dictionary shellDict = shellDicts[shellI];
const word name(shellDict.lookup("name"));
shellDict.remove("name");
shellDict.remove("level");
shellDict.remove("refineInside");
geometryDict.add(name, shellDict);
}
forAll(surfaceDicts, surfI)
{
dictionary surfDict = surfaceDicts[surfI];
const word name(string::validate<word>(surfDict.lookup("file")));
surfDict.remove("file");
surfDict.remove("regions");
if (!surfDict.found("name"))
{
surfDict.add("name", name);
}
surfDict.add("type", triSurfaceMesh::typeName);
geometryDict.add(name, surfDict);
}
allGeometryPtr_.reset
(
new searchableSurfaces
(
IOobject
(
"abc", // dummy name
//mesh_.time().findInstance("triSurface", word::null),
// instance
mesh_.time().constant(), // instance
"triSurface", // local
mesh_.time(), // registry
IOobject::MUST_READ,
IOobject::NO_WRITE
),
geometryDict
)
);
Info<< "Read geometry in = "
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
}
// Read refinement surfaces
// ~~~~~~~~~~~~~~~~~~~~~~~~
{
Info<< "Reading surfaces and constructing search trees." << endl;
surfacesPtr_.reset
(
new refinementSurfaces
(
allGeometryPtr_(),
surfaceDicts
)
);
Info<< "Read surfaces in = "
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
}
// Read refinement shells
// ~~~~~~~~~~~~~~~~~~~~~~
{
Info<< "Reading refinement shells." << endl;
shellsPtr_.reset
(
new shellSurfaces
(
allGeometryPtr_(),
shellDicts
)
);
Info<< "Read refinement shells in = "
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
//// Orient shell surfaces before any searching is done.
//Info<< "Orienting triSurface shells so point far away is outside."
// << endl;
//orientOutside(shells_);
//Info<< "Oriented shells in = "
// << mesh_.time().cpuTimeIncrement() << " s" << endl;
Info<< "Setting refinement level of surface to be consistent"
<< " with shells." << endl;
surfacesPtr_().setMinLevelFields(shells());
Info<< "Checked shell refinement in = "
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
}
// Check faceZones are synchronised
meshRefinement::checkCoupledFaceZones(mesh_);
// Refinement engine
// ~~~~~~~~~~~~~~~~~
{
Info<< nl
<< "Determining initial surface intersections" << nl
<< "-----------------------------------------" << nl
<< endl;
// Main refinement engine
meshRefinerPtr_.reset
(
new meshRefinement
(
mesh,
mergeDist_, // tolerance used in sorting coordinates
overwrite,
surfaces(),
shells()
)
);
Info<< "Calculated surface intersections in = "
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
// Some stats
meshRefinerPtr_().printMeshInfo(debug_, "Initial mesh");
meshRefinerPtr_().write
(
debug_&meshRefinement::OBJINTERSECTIONS,
mesh_.time().path()/meshRefinerPtr_().timeName()
);
}
// Add all the surface regions as patches
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
Info<< nl
<< "Adding patches for surface regions" << nl
<< "----------------------------------" << nl
<< endl;
// From global region number to mesh patch.
globalToPatch_.setSize(surfaces().nRegions(), -1);
Info<< "Patch\tRegion" << nl
<< "-----\t------"
<< endl;
const labelList& surfaceGeometry = surfaces().surfaces();
forAll(surfaceGeometry, surfI)
{
label geomI = surfaceGeometry[surfI];
const wordList& regNames = allGeometryPtr_().regionNames()[geomI];
Info<< surfaces().names()[surfI] << ':' << nl << nl;
forAll(regNames, i)
{
label patchI = meshRefinerPtr_().addMeshedPatch
(
regNames[i],
wallPolyPatch::typeName
);
Info<< patchI << '\t' << regNames[i] << nl;
globalToPatch_[surfaces().globalRegion(surfI, i)] = patchI;
}
Info<< nl;
}
Info<< "Added patches in = "
<< mesh_.time().cpuTimeIncrement() << " s" << nl << endl;
}
//// Add cyclics for any named faceZones
//// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//// (these cyclics are used later on to temporarily put the faceZones
//// in when snapping)
//
//labelList namedSurfaces(surfaces().getNamedSurfaces());
//if (namedSurfaces.size())
//{
// Info<< nl
// << "Introducing cyclics for faceZones" << nl
// << "---------------------------------" << nl
// << endl;
//
// // From surface to cyclic patch
// surfaceToCyclicPatch_.setSize(surfaces().size(), -1);
//
// Info<< "Patch\tZone" << nl
// << "----\t-----"
// << endl;
//
// forAll(namedSurfaces, i)
// {
// label surfI = namedSurfaces[i];
//
// surfaceToCyclicPatch_[surfI] = meshRefinement::addPatch
// (
// mesh,
// surfaces().faceZoneNames()[surfI],
// cyclicPolyPatch::typeName
// );
//
// Info<< surfaceToCyclicPatch_[surfI] << '\t'
// << surfaces().faceZoneNames()[surfI] << nl << endl;
// }
// Info<< "Added cyclic patches in = "
// << mesh_.time().cpuTimeIncrement() << " s" << endl;
//}
// Parallel
// ~~~~~~~~
{
// Decomposition
decomposerPtr_ = decompositionMethod::New
(
decomposeDict,
mesh_
);
decompositionMethod& decomposer = decomposerPtr_();
if (Pstream::parRun() && !decomposer.parallelAware())
{
FatalErrorIn("autoHexMeshDriver::autoHexMeshDriver"
"(const IOobject&, fvMesh&)")
<< "You have selected decomposition method "
<< decomposer.typeName
<< " which is not parallel aware." << endl
<< "Please select one that is (parMetis, hierarchical)"
<< exit(FatalError);
}
// Mesh distribution engine (uses tolerance to reconstruct meshes)
distributorPtr_.reset(new fvMeshDistribute(mesh_, mergeDist_));
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::autoHexMeshDriver::writeMesh(const string& msg) const
{
const meshRefinement& meshRefiner = meshRefinerPtr_();
meshRefiner.printMeshInfo(debug_, msg);
Info<< "Writing mesh to time " << meshRefiner.timeName() << endl;
meshRefiner.write(meshRefinement::MESH|meshRefinement::SCALARLEVELS, "");
if (debug_ & meshRefinement::OBJINTERSECTIONS)
{
meshRefiner.write
(
meshRefinement::OBJINTERSECTIONS,
mesh_.time().path()/meshRefiner.timeName()
);
}
Info<< "Written mesh in = "
<< mesh_.time().cpuTimeIncrement() << " s." << endl;
}
void Foam::autoHexMeshDriver::doMesh()
{
Switch wantRefine(dict_.lookup("doRefine"));
Switch wantSnap(dict_.lookup("doSnap"));
Switch wantLayers(dict_.lookup("doLayers"));
Info<< "Do refinement : " << wantRefine << nl
<< "Do snapping : " << wantSnap << nl
<< "Do layers : " << wantLayers << nl
<< endl;
if (wantRefine)
{
const dictionary& motionDict = dict_.subDict("motionDict");
autoRefineDriver refineDriver
(
meshRefinerPtr_(),
decomposerPtr_(),
distributorPtr_(),
globalToPatch_
);
// Get all the refinement specific params
refinementParameters refineParams(dict_, 1);
refineDriver.doRefine(dict_, refineParams, wantSnap, motionDict);
// Write mesh
writeMesh("Refined mesh");
}
if (wantSnap)
{
const dictionary& snapDict = dict_.subDict("snapDict");
const dictionary& motionDict = dict_.subDict("motionDict");
autoSnapDriver snapDriver
(
meshRefinerPtr_(),
globalToPatch_
);
// Get all the snapping specific params
snapParameters snapParams(snapDict, 1);
snapDriver.doSnap(snapDict, motionDict, snapParams);
// Write mesh.
writeMesh("Snapped mesh");
}
if (wantLayers)
{
const dictionary& motionDict = dict_.subDict("motionDict");
const dictionary& shrinkDict = dict_.subDict("shrinkDict");
PtrList<dictionary> surfaceDicts(dict_.lookup("surfaces"));
autoLayerDriver layerDriver(meshRefinerPtr_());
// Get all the layer specific params
layerParameters layerParams
(
surfaceDicts,
surfacesPtr_(),
globalToPatch_,
shrinkDict,
mesh_.boundaryMesh()
);
layerDriver.doLayers
(
shrinkDict,
motionDict,
layerParams,
true, // pre-balance
decomposerPtr_(),
distributorPtr_()
);
// Write mesh.
writeMesh("Layer mesh");
}
}
// ************************************************************************* //

View file

@ -0,0 +1,233 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::autoHexMeshDriver
Description
main meshing driver.
SourceFiles
autoHexMeshDriver.C
\*---------------------------------------------------------------------------*/
#ifndef autoHexMeshDriver_H
#define autoHexMeshDriver_H
#include "autoPtr.H"
#include "dictionary.H"
#include "wallPoint.H"
#include "searchableSurfaces.H"
#include "refinementSurfaces.H"
#include "shellSurfaces.H"
#include "meshRefinement.H"
#include "decompositionMethod.H"
#include "fvMeshDistribute.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Class forward declarations
class fvMesh;
/*---------------------------------------------------------------------------*\
Class autoHexMeshDriver Declaration
\*---------------------------------------------------------------------------*/
class autoHexMeshDriver
{
// Static data members
//- Extrusion controls
enum extrudeMode
{
NOEXTRUDE, /*!< Do not extrude. No layers added. */
EXTRUDE, /*!< Extrude */
EXTRUDEREMOVE /*!< Extrude but afterwards remove added */
/*!< faces locally */
};
// Private classes
//- Combine operator class for equalizing displacements.
class minMagEqOp
{
public:
void operator()(vector& x, const vector& y) const
{
if (magSqr(y) < magSqr(x))
{
x = y;
}
}
};
//- Combine operator class to combine normal with other normal.
class nomalsCombine
{
public:
void operator()(vector& x, const vector& y) const
{
if (y != wallPoint::greatPoint)
{
if (x == wallPoint::greatPoint)
{
x = y;
}
else
{
x *= (x&y);
}
}
}
};
// Private data
//- Reference to mesh
fvMesh& mesh_;
//- Input dictionary
const dictionary dict_;
//- Debug level
const label debug_;
//- Merge distance
const scalar mergeDist_;
//- All surface based geometry
autoPtr<searchableSurfaces> allGeometryPtr_;
//- Shells (geometry for inside/outside refinement)
autoPtr<shellSurfaces> shellsPtr_;
//- Surfaces (geometry for intersection based refinement)
autoPtr<refinementSurfaces> surfacesPtr_;
//- Per refinement surface region the patch
labelList globalToPatch_;
//- Mesh refinement engine
autoPtr<meshRefinement> meshRefinerPtr_;
//- Decomposition engine
autoPtr<decompositionMethod> decomposerPtr_;
//- Mesh distribution engine
autoPtr<fvMeshDistribute> distributorPtr_;
// Private Member Functions
//- Calculate merge distance. Check against writing tolerance.
scalar getMergeDistance(const scalar mergeTol) const;
//static void orientOutside(PtrList<searchableSurface>&);
//- Disallow default bitwise copy construct
autoHexMeshDriver(const autoHexMeshDriver&);
//- Disallow default bitwise assignment
void operator=(const autoHexMeshDriver&);
public:
//- Runtime type information
ClassName("autoHexMeshDriver");
// Constructors
//- Construct from dictionary and mesh to modify
autoHexMeshDriver
(
fvMesh& mesh,
const bool overwrite,
const dictionary& meshDict,
const dictionary& decomposeDict
);
// Member Functions
// Access
//- reference to mesh
const fvMesh& mesh() const
{
return mesh_;
}
fvMesh& mesh()
{
return mesh_;
}
//- Surfaces to base refinement on
const refinementSurfaces& surfaces() const
{
return surfacesPtr_();
}
//- Surfaces to volume refinement on
const shellSurfaces& shells() const
{
return shellsPtr_();
}
//- Per refinementsurface, per region the patch
const labelList& globalToPatch() const
{
return globalToPatch_;
}
// Meshing
//- Write mesh
void writeMesh(const string&) const;
//- Do all : refine, snap, layers
void doMesh();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,561 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::autoLayerDriver
Description
All to do with adding layers
SourceFiles
autoLayerDriver.C
\*---------------------------------------------------------------------------*/
#ifndef autoLayerDriver_H
#define autoLayerDriver_H
#include "PackedBoolList.H"
#include "meshRefinement.H"
#include "wallPoint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class removePoints;
class pointSet;
class motionSmoother;
class addPatchCellLayer;
class pointData;
class wallPoint;
class faceSet;
class layerParameters;
/*---------------------------------------------------------------------------*\
Class autoLayerDriver Declaration
\*---------------------------------------------------------------------------*/
class autoLayerDriver
{
// Static data members
//- Extrusion controls
enum extrudeMode
{
NOEXTRUDE, /*!< Do not extrude. No layers added. */
EXTRUDE, /*!< Extrude */
EXTRUDEREMOVE /*!< Extrude but afterwards remove added */
/*!< faces locally */
};
// Private classes
//- Combine operator class to combine normal with other normal.
class nomalsCombine
{
public:
void operator()(vector& x, const vector& y) const
{
if (y != wallPoint::greatPoint)
{
if (x == wallPoint::greatPoint)
{
x = y;
}
else
{
x *= (x&y);
}
}
}
};
// Private data
//- Mesh+surface
meshRefinement& meshRefiner_;
// Private Member Functions
// Face merging
//- Merge patch faces. Undo until no checkMesh errors.
label mergePatchFacesUndo
(
const scalar minCos,
const scalar concaveCos,
const dictionary&
);
//- Remove points.
autoPtr<mapPolyMesh> doRemovePoints
(
removePoints& pointRemover,
const boolList& pointCanBeDeleted
);
//- Restore faces (which contain removed points)
autoPtr<mapPolyMesh> doRestorePoints
(
removePoints& pointRemover,
const labelList& facesToRestore
);
//- Return candidateFaces that are also in set.
labelList collectFaces
(
const labelList& candidateFaces,
const labelHashSet& set
) const;
//- Pick up faces of cells of faces in set.
labelList growFaceCellFace(const labelHashSet&) const;
//- Remove points not used by any face or points used by only
// two faces where the edges are in line
label mergeEdgesUndo(const scalar minCos, const dictionary&);
// Layers
//- For debugging: Dump displacement to .obj files
static void dumpDisplacement
(
const fileName&,
const indirectPrimitivePatch&,
const vectorField&,
const List<extrudeMode>&
);
//- Check that primitivePatch is not multiply connected.
// Collect non-manifold points in pointSet.
static void checkManifold
(
const indirectPrimitivePatch&,
pointSet& nonManifoldPoints
);
//- Check that mesh outside is not multiply connected.
void checkMeshManifold() const;
// Static extrusion setup
//- Unset extrusion on point. Returns true if anything unset.
static bool unmarkExtrusion
(
const label patchPointI,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- Unset extrusion on face. Returns true if anything unset.
static bool unmarkExtrusion
(
const face& localFace,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- No extrusion at non-manifold points.
void handleNonManifolds
(
const indirectPrimitivePatch& pp,
const labelList& meshEdges,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- No extrusion on feature edges. Assumes non-manifold
// edges already handled.
void handleFeatureAngle
(
const indirectPrimitivePatch& pp,
const labelList& meshEdges,
const scalar minCos,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- No extrusion on warped faces
void handleWarpedFaces
(
const indirectPrimitivePatch& pp,
const scalar faceRatio,
const scalar edge0Len,
const labelList& cellLevel,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Determine the number of layers per point from the number of
// layers per surface.
void setNumLayers
(
const labelList& patchToNLayers,
const labelList& patchIDs,
const indirectPrimitivePatch& pp,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Grow no-extrusion layer.
static void growNoExtrusion
(
const indirectPrimitivePatch& pp,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- Calculate pointwise wanted and minimum thickness.
// thickness: wanted thickness
// minthickness: when to give up and not extrude
// Gets per patch parameters and determine pp pointwise
// parameters.
void calculateLayerThickness
(
const indirectPrimitivePatch& pp,
const labelList& patchIDs,
const scalarField& patchExpansionRatio,
const bool relativeSizes,
const scalarField& patchFinalLayerThickness,
const scalarField& patchMinThickness,
const labelList& cellLevel,
const labelList& patchNLayers,
const scalar edge0Len,
scalarField& thickness,
scalarField& minThickness,
scalarField& expansionRatio
) const;
// Extrusion execution
//- Synchronize displacement among coupled patches.
void syncPatchDisplacement
(
const motionSmoother& meshMover,
const scalarField& minThickness,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Get nearest point on surface to snap to
void getPatchDisplacement
(
const motionSmoother& meshMover,
const scalarField& thickness,
const scalarField& minThickness,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Truncates displacement
// - for all patchFaces in the faceset displacement gets set
// to zero
// - all displacement < minThickness gets set to zero
label truncateDisplacement
(
const motionSmoother& meshMover,
const scalarField& minThickness,
const faceSet& illegalPatchFaces,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Setup layer information (at points and faces) to
// modify mesh topology in
// regions where layer mesh terminates. Guarantees an
// optional slow decreasing of the number of layers.
// Returns the number of layers per face and per point
// to go into the actual layer addition engine.
void setupLayerInfoTruncation
(
const motionSmoother& meshMover,
const labelList& patchNLayers,
const List<extrudeMode>& extrudeStatus,
const label nBufferCellsNoExtrude,
labelList& nPatchPointLayers,
labelList& nPatchFaceLayers
) const;
//- Does any of the cells use a face from faces?
static bool cellsUseFace
(
const polyMesh& mesh,
const labelList& cellLabels,
const labelHashSet& faces
);
//- Checks the newly added cells and locally unmarks points
// so they will not get extruded next time round. Returns
// global number of unmarked points (0 if all was fine)
static label checkAndUnmark
(
const addPatchCellLayer& addLayer,
const dictionary& motionDict,
const indirectPrimitivePatch& pp,
const polyMesh&,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- Count global number of extruded faces
static label countExtrusion
(
const indirectPrimitivePatch& pp,
const List<extrudeMode>& extrudeStatus
);
//- Collect layer faces and layer cells into bools
// for ease of handling
static void getLayerCellsFaces
(
const polyMesh&,
const addPatchCellLayer&,
boolList&,
boolList&
);
// Mesh shrinking (to create space for layers)
//- Average field (over all subset of mesh points) by
// summing contribution from edges. Global parallel since only
// does master edges for coupled edges.
template<class Type>
static void averageNeighbours
(
const polyMesh& mesh,
const PackedBoolList& isMasterEdge,
const labelList& meshEdges,
const labelList& meshPoints,
const edgeList& edges,
const scalarField& invSumWeight,
const Field<Type>& data,
Field<Type>& average
);
//- Calculate inverse sum of edge weights
// (currently always 1.0)
void sumWeights
(
const PackedBoolList& isMasterEdge,
const labelList& meshEdges,
const labelList& meshPoints,
const edgeList& edges,
scalarField& invSumWeight
) const;
//- Smooth scalar field on patch
void smoothField
(
const motionSmoother& meshMover,
const PackedBoolList& isMasterEdge,
const labelList& meshEdges,
const scalarField& fieldMin,
const label nSmoothDisp,
scalarField& field
) const;
//- Smooth normals on patch.
void smoothPatchNormals
(
const motionSmoother& meshMover,
const PackedBoolList& isMasterEdge,
const labelList& meshEdges,
const label nSmoothDisp,
pointField& normals
) const;
//- Smooth normals in interior.
void smoothNormals
(
const label nSmoothDisp,
const PackedBoolList& isMasterEdge,
const labelList& fixedPoints,
pointVectorField& normals
) const;
bool isMaxEdge
(
const List<pointData>&,
const label edgeI,
const scalar minCos
) const;
//- Stop layer growth where mesh wraps around edge with a
// large feature angle
void handleFeatureAngleLayerTerminations
(
const indirectPrimitivePatch& pp,
const scalar minCos,
List<extrudeMode>& extrudeStatus,
pointField& patchDisp,
labelList& patchNLayers,
label& nPointCounter
) const;
//- Find isolated islands (points, edges and faces and
// layer terminations)
// in the layer mesh and stop any layer growth at these points.
void findIsolatedRegions
(
const indirectPrimitivePatch& pp,
const PackedBoolList& isMasterEdge,
const labelList& meshEdges,
const scalar minCosLayerTermination,
scalarField& field,
List<extrudeMode>& extrudeStatus,
pointField& patchDisp,
labelList& patchNLayers
) const;
// Calculate medial axis fields
void medialAxisSmoothingInfo
(
const motionSmoother& meshMover,
const label nSmoothNormals,
const label nSmoothSurfaceNormals,
const scalar minMedianAxisAngleCos,
pointVectorField& dispVec,
pointScalarField& medialRatio,
pointScalarField& medialDist
) const;
//- Main routine to shrink mesh
void shrinkMeshMedialDistance
(
motionSmoother& meshMover,
const dictionary& meshQualityDict,
const label nSmoothThickness,
const scalar maxThicknessToMedialRatio,
const label nAllowableErrors,
const label nSnap,
const scalar minCosLayerTermination,
const scalarField& layerThickness,
const scalarField& minThickness,
const pointVectorField& dispVec,
const pointScalarField& medialRatio,
const pointScalarField& medialDist,
List<extrudeMode>& extrudeStatus,
pointField& patchDisp,
labelList& patchNLayers
) const;
//- Disallow default bitwise copy construct
autoLayerDriver(const autoLayerDriver&);
//- Disallow default bitwise assignment
void operator=(const autoLayerDriver&);
public:
//- Runtime type information
ClassName("autoLayerDriver");
// Constructors
//- Construct from components
autoLayerDriver(meshRefinement& meshRefiner);
// Member Functions
//- Merge patch faces on same cell.
void mergePatchFacesUndo
(
const layerParameters& layerParams,
const dictionary& motionDict
);
//- Add cell layers
void addLayers
(
const layerParameters& layerParams,
const dictionary& motionDict,
const labelList& patchIDs,
const label nAllowableErrors,
decompositionMethod& decomposer,
fvMeshDistribute& distributor
);
//- Add layers according to the dictionary settings
void doLayers
(
const dictionary& shrinkDict,
const dictionary& motionDict,
const layerParameters& layerParams,
const bool preBalance, // balance before adding?
decompositionMethod& decomposer,
fvMeshDistribute& distributor
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "autoLayerDriverTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

File diff suppressed because it is too large Load diff

View file

@ -21,50 +21,55 @@ License
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "blockMesh.H"
#include "autoLayerDriver.H"
#include "syncTools.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::pointField Foam::blockMesh::createPoints(const dictionary& dict)
template<class Type>
void Foam::autoLayerDriver::averageNeighbours
(
const polyMesh& mesh,
const PackedBoolList& isMasterEdge,
const labelList& meshEdges,
const labelList& meshPoints,
const edgeList& edges,
const scalarField& invSumWeight,
const Field<Type>& data,
Field<Type>& average
)
{
blockMesh& blocks = *this;
average = pTraits<Type>::zero;
scalar scaleFactor = 1.0;
// optional 'convertToMeters' (or 'scale'?)
if (!dict.readIfPresent("convertToMeters", scaleFactor))
forAll(edges, edgeI)
{
dict.readIfPresent("scale", scaleFactor);
}
Info<< nl << "Creating points with scale " << scaleFactor << endl;
pointField points(nPoints_);
forAll(blocks, blockLabel)
{
const pointField& blockPoints = blocks[blockLabel].points();
forAll(blockPoints, blockPointLabel)
if (isMasterEdge.get(meshEdges[edgeI]) == 1)
{
points
[
mergeList_
[
blockPointLabel
+ blockOffsets_[blockLabel]
]
] = scaleFactor * blockPoints[blockPointLabel];
const edge& e = edges[edgeI];
//scalar eWeight = edgeWeights[edgeI];
scalar eWeight = 1.0;
label v0 = e[0];
label v1 = e[1];
average[v0] += eWeight*data[v1];
average[v1] += eWeight*data[v0];
}
}
return points;
syncTools::syncPointList
(
mesh,
meshPoints,
average,
plusEqOp<Type>(),
pTraits<Type>::zero, // null value
false // no separation
);
average *= invSumWeight;
}
// ************************************************************************* //

View file

@ -0,0 +1,874 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*----------------------------------------------------------------------------*/
#include "autoRefineDriver.H"
#include "meshRefinement.H"
#include "fvMesh.H"
#include "Time.H"
#include "cellSet.H"
#include "syncTools.H"
#include "refinementParameters.H"
#include "featureEdgeMesh.H"
#include "refinementSurfaces.H"
#include "shellSurfaces.H"
#include "mapDistributePolyMesh.H"
#include "mathematicalConstants.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(autoRefineDriver, 0);
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Read explicit feature edges
Foam::label Foam::autoRefineDriver::readFeatureEdges
(
const PtrList<dictionary>& featDicts,
PtrList<featureEdgeMesh>& featureMeshes,
labelList& featureLevels
) const
{
Info<< "Reading external feature lines." << endl;
const fvMesh& mesh = meshRefiner_.mesh();
featureMeshes.setSize(featDicts.size());
featureLevels.setSize(featDicts.size());
forAll(featDicts, i)
{
const dictionary& dict = featDicts[i];
fileName featFileName(dict.lookup("file"));
featureMeshes.set
(
i,
new featureEdgeMesh
(
IOobject
(
featFileName, // name
//mesh.time().findInstance("triSurface", featFileName),
// // instance
mesh.time().constant(), // instance
"triSurface", // local
mesh.time(), // registry
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
)
);
featureMeshes[i].mergePoints(meshRefiner_.mergeDistance());
featureLevels[i] = readLabel(dict.lookup("level"));
Info<< "Refinement level " << featureLevels[i]
<< " for all cells crossed by feature " << featFileName
<< " (" << featureMeshes[i].points().size() << " points, "
<< featureMeshes[i].edges().size() << " edges)." << endl;
}
Info<< "Read feature lines in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
return featureMeshes.size();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::autoRefineDriver::autoRefineDriver
(
meshRefinement& meshRefiner,
decompositionMethod& decomposer,
fvMeshDistribute& distributor,
const labelList& globalToPatch
)
:
meshRefiner_(meshRefiner),
decomposer_(decomposer),
distributor_(distributor),
globalToPatch_(globalToPatch)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::autoRefineDriver::featureEdgeRefine
(
const refinementParameters& refineParams,
const PtrList<dictionary>& featDicts,
const label maxIter,
const label minRefine
)
{
const fvMesh& mesh = meshRefiner_.mesh();
// Read explicit feature edges
PtrList<featureEdgeMesh> featureMeshes;
// Per feature the refinement level
labelList featureLevels;
readFeatureEdges(featDicts, featureMeshes, featureLevels);
label iter = 0;
if (featureMeshes.size() && maxIter > 0)
{
for (; iter < maxIter; iter++)
{
Info<< nl
<< "Feature refinement iteration " << iter << nl
<< "------------------------------" << nl
<< endl;
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints()[0], // For now only use one.
refineParams.curvature(),
featureMeshes,
featureLevels,
true, // featureRefinement
false, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for feature refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
if (nCellsToRefine <= minRefine)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug > 0)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"feature refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"feature refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
}
return iter;
}
Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
(
const refinementParameters& refineParams,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
// Determine the maximum refinement level over all surfaces. This
// determines the minumum number of surface refinement iterations.
label overallMaxLevel = max(meshRefiner_.surfaces().maxLevel());
label iter;
for (iter = 0; iter < maxIter; iter++)
{
Info<< nl
<< "Surface refinement iteration " << iter << nl
<< "------------------------------" << nl
<< endl;
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// Only look at surface intersections (minLevel and surface curvature),
// do not do internal refinement (refinementShells)
const PtrList<featureEdgeMesh> dummyFeatures;
PtrList<featureEdgeMesh> dummy(0);
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints()[0],
refineParams.curvature(),
dummyFeatures, // dummy featureMeshes;
labelList(0), // dummy featureLevels;
false, // featureRefinement
false, // internalRefinement
true, // surfaceRefinement
true, // curvatureRefinement
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine or have done minimum nessecary
// iterations and not enough cells to refine.
if
(
nCellsToRefine == 0
|| (
iter >= overallMaxLevel
&& nCellsToRefine <= refineParams.minRefineCells()
)
)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"surface refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"surface refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
return iter;
}
void Foam::autoRefineDriver::removeInsideCells
(
const refinementParameters& refineParams,
const label nBufferLayers
)
{
Info<< nl
<< "Removing mesh beyond surface intersections" << nl
<< "------------------------------------------" << nl
<< endl;
const fvMesh& mesh = meshRefiner_.mesh();
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
meshRefiner_.splitMesh
(
nBufferLayers, // nBufferLayers
globalToPatch_,
refineParams.keepPoints()[0]
);
if (debug)
{
Pout<< "Writing subsetted mesh to time "
<< meshRefiner_.timeName() << '.' << endl;
meshRefiner_.write(debug, mesh.time().path()/meshRefiner_.timeName());
Pout<< "Dumped mesh in = "
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
}
}
Foam::label Foam::autoRefineDriver::shellRefine
(
const refinementParameters& refineParams,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
// Mark current boundary faces with 0. Have meshRefiner maintain them.
meshRefiner_.userFaceData().setSize(1);
// mark list to remove any refined faces
meshRefiner_.userFaceData()[0].first() = meshRefinement::REMOVE;
meshRefiner_.userFaceData()[0].second() = createWithValues<labelList>
(
mesh.nFaces(),
-1,
meshRefiner_.intersectedFaces(),
0
);
// Determine the maximum refinement level over all volume refinement
// regions. This determines the minumum number of shell refinement
// iterations.
label overallMaxShellLevel = meshRefiner_.shells().maxLevel();
label iter;
for (iter = 0; iter < maxIter; iter++)
{
Info<< nl
<< "Shell refinement iteration " << iter << nl
<< "----------------------------" << nl
<< endl;
const PtrList<featureEdgeMesh> dummyFeatures;
PtrList<featureEdgeMesh> dummy(0);
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints()[0],
refineParams.curvature(),
dummyFeatures, // dummy featureMeshes;
labelList(0), // dummy featureLevels;
false, // featureRefinement
true, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
if (debug)
{
Pout<< "Dumping " << candidateCells.size()
<< " cells to cellSet candidateCellsFromShells." << endl;
cellSet
(
mesh,
"candidateCellsFromShells",
labelHashSet(candidateCells)
).write();
}
// Problem choosing starting faces for bufferlayers (bFaces)
// - we can't use the current intersected boundary faces
// (intersectedFaces) since this grows indefinitely
// - if we use 0 faces we don't satisfy bufferLayers from the
// surface.
// - possibly we want to have bFaces only the initial set of faces
// and maintain the list while doing the refinement.
labelList bFaces
(
findIndices(meshRefiner_.userFaceData()[0].second(), 0)
);
//Info<< "Collected boundary faces : "
// << returnReduce(bFaces.size(), sumOp<label>()) << endl;
labelList cellsToRefine;
if (refineParams.nBufferLayers() <= 2)
{
cellsToRefine = meshRefiner_.meshCutter().consistentSlowRefinement
(
refineParams.nBufferLayers(),
candidateCells, // cells to refine
bFaces, // faces for nBufferLayers
1, // point difference
meshRefiner_.intersectedPoints() // points to check
);
}
else
{
cellsToRefine = meshRefiner_.meshCutter().consistentSlowRefinement2
(
refineParams.nBufferLayers(),
candidateCells, // cells to refine
bFaces // faces for nBufferLayers
);
}
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for internal refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine or have done minimum nessecary
// iterations and not enough cells to refine.
if
(
nCellsToRefine == 0
|| (
iter >= overallMaxShellLevel
&& nCellsToRefine <= refineParams.minRefineCells()
)
)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"shell refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"shell refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
meshRefiner_.userFaceData().clear();
return iter;
}
void Foam::autoRefineDriver::baffleAndSplitMesh
(
const refinementParameters& refineParams,
const bool handleSnapProblems,
const dictionary& motionDict
)
{
Info<< nl
<< "Splitting mesh at surface intersections" << nl
<< "---------------------------------------" << nl
<< endl;
const fvMesh& mesh = meshRefiner_.mesh();
// Introduce baffles at surface intersections. Note:
// meshRefiment::surfaceIndex() will
// be like boundary face from now on so not coupled anymore.
meshRefiner_.baffleAndSplitMesh
(
handleSnapProblems, // detect&remove potential snap problem
false, // perpendicular edge connected cells
scalarField(0), // per region perpendicular angle
!handleSnapProblems, // merge free standing baffles?
motionDict,
const_cast<Time&>(mesh.time()),
globalToPatch_,
refineParams.keepPoints()[0]
);
}
void Foam::autoRefineDriver::zonify
(
const refinementParameters& refineParams
)
{
// Mesh is at its finest. Do zoning
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This puts all faces with intersection across a zoneable surface
// into that surface's faceZone. All cells inside faceZone get given the
// same cellZone.
if (meshRefiner_.surfaces().getNamedSurfaces().size())
{
Info<< nl
<< "Introducing zones for interfaces" << nl
<< "--------------------------------" << nl
<< endl;
const fvMesh& mesh = meshRefiner_.mesh();
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
meshRefiner_.zonify
(
refineParams.keepPoints()[0],
refineParams.allowFreeStandingZoneFaces()
);
if (debug)
{
Pout<< "Writing zoned mesh to time "
<< meshRefiner_.timeName() << '.' << endl;
meshRefiner_.write
(
debug,
mesh.time().path()/meshRefiner_.timeName()
);
}
// Check that all faces are synced
meshRefinement::checkCoupledFaceZones(mesh);
}
}
void Foam::autoRefineDriver::splitAndMergeBaffles
(
const refinementParameters& refineParams,
const bool handleSnapProblems,
const dictionary& motionDict
)
{
Info<< nl
<< "Handling cells with snap problems" << nl
<< "---------------------------------" << nl
<< endl;
const fvMesh& mesh = meshRefiner_.mesh();
// Introduce baffles and split mesh
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
const scalarField& perpAngle = meshRefiner_.surfaces().perpendicularAngle();
meshRefiner_.baffleAndSplitMesh
(
handleSnapProblems,
handleSnapProblems, // remove perp edge connected cells
perpAngle, // perp angle
false, // merge free standing baffles?
motionDict,
const_cast<Time&>(mesh.time()),
globalToPatch_,
refineParams.keepPoints()[0]
);
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
// Duplicate points on baffles that are on more than one cell
// region. This will help snapping pull them to separate surfaces.
meshRefiner_.dupNonManifoldPoints();
// Merge all baffles that are still remaining after duplicating points.
List<labelPair> couples
(
meshRefiner_.getDuplicateFaces // get all baffles
(
identity(mesh.nFaces()-mesh.nInternalFaces())
+ mesh.nInternalFaces()
)
);
label nCouples = returnReduce(couples.size(), sumOp<label>());
Info<< "Detected unsplittable baffles : "
<< nCouples << endl;
if (nCouples > 0)
{
// Actually merge baffles. Note: not exactly parallellized. Should
// convert baffle faces into processor faces if they resulted
// from them.
meshRefiner_.mergeBaffles(couples);
if (debug)
{
// Debug:test all is still synced across proc patches
meshRefiner_.checkData();
}
Info<< "Merged free-standing baffles in = "
<< mesh.time().cpuTimeIncrement() << " s." << endl;
}
if (debug)
{
Pout<< "Writing handleProblemCells mesh to time "
<< meshRefiner_.timeName() << '.' << endl;
meshRefiner_.write(debug, mesh.time().path()/meshRefiner_.timeName());
}
}
void Foam::autoRefineDriver::mergePatchFaces
(
const refinementParameters& refineParams
)
{
const fvMesh& mesh = meshRefiner_.mesh();
Info<< nl
<< "Merge refined boundary faces" << nl
<< "----------------------------" << nl
<< endl;
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
meshRefiner_.mergePatchFaces
(
Foam::cos(45*mathematicalConstant::pi/180.0),
Foam::cos(45*mathematicalConstant::pi/180.0),
meshRefiner_.meshedPatches()
);
if (debug)
{
meshRefiner_.checkData();
}
meshRefiner_.mergeEdges(Foam::cos(45*mathematicalConstant::pi/180.0));
if (debug)
{
meshRefiner_.checkData();
}
}
void Foam::autoRefineDriver::doRefine
(
const dictionary& refineDict,
const refinementParameters& refineParams,
const bool prepareForSnapping,
const dictionary& motionDict
)
{
Info<< nl
<< "Refinement phase" << nl
<< "----------------" << nl
<< endl;
const fvMesh& mesh = meshRefiner_.mesh();
// Check that all the keep points are inside the mesh.
refineParams.findCells(mesh);
PtrList<dictionary> featDicts(refineDict.lookup("features"));
// Refine around feature edges
featureEdgeRefine
(
refineParams,
featDicts,
100, // maxIter
0 // min cells to refine
);
// Refine based on surface
surfaceOnlyRefine
(
refineParams,
100 // maxIter
);
// Remove cells (a certain distance) beyond surface intersections
removeInsideCells
(
refineParams,
1 // nBufferLayers
);
// Internal mesh refinement
shellRefine
(
refineParams,
100 // maxIter
);
// Introduce baffles at surface intersections
baffleAndSplitMesh(refineParams, prepareForSnapping, motionDict);
// Mesh is at its finest. Do optional zoning.
zonify(refineParams);
// Pull baffles apart
splitAndMergeBaffles(refineParams, prepareForSnapping, motionDict);
// Do something about cells with refined faces on the boundary
if (prepareForSnapping)
{
mergePatchFaces(refineParams);
}
if (Pstream::parRun())
{
Info<< nl
<< "Doing final balancing" << nl
<< "---------------------" << nl
<< endl;
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
// Do final balancing. Keep zoned faces on one processor since the
// snap phase will convert them to baffles and this only works for
// internal faces.
meshRefiner_.balance
(
true,
false,
scalarField(mesh.nCells(), 1), // dummy weights
decomposer_,
distributor_
);
}
}
// ************************************************************************* //

View file

@ -0,0 +1,183 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::autoRefineDriver
Description
SourceFiles
autoRefineDriver.C
\*---------------------------------------------------------------------------*/
#ifndef autoRefineDriver_H
#define autoRefineDriver_H
#include "treeBoundBox.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class featureEdgeMesh;
class refinementParameters;
class meshRefinement;
class decompositionMethod;
class fvMeshDistribute;
/*---------------------------------------------------------------------------*\
Class autoRefineDriver Declaration
\*---------------------------------------------------------------------------*/
class autoRefineDriver
{
// Private data
//- Mesh+surface
meshRefinement& meshRefiner_;
//- Reference to decomposition method
decompositionMethod& decomposer_;
//- Reference to mesh distribution engine
fvMeshDistribute& distributor_;
//- From surface region to patch
const labelList globalToPatch_;
// Private Member Functions
//- Read explicit feature edges
label readFeatureEdges
(
const PtrList<dictionary>& featDicts,
PtrList<featureEdgeMesh>& featureMeshes,
labelList& featureLevel
) const;
//- Refine all cells pierced by explicit feature edges
label featureEdgeRefine
(
const refinementParameters& refineParams,
const PtrList<dictionary>& featDicts,
const label maxIter,
const label minRefine
);
//- Refine all cells interacting with the surface
label surfaceOnlyRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Remove all cells within intersected region
void removeInsideCells
(
const refinementParameters& refineParams,
const label nBufferLayers
);
//- Remove all cells inside/outside shell
label shellRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Add baffles and remove unreachable cells
void baffleAndSplitMesh
(
const refinementParameters& refineParams,
const bool handleSnapProblems,
const dictionary& motionDict
);
//- Add zones
void zonify(const refinementParameters& refineParams);
void splitAndMergeBaffles
(
const refinementParameters& refineParams,
const bool handleSnapProblems,
const dictionary& motionDict
);
//- Merge refined boundary faces (from exposing coarser cell)
void mergePatchFaces
(
const refinementParameters& refineParams
);
//- Disallow default bitwise copy construct
autoRefineDriver(const autoRefineDriver&);
//- Disallow default bitwise assignment
void operator=(const autoRefineDriver&);
public:
//- Runtime type information
ClassName("autoRefineDriver");
// Constructors
//- Construct from components
autoRefineDriver
(
meshRefinement& meshRefiner,
decompositionMethod& decomposer,
fvMeshDistribute& distributor,
const labelList& globalToPatch
);
// Member Functions
//- Do all the refinement
void doRefine
(
const dictionary& refineDict,
const refinementParameters& refineParams,
const bool prepareForSnapping,
const dictionary& motionDict
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,242 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::autoSnapDriver
Description
All to do with snapping to surface
SourceFiles
autoSnapDriver.C
\*---------------------------------------------------------------------------*/
#ifndef autoSnapDriver_H
#define autoSnapDriver_H
#include "PackedBoolList.H"
#include "meshRefinement.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class motionSmoother;
class snapParameters;
/*---------------------------------------------------------------------------*\
Class autoSnapDriver Declaration
\*---------------------------------------------------------------------------*/
class autoSnapDriver
{
// Private classes
//- Combine operator class for equalizing displacements.
class minMagEqOp
{
public:
void operator()(vector& x, const vector& y) const
{
if (magSqr(y) < magSqr(x))
{
x = y;
}
}
};
// Private data
//- Mesh+surface
meshRefinement& meshRefiner_;
//- From surface region to patch
const labelList globalToPatch_;
// Private Member Functions
// Snapping
//- Get faces to repatch. Returns map from face to patch.
Map<label> getZoneBafflePatches(const bool allowBoundary) const;
//- Calculates (geometric) shared points
static label getCollocatedPoints
(
const scalar tol,
const pointField&,
PackedBoolList&
);
//- Calculate displacement per patch point to smooth out patch.
// Quite complicated in determining which points to move where.
pointField smoothPatchDisplacement
(
const motionSmoother&,
const List<labelPair>&
) const;
//- Check that face zones are synced
void checkCoupledFaceZones() const;
//- Per edge distance to patch
static tmp<scalarField> edgePatchDist
(
const pointMesh&,
const indirectPrimitivePatch&
);
//- Write displacement as .obj file.
static void dumpMove
(
const fileName&,
const pointField&,
const pointField&
);
//- Check displacement is outwards pointing
static bool outwardsDisplacement
(
const indirectPrimitivePatch&,
const vectorField&
);
//- Disallow default bitwise copy construct
autoSnapDriver(const autoSnapDriver&);
//- Disallow default bitwise assignment
void operator=(const autoSnapDriver&);
public:
//- Runtime type information
ClassName("autoSnapDriver");
// Constructors
//- Construct from components
autoSnapDriver
(
meshRefinement& meshRefiner,
const labelList& globalToPatch
);
// Member Functions
// Snapping
//- Create baffles for faces straddling zoned surfaces. Return
// baffles.
autoPtr<mapPolyMesh> createZoneBaffles(List<labelPair>&);
//- Merge baffles.
autoPtr<mapPolyMesh> mergeZoneBaffles(const List<labelPair>&);
//- Calculate edge length per patch point.
scalarField calcSnapDistance
(
const snapParameters& snapParams,
const indirectPrimitivePatch&
) const;
//- Smooth the mesh (patch and internal) to increase visibility
// of surface points (on castellated mesh) w.r.t. surface.
void preSmoothPatch
(
const snapParameters& snapParams,
const label nInitErrors,
const List<labelPair>& baffles,
motionSmoother&
) const;
//- Get points both on patch and facezone.
labelList getZoneSurfacePoints
(
const indirectPrimitivePatch&,
const word& zoneName
) const;
//- Per patch point calculate point on nearest surface. Set as
// boundary conditions of motionSmoother displacement field. Return
// displacement of patch points.
vectorField calcNearestSurface
(
const scalarField& snapDist,
motionSmoother& meshMover
) const;
//- Smooth the displacement field to the internal.
void smoothDisplacement
(
const snapParameters& snapParams,
motionSmoother&
) const;
//- Do the hard work: move the mesh according to displacement,
// locally relax the displacement.
void scaleMesh
(
const snapParameters& snapParams,
const label nInitErrors,
const List<labelPair>& baffles,
motionSmoother&
);
//- Repatch faces according to surface nearest the face centre
autoPtr<mapPolyMesh> repatchToSurface
(
const snapParameters& snapParams,
const labelList& adaptPatchIDs
);
void doSnap
(
const dictionary& snapDict,
const dictionary& motionDict,
const snapParameters& snapParams
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,384 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "layerParameters.H"
#include "polyBoundaryMesh.H"
#include "mathematicalConstants.H"
#include "refinementSurfaces.H"
#include "searchableSurfaces.H"
#include "regExp.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Read the number of layers from dictionary. Per patch 0 or the number
// of layers.
Foam::labelList Foam::layerParameters::readNumLayers
(
const PtrList<dictionary>& surfaceDicts,
const refinementSurfaces& refineSurfaces,
const labelList& globalToPatch,
const polyBoundaryMesh& boundaryMesh
)
{
// Per surface the number of layers
labelList globalSurfLayers(surfaceDicts.size());
// Per surface, per region the number of layers
List<Map<label> > regionSurfLayers(surfaceDicts.size());
const labelList& surfaceIndices = refineSurfaces.surfaces();
forAll(surfaceDicts, surfI)
{
const dictionary& dict = surfaceDicts[surfI];
globalSurfLayers[surfI] = readLabel(dict.lookup("surfaceLayers"));
if (dict.found("regions"))
{
// Per-region layer information
PtrList<dictionary> regionDicts(dict.lookup("regions"));
const wordList& regionNames =
refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
forAll(regionDicts, dictI)
{
const dictionary& regionDict = regionDicts[dictI];
const word regionName(regionDict.lookup("name"));
label regionI = findIndex(regionNames, regionName);
label nLayers = readLabel(regionDict.lookup("surfaceLayers"));
Info<< " region " << regionName << ':'<< nl
<< " surface layers:" << nLayers << nl;
regionSurfLayers[surfI].insert(regionI, nLayers);
}
}
}
// Transfer per surface/region information into patchwise region info
labelList nLayers(boundaryMesh.size(), 0);
forAll(surfaceIndices, surfI)
{
const wordList& regionNames =
refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
forAll(regionNames, regionI)
{
const word& regionName = regionNames[regionI];
label global = refineSurfaces.globalRegion(surfI, regionI);
label patchI = globalToPatch[global];
// Initialise to surface-wise layers
nLayers[patchI] = globalSurfLayers[surfI];
// Override with region specific data if available
Map<label>::const_iterator iter =
regionSurfLayers[surfI].find(regionI);
if (iter != regionSurfLayers[surfI].end())
{
nLayers[patchI] = iter();
}
// Check
if (nLayers[patchI] < 0)
{
FatalErrorIn
(
"layerParameters::readNumLayers(..)"
) << "Illegal number of layers " << nLayers[patchI]
<< " for surface "
<< refineSurfaces.names()[surfI]
<< " region " << regionName << endl
<< exit(FatalError);
}
}
}
return nLayers;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::layerParameters::layerParameters
(
const PtrList<dictionary>& surfaceDicts,
const refinementSurfaces& refineSurfaces,
const labelList& globalToPatch,
const dictionary& dict,
const polyBoundaryMesh& boundaryMesh
)
:
numLayers_
(
readNumLayers
(
surfaceDicts,
refineSurfaces,
globalToPatch,
boundaryMesh
)
),
expansionRatio_
(
numLayers_.size(),
readScalar(dict.lookup("expansionRatio"))
),
relativeSizes_(false),
finalLayerThickness_
(
numLayers_.size(),
readScalar(dict.lookup("finalLayerRatio"))
),
minThickness_
(
numLayers_.size(),
readScalar(dict.lookup("minThickness"))
),
featureAngle_(readScalar(dict.lookup("featureAngle"))),
concaveAngle_
(
dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)
),
nGrow_(readLabel(dict.lookup("nGrow"))),
nSmoothSurfaceNormals_
(
readLabel(dict.lookup("nSmoothSurfaceNormals"))
),
nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
maxFaceThicknessRatio_
(
readScalar(dict.lookup("maxFaceThicknessRatio"))
),
layerTerminationCos_
(
Foam::cos
(
0.5
* featureAngle_
* mathematicalConstant::pi/180.
)
),
maxThicknessToMedialRatio_
(
readScalar(dict.lookup("maxThicknessToMedialRatio"))
),
minMedianAxisAngleCos_
(
Foam::cos(readScalar(dict.lookup("minMedianAxisAngle")))
* mathematicalConstant::pi/180.
),
nBufferCellsNoExtrude_
(
readLabel(dict.lookup("nBufferCellsNoExtrude"))
),
nSnap_(readLabel(dict.lookup("nSnap"))),
nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
nRelaxedIter_(labelMax)
{
if (dict.found("nRelaxedIter"))
{
dict.lookup("nRelaxedIter") >> nRelaxedIter_;
}
if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
{
FatalErrorIn("layerParameters::layerParameters(..)")
<< "Layer iterations should be >= 0." << endl
<< "nLayerIter:" << nLayerIter_
<< " nRelaxedIter:" << nRelaxedIter_
<< exit(FatalError);
}
}
// Construct from dictionary
Foam::layerParameters::layerParameters
(
const dictionary& dict,
const polyBoundaryMesh& boundaryMesh
)
:
numLayers_(boundaryMesh.size(), 0),
expansionRatio_
(
boundaryMesh.size(),
readScalar(dict.lookup("expansionRatio"))
),
relativeSizes_(dict.lookup("relativeSizes")),
finalLayerThickness_
(
boundaryMesh.size(),
readScalar(dict.lookup("finalLayerThickness"))
),
minThickness_
(
boundaryMesh.size(),
readScalar(dict.lookup("minThickness"))
),
featureAngle_(readScalar(dict.lookup("featureAngle"))),
concaveAngle_
(
dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)
),
nGrow_(readLabel(dict.lookup("nGrow"))),
nSmoothSurfaceNormals_
(
readLabel(dict.lookup("nSmoothSurfaceNormals"))
),
nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
maxFaceThicknessRatio_
(
readScalar(dict.lookup("maxFaceThicknessRatio"))
),
layerTerminationCos_
(
Foam::cos
(
0.5
* featureAngle_
* mathematicalConstant::pi/180.
)
),
maxThicknessToMedialRatio_
(
readScalar(dict.lookup("maxThicknessToMedialRatio"))
),
minMedianAxisAngleCos_
(
Foam::cos(readScalar(dict.lookup("minMedianAxisAngle")))
* mathematicalConstant::pi/180.
),
nBufferCellsNoExtrude_
(
readLabel(dict.lookup("nBufferCellsNoExtrude"))
),
nSnap_(readLabel(dict.lookup("nRelaxIter"))),
nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
nRelaxedIter_(labelMax)
{
if (dict.found("nRelaxedIter"))
{
dict.lookup("nRelaxedIter") >> nRelaxedIter_;
}
if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
{
FatalErrorIn("layerParameters::layerParameters(..)")
<< "Layer iterations should be >= 0." << endl
<< "nLayerIter:" << nLayerIter_
<< " nRelaxedIter:" << nRelaxedIter_
<< exit(FatalError);
}
const dictionary& layersDict = dict.subDict("layers");
forAll(boundaryMesh, patchI)
{
const word& patchName = boundaryMesh[patchI].name();
if (layersDict.found(patchName))
{
const dictionary& layerDict = layersDict.subDict(patchName);
numLayers_[patchI] =
readLabel(layerDict.lookup("nSurfaceLayers"));
layerDict.readIfPresent
(
"expansionRatio",
expansionRatio_[patchI]
);
layerDict.readIfPresent
(
"finalLayerThickness",
finalLayerThickness_[patchI]
);
layerDict.readIfPresent
(
"minThickness",
minThickness_[patchI]
);
}
}
// Check whether layer specification matches any patches
const List<keyType> wildCards = layersDict.keys(true);
forAll(wildCards, i)
{
regExp re(wildCards[i]);
bool hasMatch = false;
forAll(boundaryMesh, patchI)
{
if (re.match(boundaryMesh[patchI].name()))
{
hasMatch = true;
break;
}
}
if (!hasMatch)
{
IOWarningIn("layerParameters::layerParameters(..)", layersDict)
<< "Wildcard layer specification for " << wildCards[i]
<< " does not match any patch." << endl;
}
}
const List<keyType> nonWildCards = layersDict.keys(false);
forAll(nonWildCards, i)
{
if (boundaryMesh.findPatchID(nonWildCards[i]) == -1)
{
IOWarningIn("layerParameters::layerParameters(..)", layersDict)
<< "Layer specification for " << nonWildCards[i]
<< " does not match any patch." << endl;
}
}
}
// ************************************************************************* //

View file

@ -0,0 +1,290 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::layerParameters
Description
Simple container to keep together layer specific information.
SourceFiles
layerParameters.C
\*---------------------------------------------------------------------------*/
#ifndef layerParameters_H
#define layerParameters_H
#include "dictionary.H"
#include "scalarField.H"
#include "labelList.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Class forward declarations
class polyBoundaryMesh;
class refinementSurfaces;
/*---------------------------------------------------------------------------*\
Class layerParameters Declaration
\*---------------------------------------------------------------------------*/
class layerParameters
{
// Static data members
//- Default angle for faces to be convcave
static const scalar defaultConcaveAngle;
// Private data
// Per patch (not region!) information
//- How many layers to add.
labelList numLayers_;
scalarField expansionRatio_;
Switch relativeSizes_;
scalarField finalLayerThickness_;
scalarField minThickness_;
scalar featureAngle_;
scalar concaveAngle_;
label nGrow_;
label nSmoothSurfaceNormals_;
label nSmoothNormals_;
label nSmoothThickness_;
scalar maxFaceThicknessRatio_;
scalar layerTerminationCos_;
scalar maxThicknessToMedialRatio_;
scalar minMedianAxisAngleCos_;
label nBufferCellsNoExtrude_;
label nSnap_;
label nLayerIter_;
label nRelaxedIter_;
// Private Member Functions
//- Extract patch-wise number of layers
static labelList readNumLayers
(
const PtrList<dictionary>& surfaceDicts,
const refinementSurfaces& refineSurfaces,
const labelList& globalToPatch,
const polyBoundaryMesh& boundaryMesh
);
//- Disallow default bitwise copy construct
layerParameters(const layerParameters&);
//- Disallow default bitwise assignment
void operator=(const layerParameters&);
public:
// Constructors
//- Construct from dictionary - old syntax
layerParameters
(
const PtrList<dictionary>& surfaceDicts,
const refinementSurfaces& refineSurfaces,
const labelList& globalToPatch,
const dictionary& dict,
const polyBoundaryMesh& boundaryMesh
);
//- Construct from dictionary - new syntax
layerParameters(const dictionary& dict, const polyBoundaryMesh&);
// Member Functions
// Access
// Per patch information
//- How many layers to add.
const labelList& numLayers() const
{
return numLayers_;
}
// Expansion factor for layer mesh
const scalarField& expansionRatio() const
{
return expansionRatio_;
}
//- Are size parameters relative to inner cell size or
// absolute distances.
bool relativeSizes() const
{
return relativeSizes_;
}
//- Wanted thickness of final added cell layer. If multiple
// layers is the thickness of the layer furthest away
// from the wall (i.e. nearest the original mesh)
// If relativeSize() this number is relative to undistorted
// size of the cell outside layer.
const scalarField& finalLayerThickness() const
{
return finalLayerThickness_;
}
//- Minimum thickness of cell layer. If for any reason layer
// cannot be above minThickness do not add layer.
// If relativeSize() this number is relative to undistorted
// size of the cell outside layer.
const scalarField& minThickness() const
{
return minThickness_;
}
scalar featureAngle() const
{
return featureAngle_;
}
scalar concaveAngle() const
{
return concaveAngle_;
}
//- If points get not extruded do nGrow layers of connected faces
// that are not grown. Is used to not do layers at all close to
// features.
label nGrow() const
{
return nGrow_;
}
//- Number of smoothing iterations of surface normals
label nSmoothSurfaceNormals() const
{
return nSmoothSurfaceNormals_;
}
//- Number of smoothing iterations of interior mesh movement
// direction
label nSmoothNormals() const
{
return nSmoothNormals_;
}
//- Stop layer growth on highly warped cells
scalar maxFaceThicknessRatio() const
{
return maxFaceThicknessRatio_;
}
scalar layerTerminationCos() const
{
return layerTerminationCos_;
}
//- Smooth layer thickness over surface patches
label nSmoothThickness() const
{
return nSmoothThickness_;
}
//- Reduce layer growth where ratio thickness to medial
// distance is large
scalar maxThicknessToMedialRatio() const
{
return maxThicknessToMedialRatio_;
}
//- Angle used to pick up medial axis points
scalar minMedianAxisAngleCos() const
{
return minMedianAxisAngleCos_;
}
//- Create buffer region for new layer terminations
label nBufferCellsNoExtrude() const
{
return nBufferCellsNoExtrude_;
}
label nSnap() const
{
return nSnap_;
}
// Overall
//- Number of overall layer addition iterations
label nLayerIter() const
{
return nLayerIter_;
}
//- Number of iterations after which relaxed motion rules
// are to be used.
label nRelaxedIter() const
{
return nRelaxedIter_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -21,35 +21,30 @@ License
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::curvedEdgeList
Description
A PtrList of curvedEdges
\*---------------------------------------------------------------------------*/
#ifndef curvedEdgeList_H
#define curvedEdgeList_H
#include "pointData.H"
#include "curvedEdge.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
Foam::Ostream& Foam::operator<<(Ostream& os, const pointData& wDist)
{
if (os.format() == IOstream::ASCII)
{
return os
<< wDist.origin() << token::SPACE << wDist.distSqr()
<< token::SPACE << wDist.s() << token::SPACE << wDist.v();
}
else
{
return os
<< wDist.origin() << wDist.distSqr() << wDist.s() << wDist.v();
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef PtrList<curvedEdge> curvedEdgeList;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
Foam::Istream& Foam::operator>>(Istream& is, pointData& wDist)
{
return is >> wDist.origin_ >> wDist.distSqr_ >> wDist.s_ >> wDist.v_;
}
// ************************************************************************* //

View file

@ -0,0 +1,226 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::pointData
Description
Holds information regarding nearest wall point. Used in pointEdgeWave.
(so not standard meshWave)
To be used in wall distance calculation.
SourceFiles
pointDataI.H
pointData.C
\*---------------------------------------------------------------------------*/
#ifndef pointData_H
#define pointData_H
#include "point.H"
#include "label.H"
#include "tensor.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Class forward declarations
class polyPatch;
class polyMesh;
/*---------------------------------------------------------------------------*\
Class pointData Declaration
\*---------------------------------------------------------------------------*/
class pointData
{
// Private data
//- position of nearest wall center
point origin_;
//- normal distance (squared) from point to origin
scalar distSqr_;
//- additional information.
scalar s_;
//- additional information.
vector v_;
// Private Member Functions
//- Evaluate distance to point. Update distSqr, origin from whomever
// is nearer pt. Return true if w2 is closer to point,
// false otherwise.
inline bool update
(
const point&,
const pointData& w2,
const scalar tol
);
//- Combine current with w2. Update distSqr, origin if w2 has smaller
// quantities and returns true.
inline bool update
(
const pointData& w2,
const scalar tol
);
public:
// Constructors
//- Construct null
inline pointData();
//- Construct from origin, distance
inline pointData
(
const point& origin,
const scalar distSqr,
const scalar s,
const vector& v
);
//- Construct as copy
inline pointData(const pointData&);
// Member Functions
// Access
inline const point& origin() const;
inline scalar distSqr() const;
inline scalar s() const;
inline const vector& v() const;
// Needed by meshWave
//- Check whether origin has been changed at all or
// still contains original (invalid) value.
inline bool valid() const;
//- Check for identical geometrical data. Used for cyclics checking.
inline bool sameGeometry(const pointData&, const scalar tol)
const;
//- Convert origin to relative vector to leaving point
// (= point coordinate)
inline void leaveDomain
(
const polyPatch& patch,
const label patchPointI,
const point& pos
);
//- Convert relative origin to absolute by adding entering point
inline void enterDomain
(
const polyPatch& patch,
const label patchPointI,
const point& pos
);
//- Apply rotation matrix to origin
inline void transform(const tensor& rotTensor);
//- Influence of edge on point
inline bool updatePoint
(
const polyMesh& mesh,
const label pointI,
const label edgeI,
const pointData& edgeInfo,
const scalar tol
);
//- Influence of different value on same point.
// Merge new and old info.
inline bool updatePoint
(
const polyMesh& mesh,
const label pointI,
const pointData& newPointInfo,
const scalar tol
);
//- Influence of different value on same point.
// No information about current position whatsoever.
inline bool updatePoint
(
const pointData& newPointInfo,
const scalar tol
);
//- Influence of point on edge.
inline bool updateEdge
(
const polyMesh& mesh,
const label edgeI,
const label pointI,
const pointData& pointInfo,
const scalar tol
);
// Member Operators
//Note: Used to determine whether to call update.
inline bool operator==(const pointData&) const;
inline bool operator!=(const pointData&) const;
// IOstream Operators
friend Ostream& operator<<(Ostream&, const pointData&);
friend Istream& operator>>(Istream&, pointData&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "pointDataI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,353 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "polyMesh.H"
#include "transform.H"
#include "wallPoint.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Update this with w2 if w2 nearer to pt.
inline bool Foam::pointData::update
(
const point& pt,
const pointData& w2,
const scalar tol
)
{
scalar dist2 = magSqr(pt - w2.origin());
if (!valid())
{
distSqr_ = dist2;
origin_ = w2.origin();
s_ = w2.s();
v_ = w2.v();
return true;
}
// if (v_ != w2.v())
// {
// return false;
// }
scalar diff = distSqr_ - dist2;
if (diff < 0)
{
// already nearer to pt
return false;
}
if ((diff < SMALL) || ((distSqr_ > SMALL) && (diff/distSqr_ < tol)))
{
// don't propagate small changes
return false;
}
else
{
// update with new values
distSqr_ = dist2;
origin_ = w2.origin();
s_ = w2.s();
v_ = w2.v();
return true;
}
}
// Update this with w2 (information on same point)
inline bool Foam::pointData::update
(
const pointData& w2,
const scalar tol
)
{
if (!valid())
{
// current not yet set so use any value
distSqr_ = w2.distSqr();
origin_ = w2.origin();
s_ = w2.s();
v_ = w2.v();
return true;
}
// if (v_ != w2.v())
// {
// return false;
// }
scalar diff = distSqr_ - w2.distSqr();
if (diff < 0)
{
// already nearer to pt
return false;
}
if ((diff < SMALL) || ((distSqr_ > SMALL) && (diff/distSqr_ < tol)))
{
// don't propagate small changes
return false;
}
else
{
// update with new values
distSqr_ = w2.distSqr();
origin_ = w2.origin();
s_ = w2.s();
v_ = w2.v();
return true;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Null constructor
inline Foam::pointData::pointData()
:
origin_(wallPoint::greatPoint),
distSqr_(GREAT),
s_(GREAT),
v_(wallPoint::greatPoint)
{}
// Construct from origin, distance
inline Foam::pointData::pointData
(
const point& origin,
const scalar distSqr,
const scalar s,
const vector& v
)
:
origin_(origin),
distSqr_(distSqr),
s_(s),
v_(v)
{}
// Construct as copy
inline Foam::pointData::pointData(const pointData& wpt)
:
origin_(wpt.origin()),
distSqr_(wpt.distSqr()),
s_(wpt.s()),
v_(wpt.v())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::point& Foam::pointData::origin() const
{
return origin_;
}
inline Foam::scalar Foam::pointData::distSqr() const
{
return distSqr_;
}
inline Foam::scalar Foam::pointData::s() const
{
return s_;
}
inline const Foam::vector& Foam::pointData::v() const
{
return v_;
}
inline bool Foam::pointData::valid() const
{
return origin_ != wallPoint::greatPoint;
}
// Checks for cyclic points
inline bool Foam::pointData::sameGeometry
(
const pointData& w2,
const scalar tol
) const
{
scalar diff = Foam::mag(distSqr() - w2.distSqr());
if (diff < SMALL)
{
return true;
}
else
{
if ((distSqr() > SMALL) && ((diff/distSqr()) < tol))
{
return true;
}
else
{
return false;
}
}
}
inline void Foam::pointData::leaveDomain
(
const polyPatch& patch,
const label patchPointI,
const point& coord
)
{
origin_ -= coord;
}
inline void Foam::pointData::transform(const tensor& rotTensor)
{
origin_ = Foam::transform(rotTensor, origin_);
}
// Update absolute geometric quantities. Note that distance (distSqr_)
// is not affected by leaving/entering domain.
inline void Foam::pointData::enterDomain
(
const polyPatch& patch,
const label patchPointI,
const point& coord
)
{
// back to absolute form
origin_ += coord;
}
// Update this with information from connected edge
inline bool Foam::pointData::updatePoint
(
const polyMesh& mesh,
const label pointI,
const label edgeI,
const pointData& edgeInfo,
const scalar tol
)
{
return
update
(
mesh.points()[pointI],
edgeInfo,
tol
);
}
// Update this with new information on same point
inline bool Foam::pointData::updatePoint
(
const polyMesh& mesh,
const label pointI,
const pointData& newPointInfo,
const scalar tol
)
{
return
update
(
mesh.points()[pointI],
newPointInfo,
tol
);
}
// Update this with new information on same point. No extra information.
inline bool Foam::pointData::updatePoint
(
const pointData& newPointInfo,
const scalar tol
)
{
return update(newPointInfo, tol);
}
// Update this with information from connected point
inline bool Foam::pointData::updateEdge
(
const polyMesh& mesh,
const label edgeI,
const label pointI,
const pointData& pointInfo,
const scalar tol
)
{
const pointField& points = mesh.points();
const edge& e = mesh.edges()[edgeI];
const point edgeMid(0.5*(points[e[0]] + points[e[1]]));
return
update
(
edgeMid,
pointInfo,
tol
);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline bool Foam::pointData::operator==(const pointData& rhs) const
{
return origin() == rhs.origin();
}
inline bool Foam::pointData::operator!=(const pointData& rhs) const
{
return !(*this == rhs);
}
// ************************************************************************* //

View file

@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "refinementParameters.H"
#include "mathematicalConstants.H"
#include "polyMesh.H"
#include "globalIndex.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::refinementParameters::refinementParameters
(
const dictionary& dict,
const label dummy
)
:
maxGlobalCells_(readLabel(dict.lookup("cellLimit"))),
maxLocalCells_(readLabel(dict.lookup("procCellLimit"))),
minRefineCells_(readLabel(dict.lookup("minimumRefine"))),
curvature_(readScalar(dict.lookup("curvature"))),
nBufferLayers_(readLabel(dict.lookup("nBufferLayers"))),
keepPoints_(dict.lookup("keepPoints")),
allowFreeStandingZoneFaces_
(
dict.lookupOrDefault<Switch>
(
"allowFreeStandingZoneFaces",
true
)
),
maxLoadUnbalance_(dict.lookupOrDefault<scalar>("maxLoadUnbalance",0))
{}
Foam::refinementParameters::refinementParameters(const dictionary& dict)
:
maxGlobalCells_(readLabel(dict.lookup("maxGlobalCells"))),
maxLocalCells_(readLabel(dict.lookup("maxLocalCells"))),
minRefineCells_(readLabel(dict.lookup("minRefinementCells"))),
nBufferLayers_(readLabel(dict.lookup("nCellsBetweenLevels"))),
keepPoints_(pointField(1, dict.lookup("locationInMesh"))),
allowFreeStandingZoneFaces_
(
dict.lookupOrDefault<Switch>
(
"allowFreeStandingZoneFaces",
true
)
),
maxLoadUnbalance_(dict.lookupOrDefault<scalar>("maxLoadUnbalance",0))
{
scalar featAngle(readScalar(dict.lookup("resolveFeatureAngle")));
if (featAngle < 0 || featAngle > 180)
{
curvature_ = -GREAT;
}
else
{
curvature_ = Foam::cos(featAngle*mathematicalConstant::pi/180.0);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::labelList Foam::refinementParameters::findCells(const polyMesh& mesh)
const
{
// Global calculation engine
globalIndex globalCells(mesh.nCells());
// Cell label per point
labelList cellLabels(keepPoints_.size());
forAll(keepPoints_, i)
{
const point& keepPoint = keepPoints_[i];
label localCellI = mesh.findCell(keepPoint);
label globalCellI = -1;
if (localCellI != -1)
{
Pout<< "Found point " << keepPoint << " in cell " << localCellI
<< " on processor " << Pstream::myProcNo() << endl;
globalCellI = globalCells.toGlobal(localCellI);
}
reduce(globalCellI, maxOp<label>());
if (globalCellI == -1)
{
FatalErrorIn
(
"refinementParameters::findCells(const polyMesh&) const"
) << "Point " << keepPoint
<< " is not inside the mesh or on a face or edge." << nl
<< "Bounding box of the mesh:" << mesh.bounds()
<< exit(FatalError);
}
if (globalCells.isLocal(globalCellI))
{
cellLabels[i] = localCellI;
}
else
{
cellLabels[i] = -1;
}
}
return cellLabels;
}
// ************************************************************************* //

View file

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::refinementParameters
Description
Simple container to keep together refinement specific information.
SourceFiles
refinementParameters.C
\*---------------------------------------------------------------------------*/
#ifndef refinementParameters_H
#define refinementParameters_H
#include "dictionary.H"
#include "pointField.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Class forward declarations
class polyMesh;
/*---------------------------------------------------------------------------*\
Class refinementParameters Declaration
\*---------------------------------------------------------------------------*/
class refinementParameters
{
// Private data
//- Total number of cells
const label maxGlobalCells_;
//- Per processor max number of cells
const label maxLocalCells_;
//- When to stop refining
const label minRefineCells_;
//- Curvature
scalar curvature_;
//- Number of layers between different refinement levels
const label nBufferLayers_;
//- Areas to keep
const pointField keepPoints_;
//- FaceZone faces allowed which have owner and neighbour in same
// cellZone?
Switch allowFreeStandingZoneFaces_;
//- Allowed load unbalance
scalar maxLoadUnbalance_;
// Private Member Functions
//- Disallow default bitwise copy construct
refinementParameters(const refinementParameters&);
//- Disallow default bitwise assignment
void operator=(const refinementParameters&);
public:
// Constructors
//- Construct from dictionary - old syntax
refinementParameters(const dictionary& dict, const label dummy);
//- Construct from dictionary - new syntax
refinementParameters(const dictionary& dict);
// Member Functions
// Access
//- Total number of cells
label maxGlobalCells() const
{
return maxGlobalCells_;
}
//- Per processor max number of cells
label maxLocalCells() const
{
return maxLocalCells_;
}
//- When to stop refining
label minRefineCells() const
{
return minRefineCells_;
}
//- Curvature
scalar curvature() const
{
return curvature_;
}
//- Number of layers between different refinement levels
label nBufferLayers() const
{
return nBufferLayers_;
}
//- Areas to keep
const pointField& keepPoints() const
{
return keepPoints_;
}
//- Are zone faces allowed only inbetween different cell zones
// or also just free standing?
bool allowFreeStandingZoneFaces() const
{
return allowFreeStandingZoneFaces_;
}
//- Allowed load unbalance
scalar maxLoadUnbalance() const
{
return maxLoadUnbalance_;
}
// Other
//- Checks that cells are in mesh. Returns cells they are in.
labelList findCells(const polyMesh&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -21,39 +21,33 @@ License
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "blockMesh.H"
#include "snapParameters.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::labelList Foam::blockMesh::createBlockOffsets()
{
Info<< nl << "Creating block offsets" << endl;
// Construct from dictionary
Foam::snapParameters::snapParameters(const dictionary& dict, const label dummy)
:
nSmoothPatch_(readLabel(dict.lookup("nSmoothPatch"))),
snapTol_(readScalar(dict.lookup("snapTol"))),
nSmoothDispl_(readLabel(dict.lookup("nSmoothDispl"))),
nSnap_(readLabel(dict.lookup("nSnap")))
{}
blockMesh& blocks = *this;
nPoints_ = blocks[0].points().size();
nCells_ = blocks[0].cells().size();
// Construct from dictionary
Foam::snapParameters::snapParameters(const dictionary& dict)
:
nSmoothPatch_(readLabel(dict.lookup("nSmoothPatch"))),
snapTol_(readScalar(dict.lookup("tolerance"))),
nSmoothDispl_(readLabel(dict.lookup("nSolveIter"))),
nSnap_(readLabel(dict.lookup("nRelaxIter")))
{}
labelList BlockOffsets(blocks.size());
BlockOffsets[0] = 0;
label blockLabel;
for (blockLabel=1; blockLabel<blocks.size(); blockLabel++)
{
nPoints_ += blocks[blockLabel].points().size();
nCells_ += blocks[blockLabel].cells().size();
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
BlockOffsets[blockLabel]
= BlockOffsets[blockLabel-1]
+ blocks[blockLabel-1].points().size();
}
return BlockOffsets;
}
// ************************************************************************* //

View file

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::snapParameters
Description
Simple container to keep together snap specific information.
SourceFiles
snapParameters.C
\*---------------------------------------------------------------------------*/
#ifndef snapParameters_H
#define snapParameters_H
#include "dictionary.H"
#include "scalar.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Class forward declarations
/*---------------------------------------------------------------------------*\
Class snapParameters Declaration
\*---------------------------------------------------------------------------*/
class snapParameters
{
// Private data
const label nSmoothPatch_;
const scalar snapTol_;
const label nSmoothDispl_;
const label nSnap_;
// Private Member Functions
//- Disallow default bitwise copy construct
snapParameters(const snapParameters&);
//- Disallow default bitwise assignment
void operator=(const snapParameters&);
public:
// Constructors
//- Construct from dictionary - old syntax
snapParameters(const dictionary& dict, const label dummy);
//- Construct from dictionary - new syntax
snapParameters(const dictionary& dict);
// Member Functions
// Access
//- Number of patch smoothing iterations before finding
// correspondence to surface
label nSmoothPatch() const
{
return nSmoothPatch_;
}
//- Relative distance for points to be attracted by surface
// feature point
// or edge. True distance is this factor times local
// maximum edge length.
scalar snapTol() const
{
return snapTol_;
}
//- Number of mesh displacement smoothing iterations.
label nSmoothDispl() const
{
return nSmoothDispl_;
}
//- Maximum number of snapping relaxation iterations. Should stop
// before upon reaching a correct mesh.
label nSnap() const
{
return nSnap_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,841 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::meshRefinement
Description
Helper class which maintains intersections of (changing) mesh with
(static) surfaces.
Maintains
- per face any intersections of the cc-cc segment with any of the surfaces
SourceFiles
meshRefinement.C
meshRefinementBaffles.C
meshRefinementMerge.C
meshRefinementProblemCells.C
meshRefinementRefine.C
\*---------------------------------------------------------------------------*/
#ifndef meshRefinement_H
#define meshRefinement_H
#include "hexRef8.H"
#include "mapPolyMesh.H"
#include "autoPtr.H"
#include "labelPair.H"
#include "indirectPrimitivePatch.H"
#include "pointFieldsFwd.H"
#include "Tuple2.H"
#include "pointIndexHit.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Class forward declarations
class fvMesh;
class mapDistributePolyMesh;
class decompositionMethod;
class refinementSurfaces;
class shellSurfaces;
class removeCells;
class featureEdgeMesh;
class fvMeshDistribute;
class searchableSurface;
class regionSplit;
class globalIndex;
/*---------------------------------------------------------------------------*\
Class meshRefinement Declaration
\*---------------------------------------------------------------------------*/
class meshRefinement
{
public:
// Public data types
//- Enumeration for debug dumping
enum writeFlag
{
MESH = 1,
SCALARLEVELS = 2,
OBJINTERSECTIONS = 4
};
//- Enumeration for how the userdata is to be mapped upon refinement.
enum mapType
{
MASTERONLY = 1, /*!< maintain master only */
KEEPALL = 2, /*!< have slaves (upon refinement) from master */
REMOVE = 4 /*!< set value to -1 any face that was refined */
};
private:
// Private data
//- Reference to mesh
fvMesh& mesh_;
//- tolerance used for sorting coordinates (used in 'less' routine)
const scalar mergeDistance_;
//- overwrite the mesh?
const bool overwrite_;
//- Instance of mesh upon construction. Used when in overwrite_ mode.
const word oldInstance_;
//- All surface-intersection interaction
const refinementSurfaces& surfaces_;
//- All shell-refinement interaction
const shellSurfaces& shells_;
//- refinement engine
hexRef8 meshCutter_;
//- per cc-cc vector the index of the surface hit
labelIOList surfaceIndex_;
//- user supplied face based data.
List<Tuple2<mapType, labelList> > userFaceData_;
//- Meshed patches - are treated differently. Stored as wordList since
// order changes.
wordList meshedPatches_;
// Private Member Functions
//- Reorder list according to map.
template<class T>
static void updateList
(
const labelList& newToOld,
const T& nullValue,
List<T>& elems
);
//- Add patchfield of given type to all fields on mesh
template<class GeoField>
static void addPatchFields(fvMesh&, const word& patchFieldType);
//- Reorder patchfields of all fields on mesh
template<class GeoField>
static void reorderPatchFields(fvMesh&, const labelList& oldToNew);
//- Find out which faces have changed given cells (old mesh labels)
// that were marked for refinement.
static labelList getChangedFaces
(
const mapPolyMesh&,
const labelList& oldCellsToRefine
);
//- Calculate coupled boundary end vector and refinement level
void calcNeighbourData
(
labelList& neiLevel,
pointField& neiCc
) const;
//- Find any intersection of surface. Store in surfaceIndex_.
void updateIntersections(const labelList& changedFaces);
//- Remove cells. Put exposedFaces into exposedPatchIDs.
autoPtr<mapPolyMesh> doRemoveCells
(
const labelList& cellsToRemove,
const labelList& exposedFaces,
const labelList& exposedPatchIDs,
removeCells& cellRemover
);
// Get cells which are inside any closed surface. Note that
// all closed surfaces
// will have already been oriented to have keepPoint outside.
labelList getInsideCells(const word&) const;
// Do all to remove inside cells
autoPtr<mapPolyMesh> removeInsideCells
(
const string& msg,
const label exposedPatchI
);
// For decomposeCombineRegions
//- Used in decomposeCombineRegions. Given global region per cell
// determines master processor/cell for regions straddling
// procboundaries.
void getCoupledRegionMaster
(
const globalIndex& globalCells,
const boolList& blockedFace,
const regionSplit& globalRegion,
Map<label>& regionToMaster
) const;
//- Determine regions that are local to me or coupled ones that
// are owned by me. Determine representative location.
void calcLocalRegions
(
const globalIndex& globalCells,
const labelList& globalRegion,
const Map<label>& coupledRegionToMaster,
const scalarField& cellWeights,
Map<label>& globalToLocalRegion,
pointField& localPoints,
scalarField& localWeights
) const;
//- Convert region into global index.
static label getShiftedRegion
(
const globalIndex& indexer,
const Map<label>& globalToLocalRegion,
const Map<label>& coupledRegionToShifted,
const label globalRegion
);
//- helper: add element if not in list. Linear search.
static void addUnique(const label, labelList&);
//- Calculate region connectivity. Major communication.
void calcRegionRegions
(
const labelList& globalRegion,
const Map<label>& globalToLocalRegion,
const Map<label>& coupledRegionToMaster,
labelListList& regionRegions
) const;
// Refinement candidate selection
//- Mark cell for refinement (if not already marked). Return false
// if refinelimit hit. Keeps running count (in nRefine) of cells
// marked for refinement
static bool markForRefine
(
const label markValue,
const label nAllowRefine,
label& cellValue,
label& nRefine
);
//- Calculate list of cells to refine based on intersection of
// features.
label markFeatureRefinement
(
const point& keepPoint,
const PtrList<featureEdgeMesh>& featureMeshes,
const labelList& featureLevels,
const label nAllowRefine,
labelList& refineCell,
label& nRefine
) const;
//- Mark cells for refinement-shells based refinement.
label markInternalRefinement
(
const label nAllowRefine,
labelList& refineCell,
label& nRefine
) const;
//- Collect faces that are intersected and whose neighbours aren't
// yet marked for refinement.
labelList getRefineCandidateFaces
(
const labelList& refineCell
) const;
//- Mark cells for surface intersection based refinement.
label markSurfaceRefinement
(
const label nAllowRefine,
const labelList& neiLevel,
const pointField& neiCc,
labelList& refineCell,
label& nRefine
) const;
//- Mark cell if local curvature > curvature or
// markDifferingRegions = true and intersections with different
// regions.
bool checkCurvature
(
const scalar curvature,
const label nAllowRefine,
const label surfaceLevel,
const vector& surfaceNormal,
const label cellI,
label& cellMaxLevel,
vector& cellMaxNormal,
labelList& refineCell,
label& nRefine
) const;
//- Mark cells for surface curvature based refinement. Marks if
// local curvature > curvature or if on different regions
// (markDifferingRegions)
label markSurfaceCurvatureRefinement
(
const scalar curvature,
const label nAllowRefine,
const labelList& neiLevel,
const pointField& neiCc,
labelList& refineCell,
label& nRefine
) const;
// Baffle handling
//- Determine patches for baffles
void getBafflePatches
(
const labelList& globalToPatch,
const labelList& neiLevel,
const pointField& neiCc,
labelList& ownPatch,
labelList& neiPatch
) const;
//- Determine patch for baffle using some heuristic (and not
// surface)
label getBafflePatch
(
const labelList& facePatch,
const label faceI
) const;
//- Repatches external face or creates baffle for internal face
// with user specified patches (might be different for both sides).
// Returns label of added face.
label createBaffle
(
const label faceI,
const label ownPatch,
const label neiPatch,
directTopoChange& meshMod
) const;
// Problem cell handling
//- Helper function to mark face as being on 'boundary'. Used by
// markFacesOnProblemCells
void markBoundaryFace
(
const label faceI,
boolList& isBoundaryFace,
boolList& isBoundaryEdge,
boolList& isBoundaryPoint
) const;
void findNearest
(
const labelList& meshFaces,
List<pointIndexHit>& nearestInfo,
labelList& nearestSurface,
labelList& nearestRegion,
vectorField& nearestNormal
) const;
Map<label> findEdgeConnectedProblemCells
(
const scalarField& perpendicularAngle,
const labelList&
) const;
bool isCollapsedFace
(
const pointField&,
const pointField& neiCc,
const scalar minFaceArea,
const scalar maxNonOrtho,
const label faceI
) const;
bool isCollapsedCell
(
const pointField&,
const scalar volFraction,
const label cellI
) const;
//- Returns list with for every internal face -1 or the patch
// they should be baffled into. If removeEdgeConnectedCells is set
// removes cells based on perpendicularAngle.
labelList markFacesOnProblemCells
(
const dictionary& motionDict,
const bool removeEdgeConnectedCells,
const scalarField& perpendicularAngle,
const labelList& globalToPatch
) const;
////- Initial test of marking faces using geometric information.
//labelList markFacesOnProblemCellsGeometric
//(
// const dictionary& motionDict
//) const;
// Baffle merging
//- Extract those baffles (duplicate) faces that are on the edge
// of a baffle region. These are candidates for merging.
List<labelPair> filterDuplicateFaces(const List<labelPair>&) const;
// Zone handling
//- Finds zone per cell for cells inside closed named surfaces.
// (uses geometric test for insideness)
// Adapts namedSurfaceIndex so all faces on boundary of cellZone
// have corresponding faceZone.
void findCellZoneGeometric
(
const labelList& closedNamedSurfaces,
labelList& namedSurfaceIndex,
const labelList& surfaceToCellZone,
labelList& cellToZone
) const;
//- Determines cell zone from cell region information.
bool calcRegionToZone
(
const label surfZoneI,
const label ownRegion,
const label neiRegion,
labelList& regionToCellZone
) const;
//- Finds zone per cell. Uses topological walk with all faces
// marked in namedSurfaceIndex regarded as blocked.
void findCellZoneTopo
(
const point& keepPoint,
const labelList& namedSurfaceIndex,
const labelList& surfaceToCellZone,
labelList& cellToZone
) const;
void makeConsistentFaceIndex
(
const labelList& cellToZone,
labelList& namedSurfaceIndex
) const;
//- Disallow default bitwise copy construct
meshRefinement(const meshRefinement&);
//- Disallow default bitwise assignment
void operator=(const meshRefinement&);
public:
//- Runtime type information
ClassName("meshRefinement");
// Constructors
//- Construct from components
meshRefinement
(
fvMesh& mesh,
const scalar mergeDistance,
const bool overwrite,
const refinementSurfaces&,
const shellSurfaces&
);
// Member Functions
// Access
//- reference to mesh
const fvMesh& mesh() const
{
return mesh_;
}
fvMesh& mesh()
{
return mesh_;
}
scalar mergeDistance() const
{
return mergeDistance_;
}
//- Overwrite the mesh?
bool overwrite() const
{
return overwrite_;
}
//- (points)instance of mesh upon construction
const word& oldInstance() const
{
return oldInstance_;
}
//- reference to surface search engines
const refinementSurfaces& surfaces() const
{
return surfaces_;
}
//- reference to refinement shells (regions)
const shellSurfaces& shells() const
{
return shells_;
}
//- reference to meshcutting engine
const hexRef8& meshCutter() const
{
return meshCutter_;
}
//- per start-end edge the index of the surface hit
const labelList& surfaceIndex() const
{
return surfaceIndex_;
}
labelList& surfaceIndex()
{
return surfaceIndex_;
}
//- Additional face data that is maintained across
// topo changes. Every entry is a list over all faces.
// Bit of a hack. Additional flag to say whether to maintain master
// only (false) or increase set to account for face-from-face.
const List<Tuple2<mapType, labelList> >& userFaceData() const
{
return userFaceData_;
}
List<Tuple2<mapType, labelList> >& userFaceData()
{
return userFaceData_;
}
// Other
//- Count number of intersections (local)
label countHits() const;
//- Helper function to get decomposition such that all connected
// regions get moved onto one processor. Used to prevent baffles
// straddling processor boundaries. explicitConnections is to
// keep pairs of non-coupled boundary faces together
// (e.g. to keep baffles together)
labelList decomposeCombineRegions
(
const scalarField& cellWeights,
const boolList& blockedFace,
const List<labelPair>& explicitConnections,
decompositionMethod&
) const;
//- Redecompose according to cell count
// keepZoneFaces : find all faceZones from zoned surfaces and keep
// owner and neighbour together
// keepBaffles : find all baffles and keep them together
autoPtr<mapDistributePolyMesh> balance
(
const bool keepZoneFaces,
const bool keepBaffles,
const scalarField& cellWeights,
decompositionMethod& decomposer,
fvMeshDistribute& distributor
);
//- Get faces with intersection.
labelList intersectedFaces() const;
//- Get points on surfaces with intersection and boundary faces.
labelList intersectedPoints() const;
//- Create patch from set of patches
static autoPtr<indirectPrimitivePatch> makePatch
(
const polyMesh&,
const labelList&
);
//- Helper function to make a pointVectorField with correct
// bcs for mesh movement:
// - adaptPatchIDs : fixedValue
// - processor : calculated (so free to move)
// - cyclic/wedge/symmetry : slip
// - other : slip
static tmp<pointVectorField> makeDisplacementField
(
const pointMesh& pMesh,
const labelList& adaptPatchIDs
);
//- Helper function: check that face zones are synced
static void checkCoupledFaceZones(const polyMesh&);
// Refinement
//- Calculate list of cells to refine.
labelList refineCandidates
(
const point& keepPoint,
const scalar curvature,
const PtrList<featureEdgeMesh>& featureMeshes,
const labelList& featureLevels,
const bool featureRefinement,
const bool internalRefinement,
const bool surfaceRefinement,
const bool curvatureRefinement,
const label maxGlobalCells,
const label maxLocalCells
) const;
//- Refine some cells
autoPtr<mapPolyMesh> refine(const labelList& cellsToRefine);
//- Refine some cells and rebalance
autoPtr<mapDistributePolyMesh> refineAndBalance
(
const string& msg,
decompositionMethod& decomposer,
fvMeshDistribute& distributor,
const labelList& cellsToRefine,
const scalar maxLoadUnbalance
);
//- Balance before refining some cells
autoPtr<mapDistributePolyMesh> balanceAndRefine
(
const string& msg,
decompositionMethod& decomposer,
fvMeshDistribute& distributor,
const labelList& cellsToRefine,
const scalar maxLoadUnbalance
);
// Baffle handling
//- Split off unreachable areas of mesh.
void baffleAndSplitMesh
(
const bool handleSnapProblems,
const bool removeEdgeConnectedCells,
const scalarField& perpendicularAngle,
const bool mergeFreeStanding,
const dictionary& motionDict,
Time& runTime,
const labelList& globalToPatch,
const point& keepPoint
);
//- Split off (with optional buffer layers) unreachable areas
// of mesh. Does not introduce baffles.
autoPtr<mapPolyMesh> splitMesh
(
const label nBufferLayers,
const labelList& globalToPatch,
const point& keepPoint
);
//- Find boundary points that connect to more than one cell
// region and split them.
autoPtr<mapPolyMesh> dupNonManifoldPoints();
//- Create baffle for every internal face where ownPatch != -1.
// External faces get repatched according to ownPatch (neiPatch
// should be -1 for these)
autoPtr<mapPolyMesh> createBaffles
(
const labelList& ownPatch,
const labelList& neiPatch
);
//- Return a list of coupled face pairs, i.e. faces that
// use the same vertices.
List<labelPair> getDuplicateFaces(const labelList& testFaces) const;
//- Merge baffles. Gets pairs of faces.
autoPtr<mapPolyMesh> mergeBaffles(const List<labelPair>&);
//- Put faces/cells into zones according to surface specification.
// Returns null if no zone surfaces present. Region containing
// the keepPoint will not be put into a cellZone.
autoPtr<mapPolyMesh> zonify
(
const point& keepPoint,
const bool allowFreeStandingZoneFaces
);
// Other topo changes
//- Helper:add patch to mesh. Update all registered fields.
// Use addMeshedPatch to add patches originating from surfaces.
static label addPatch(fvMesh&, const word& name, const word& type);
//- Add patch originating from meshing. Update meshedPatches_.
label addMeshedPatch(const word& name, const word& type);
//- Get patchIDs for patches added in addMeshedPatch.
labelList meshedPatches() const;
//- Split mesh. Keep part containing point.
autoPtr<mapPolyMesh> splitMeshRegions(const point& keepPoint);
//- Update local numbering for mesh redistribution
void distribute(const mapDistributePolyMesh&);
//- Update for external change to mesh. changedFaces are in new mesh
// face labels.
void updateMesh
(
const mapPolyMesh&,
const labelList& changedFaces
);
// Restoring : is where other processes delete and reinsert data.
//- Signal points/face/cells for which to store data
void storeData
(
const labelList& pointsToStore,
const labelList& facesToStore,
const labelList& cellsToStore
);
//- Update local numbering + undo
// Data to restore given as new pointlabel + stored pointlabel
// (i.e. what was in pointsToStore)
void updateMesh
(
const mapPolyMesh&,
const labelList& changedFaces,
const Map<label>& pointsToRestore,
const Map<label>& facesToRestore,
const Map<label>& cellsToRestore
);
//- Merge faces on the same patch (usually from exposing refinement)
// Returns global number of faces merged.
label mergePatchFaces
(
const scalar minCos,
const scalar concaveCos,
const labelList& patchIDs
);
//- Remove points not used by any face or points used
// by only two faces where the edges are in line
autoPtr<mapPolyMesh> mergeEdges(const scalar minCos);
// Debug/IO
//- Debugging: check that all faces still obey start()>end()
void checkData();
//- Compare two lists over all boundary faces
template<class T>
void testSyncBoundaryFaceList
(
const scalar mergeDistance,
const string&,
const UList<T>&,
const UList<T>&
) const;
//- Print some mesh stats.
void printMeshInfo(const bool, const string&) const;
//- Replacement for Time::timeName() : return oldInstance (if
// overwrite_)
word timeName() const;
//- Set instance of all local IOobjects
void setInstance(const fileName&);
//- Write mesh and all data
bool write() const;
//- Write refinement level as volScalarFields for postprocessing
void dumpRefinementLevel() const;
//- Debug: Write intersection information to OBJ format
void dumpIntersections(const fileName& prefix) const;
//- Do any one of above IO functions. flag is combination of
// writeFlag values.
void write(const label flag, const fileName&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "meshRefinementTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,246 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*----------------------------------------------------------------------------*/
#include "meshRefinement.H"
#include "combineFaces.H"
#include "directTopoChange.H"
#include "removePoints.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Merge faces that are in-line.
Foam::label Foam::meshRefinement::mergePatchFaces
(
const scalar minCos,
const scalar concaveCos,
const labelList& patchIDs
)
{
// Patch face merging engine
combineFaces faceCombiner(mesh_);
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Pick up all candidate cells on boundary
labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
forAll(patchIDs, i)
{
label patchI = patchIDs[i];
const polyPatch& patch = patches[patchI];
if (!patch.coupled())
{
forAll(patch, i)
{
boundaryCells.insert(mesh_.faceOwner()[patch.start()+i]);
}
}
}
// Get all sets of faces that can be merged
labelListList mergeSets
(
faceCombiner.getMergeSets
(
minCos,
concaveCos,
boundaryCells
)
);
label nFaceSets = returnReduce(mergeSets.size(), sumOp<label>());
Info<< "mergePatchFaces : Merging " << nFaceSets
<< " sets of faces." << endl;
if (nFaceSets > 0)
{
// Topology changes container
directTopoChange meshMod(mesh_);
// Merge all faces of a set into the first face of the set. Remove
// unused points.
faceCombiner.setRefinement(mergeSets, meshMod);
// Change the mesh (no inflation)
autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh_, false, true);
// Update fields
mesh_.updateMesh(map);
// Move mesh (since morphing does not do this)
if (map().hasMotionPoints())
{
mesh_.movePoints(map().preMotionPoints());
}
else
{
// Delete mesh volumes. No other way to do this?
mesh_.clearOut();
}
if (overwrite())
{
mesh_.setInstance(oldInstance());
}
faceCombiner.updateMesh(map);
// Get the kept faces that need to be recalculated.
// Merging two boundary faces might shift the cell centre
// (unless the faces are absolutely planar)
labelHashSet retestFaces(6*mergeSets.size());
forAll(mergeSets, setI)
{
label oldMasterI = mergeSets[setI][0];
label faceI = map().reverseFaceMap()[oldMasterI];
// faceI is always uncoupled boundary face
const cell& cFaces = mesh_.cells()[mesh_.faceOwner()[faceI]];
forAll(cFaces, i)
{
retestFaces.insert(cFaces[i]);
}
}
updateMesh(map, retestFaces.toc());
}
return nFaceSets;
}
// Remove points not used by any face or points used by only two faces where
// the edges are in line
Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::mergeEdges
(
const scalar minCos
)
{
// Point removal analysis engine
removePoints pointRemover(mesh_);
// Count usage of points
boolList pointCanBeDeleted;
label nRemove = pointRemover.countPointUsage(minCos, pointCanBeDeleted);
Info<< "Removing " << nRemove
<< " straight edge points." << endl;
autoPtr<mapPolyMesh> map;
if (nRemove > 0)
{
// Save my local faces that will change. These changed faces might
// cause a shift in the cell centre which needs to be retested.
// Have to do this before changing mesh since point will be removed.
labelHashSet retestOldFaces(nRemove / Pstream::nProcs());
{
const faceList& faces = mesh_.faces();
forAll(faces, faceI)
{
const face& f = faces[faceI];
forAll(f, fp)
{
if (pointCanBeDeleted[f[fp]])
{
retestOldFaces.insert(faceI);
break;
}
}
}
}
// Topology changes container
directTopoChange meshMod(mesh_);
pointRemover.setRefinement(pointCanBeDeleted, meshMod);
// Change the mesh (no inflation)
map = meshMod.changeMesh(mesh_, false, true);
// Update fields
mesh_.updateMesh(map);
// Move mesh (since morphing does not do this)
if (map().hasMotionPoints())
{
mesh_.movePoints(map().preMotionPoints());
}
else
{
// Delete mesh volumes. No other way to do this?
mesh_.clearOut();
}
if (overwrite())
{
mesh_.setInstance(oldInstance());
}
pointRemover.updateMesh(map);
// Get the kept faces that need to be recalculated.
labelHashSet retestFaces(6*retestOldFaces.size());
const cellList& cells = mesh_.cells();
forAllConstIter(labelHashSet, retestOldFaces, iter)
{
label faceI = map().reverseFaceMap()[iter.key()];
const cell& ownFaces = cells[mesh_.faceOwner()[faceI]];
forAll(ownFaces, i)
{
retestFaces.insert(ownFaces[i]);
}
if (mesh_.isInternalFace(faceI))
{
const cell& neiFaces = cells[mesh_.faceNeighbour()[faceI]];
forAll(neiFaces, i)
{
retestFaces.insert(neiFaces[i]);
}
}
}
updateMesh(map, retestFaces.toc());
}
return map;
}
// ************************************************************************* //

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,194 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "meshRefinement.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Add a T entry
template<class T> void meshRefinement::updateList
(
const labelList& newToOld,
const T& nullValue,
List<T>& elems
)
{
List<T> newElems(newToOld.size(), nullValue);
forAll(newElems, i)
{
label oldI = newToOld[i];
if (oldI >= 0)
{
newElems[i] = elems[oldI];
}
}
elems.transfer(newElems);
}
// Compare two lists over all boundary faces
template<class T>
void meshRefinement::testSyncBoundaryFaceList
(
const scalar tol,
const string& msg,
const UList<T>& faceData,
const UList<T>& syncedFaceData
) const
{
label nBFaces = mesh_.nFaces() - mesh_.nInternalFaces();
if (faceData.size() != nBFaces || syncedFaceData.size() != nBFaces)
{
FatalErrorIn
(
"meshRefinement::testSyncBoundaryFaceList"
"(const scalar, const string&, const List<T>&, const List<T>&)"
) << "Boundary faces:" << nBFaces
<< " faceData:" << faceData.size()
<< " syncedFaceData:" << syncedFaceData.size()
<< abort(FatalError);
}
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
label bFaceI = pp.start() - mesh_.nInternalFaces();
forAll(pp, i)
{
const T& data = faceData[bFaceI];
const T& syncData = syncedFaceData[bFaceI];
if (mag(data - syncData) > tol)
{
label faceI = pp.start()+i;
FatalErrorIn("testSyncFaces")
<< msg
<< "patchFace:" << i
<< " face:" << faceI
<< " fc:" << mesh_.faceCentres()[faceI]
<< " patch:" << pp.name()
<< " faceData:" << data
<< " syncedFaceData:" << syncData
<< " diff:" << mag(data - syncData)
<< abort(FatalError);
}
bFaceI++;
}
}
}
//template <class T, class Mesh>
template<class GeoField>
void meshRefinement::addPatchFields(fvMesh& mesh, const word& patchFieldType)
{
HashTable<const GeoField*> flds
(
mesh.objectRegistry::lookupClass<GeoField>()
);
for
(
typename HashTable<const GeoField*>::const_iterator iter = flds.begin();
iter != flds.end();
++iter
)
{
const GeoField& fld = *iter();
typename GeoField::GeometricBoundaryField& bfld =
const_cast<typename GeoField::GeometricBoundaryField&>
(
fld.boundaryField()
);
label sz = bfld.size();
bfld.setSize(sz+1);
bfld.set
(
sz,
GeoField::PatchFieldType::New
(
patchFieldType,
mesh.boundary()[sz],
fld.dimensionedInternalField()
)
);
}
}
// Reorder patch field
template<class GeoField>
void meshRefinement::reorderPatchFields(fvMesh& mesh, const labelList& oldToNew)
{
HashTable<const GeoField*> flds
(
mesh.objectRegistry::lookupClass<GeoField>()
);
for
(
typename HashTable<const GeoField*>::const_iterator iter = flds.begin();
iter != flds.end();
++iter
)
{
const GeoField& fld = *iter();
typename GeoField::GeometricBoundaryField& bfld =
const_cast<typename GeoField::GeometricBoundaryField&>
(
fld.boundaryField()
);
bfld.reorder(oldToNew);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,317 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::refinementSurfaces
Description
Container for data on surfaces used for surface-driven refinement.
Contains all the data about the level of refinement needed per
surface.
SourceFiles
refinementSurfaces.C
\*---------------------------------------------------------------------------*/
#ifndef refinementSurfaces_H
#define refinementSurfaces_H
#include "triSurfaceGeoMesh.H"
#include "triSurfaceFields.H"
#include "vectorList.H"
#include "pointIndexHit.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class searchableSurfaces;
class shellSurfaces;
class triSurfaceMesh;
/*---------------------------------------------------------------------------*\
Class refinementSurfaces Declaration
\*---------------------------------------------------------------------------*/
class refinementSurfaces
{
// Private data
//- Reference to all geometry.
const searchableSurfaces& allGeometry_;
//- Indices of surfaces that are refinement ones
labelList surfaces_;
//- Surface name (word)
wordList names_;
//- Per 'interface' surface : name of faceZone to put faces into
wordList faceZoneNames_;
//- Per 'interface' surface : name of cellZone to put cells into
wordList cellZoneNames_;
//- Per 'interface' surface : (only used if surface is closed)
// whether to zone cells inside or outside surface.
boolList zoneInside_;
//- From local region number to global region number
labelList regionOffset_;
//- From global region number to refinement level
labelList minLevel_;
//- From global region number to refinement level
labelList maxLevel_;
//- From global region number to perpendicular angle
scalarField perpendicularAngle_;
// Private Member Functions
//- Disallow default bitwise copy construct
refinementSurfaces(const refinementSurfaces&);
//- Disallow default bitwise assignment
void operator=(const refinementSurfaces&);
public:
// Constructors
//- Construct from surfaces and dictionaries
refinementSurfaces
(
const searchableSurfaces& allGeometry,
const PtrList<dictionary>&
);
//- Construct from surfaces and dictionary
refinementSurfaces
(
const searchableSurfaces& allGeometry,
const dictionary&
);
// Member Functions
// Access
const searchableSurfaces& geometry() const
{
return allGeometry_;
}
const labelList& surfaces() const
{
return surfaces_;
}
//- Names of surfaces
const wordList& names() const
{
return names_;
}
//- Per 'interface' surface : name of faceZone to put faces into
const wordList& faceZoneNames() const
{
return faceZoneNames_;
}
//- Per 'interface' surface : name of cellZone to put cells into
const wordList& cellZoneNames() const
{
return cellZoneNames_;
}
//- Get indices of unnamed surfaces (surfaces without faceZoneName)
labelList getUnnamedSurfaces() const;
//- Get indices of named surfaces (surfaces with faceZoneName)
labelList getNamedSurfaces() const;
//- Get indices of closed named surfaces
labelList getClosedNamedSurfaces() const;
//- From local region number to global region number
const labelList& regionOffset() const
{
return regionOffset_;
}
//- From global region number to refinement level
const labelList& minLevel() const
{
return minLevel_;
}
//- From global region number to refinement level
const labelList& maxLevel() const
{
return maxLevel_;
}
//- From global region number to perpendicular angle
const scalarField& perpendicularAngle() const
{
return perpendicularAngle_;
}
// Helper
//- From surface and region on surface to global region
label globalRegion(const label surfI, const label regionI) const
{
return regionOffset_[surfI]+regionI;
}
//- Min level for surface and region on surface
label minLevel(const label surfI, const label regionI) const
{
return minLevel_[globalRegion(surfI, regionI)];
}
//- Max level for surface and region on surface
label maxLevel(const label surfI, const label regionI) const
{
return maxLevel_[globalRegion(surfI, regionI)];
}
label nRegions() const
{
return minLevel_.size();
}
//- Calculate minLevelFields
void setMinLevelFields
(
const shellSurfaces& shells
);
////- Helper: count number of triangles per region
//static labelList countRegions(const triSurface&);
// Searching
//- Find intersection of edge. Return -1 or first surface
// with higher (than currentLevel) minlevel.
// Return surface number and level.
void findHigherIntersection
(
const pointField& start,
const pointField& end,
const labelList& currentLevel, // current cell refinement level
labelList& surfaces,
labelList& surfaceLevel
) const;
//- Find all intersections of edge. Unsorted order.
void findAllHigherIntersections
(
const pointField& start,
const pointField& end,
const labelList& currentLevel, // current cell refinement level
List<vectorList>& surfaceNormal,
labelListList& surfaceLevel
) const;
//- Find intersection nearest to the endpoints. surface1,2 are
// not indices into surfacesToTest but refinement surface indices.
// Returns surface, region on surface (so not global surface)
// and position on surface.
void findNearestIntersection
(
const labelList& surfacesToTest,
const pointField& start,
const pointField& end,
labelList& surface1,
List<pointIndexHit>& hit1,
labelList& region1,
labelList& surface2,
List<pointIndexHit>& hit2,
labelList& region2
) const;
//- Used for debugging only: find intersection of edge.
void findAnyIntersection
(
const pointField& start,
const pointField& end,
labelList& surfaces,
List<pointIndexHit>&
) const;
//- Find nearest point on surfaces.
void findNearest
(
const labelList& surfacesToTest,
const pointField& samples,
const scalarField& nearestDistSqr,
labelList& surfaces,
List<pointIndexHit>&
) const;
//- Find nearest point on surfaces. Return surface and region on
// surface (so not global surface)
void findNearestRegion
(
const labelList& surfacesToTest,
const pointField& samples,
const scalarField& nearestDistSqr,
labelList& hitSurface,
labelList& hitRegion
) const;
//- Detect if a point is 'inside' (closed) surfaces.
// Returns -1 if not, returns first surface it is.
void findInside
(
const labelList& surfacesToTest,
const pointField& pt,
labelList& insideSurfaces
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,481 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "searchableSurface.H"
#include "shellSurfaces.H"
#include "boundBox.H"
#include "triSurfaceMesh.H"
#include "refinementSurfaces.H"
#include "searchableSurfaces.H"
#include "orientedSurface.H"
#include "pointIndexHit.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
template<>
const char*
NamedEnum<shellSurfaces::refineMode, 3>::
names[] =
{
"inside",
"outside",
"distance"
};
const NamedEnum<shellSurfaces::refineMode, 3> shellSurfaces::refineModeNames_;
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::shellSurfaces::setAndCheckLevels
(
const label shellI,
const List<Tuple2<scalar, label> >& distLevels
)
{
if (modes_[shellI] != DISTANCE && distLevels.size() != 1)
{
FatalErrorIn
(
"shellSurfaces::shellSurfaces"
"(const searchableSurfaces&, const dictionary&)"
) << "For refinement mode "
<< refineModeNames_[modes_[shellI]]
<< " specify only one distance+level."
<< " (its distance gets discarded)"
<< exit(FatalError);
}
// Extract information into separate distance and level
distances_[shellI].setSize(distLevels.size());
levels_[shellI].setSize(distLevels.size());
forAll(distLevels, j)
{
distances_[shellI][j] = distLevels[j].first();
levels_[shellI][j] = distLevels[j].second();
// Check in incremental order
if (j > 0)
{
if
(
(distances_[shellI][j] <= distances_[shellI][j-1])
|| (levels_[shellI][j] > levels_[shellI][j-1])
)
{
FatalErrorIn
(
"shellSurfaces::shellSurfaces"
"(const searchableSurfaces&, const dictionary&)"
) << "For refinement mode "
<< refineModeNames_[modes_[shellI]]
<< " : Refinement should be specified in order"
<< " of increasing distance"
<< " (and decreasing refinement level)." << endl
<< "Distance:" << distances_[shellI][j]
<< " refinementLevel:" << levels_[shellI][j]
<< exit(FatalError);
}
}
}
const searchableSurface& shell = allGeometry_[shells_[shellI]];
if (modes_[shellI] == DISTANCE)
{
Info<< "Refinement level according to distance to "
<< shell.name() << endl;
forAll(levels_[shellI], j)
{
Info<< " level " << levels_[shellI][j]
<< " for all cells within " << distances_[shellI][j]
<< " meter." << endl;
}
}
else
{
if (!allGeometry_[shells_[shellI]].hasVolumeType())
{
FatalErrorIn
(
"shellSurfaces::shellSurfaces"
"(const searchableSurfaces&"
", const PtrList<dictionary>&)"
) << "Shell " << shell.name()
<< " does not support testing for "
<< refineModeNames_[modes_[shellI]] << endl
<< "Probably it is not closed."
<< exit(FatalError);
}
if (modes_[shellI] == INSIDE)
{
Info<< "Refinement level " << levels_[shellI][0]
<< " for all cells inside " << shell.name() << endl;
}
else
{
Info<< "Refinement level " << levels_[shellI][0]
<< " for all cells outside " << shell.name() << endl;
}
}
}
// Specifically orient triSurfaces using a calculated point outside.
// Done since quite often triSurfaces not of consistent orientation which
// is (currently) necessary for sideness calculation
void Foam::shellSurfaces::orient()
{
// Determine outside point.
boundBox overallBb = boundBox::invertedBox;
bool hasSurface = false;
forAll(shells_, shellI)
{
const searchableSurface& s = allGeometry_[shells_[shellI]];
if (modes_[shellI] != DISTANCE && isA<triSurfaceMesh>(s))
{
const triSurfaceMesh& shell = refCast<const triSurfaceMesh>(s);
if (shell.triSurface::size())
{
const pointField& points = shell.points();
hasSurface = true;
boundBox shellBb(points[0], points[0]);
// Assume surface is compact!
for (label i = 0; i < points.size(); i++)
{
const point& pt = points[i];
shellBb.min() = min(shellBb.min(), pt);
shellBb.max() = max(shellBb.max(), pt);
}
overallBb.min() = min(overallBb.min(), shellBb.min());
overallBb.max() = max(overallBb.max(), shellBb.max());
}
}
}
if (hasSurface)
{
const point outsidePt = overallBb.max() + overallBb.span();
//Info<< "Using point " << outsidePt << " to orient shells" << endl;
forAll(shells_, shellI)
{
const searchableSurface& s = allGeometry_[shells_[shellI]];
if (modes_[shellI] != DISTANCE && isA<triSurfaceMesh>(s))
{
triSurfaceMesh& shell = const_cast<triSurfaceMesh&>
(
refCast<const triSurfaceMesh>(s)
);
// Flip surface so outsidePt is outside.
bool anyFlipped = orientedSurface::orient
(
shell,
outsidePt,
true
);
if (anyFlipped)
{
// orientedSurface will have done a clearOut of the surface.
// we could do a clearout of the triSurfaceMeshes::trees()
// but these aren't affected by orientation
// (except for cached
// sideness which should not be set at this point.
// !!Should check!)
Info<< "shellSurfaces : Flipped orientation of surface "
<< s.name()
<< " so point " << outsidePt << " is outside." << endl;
}
}
}
}
}
// Find maximum level of a shell.
void Foam::shellSurfaces::findHigherLevel
(
const pointField& pt,
const label shellI,
labelList& maxLevel
) const
{
const labelList& levels = levels_[shellI];
if (modes_[shellI] == DISTANCE)
{
// Distance mode.
const scalarField& distances = distances_[shellI];
// Collect all those points that have a current maxLevel less than
// (any of) the shell. Also collect the furthest distance allowable
// to any shell with a higher level.
pointField candidates(pt.size());
labelList candidateMap(pt.size());
scalarField candidateDistSqr(pt.size());
label candidateI = 0;
forAll(maxLevel, pointI)
{
forAllReverse(levels, levelI)
{
if (levels[levelI] > maxLevel[pointI])
{
candidates[candidateI] = pt[pointI];
candidateMap[candidateI] = pointI;
candidateDistSqr[candidateI] = sqr(distances[levelI]);
candidateI++;
break;
}
}
}
candidates.setSize(candidateI);
candidateMap.setSize(candidateI);
candidateDistSqr.setSize(candidateI);
// Do the expensive nearest test only for the candidate points.
List<pointIndexHit> nearInfo;
allGeometry_[shells_[shellI]].findNearest
(
candidates,
candidateDistSqr,
nearInfo
);
// Update maxLevel
forAll(nearInfo, candidateI)
{
if (nearInfo[candidateI].hit())
{
// Check which level it actually is in.
label minDistI = findLower
(
distances,
mag(nearInfo[candidateI].hitPoint()-candidates[candidateI])
);
label pointI = candidateMap[candidateI];
// pt is inbetween shell[minDistI] and shell[minDistI+1]
maxLevel[pointI] = levels[minDistI+1];
}
}
}
else
{
// Inside/outside mode
// Collect all those points that have a current maxLevel less than the
// shell.
pointField candidates(pt.size());
labelList candidateMap(pt.size());
label candidateI = 0;
forAll(maxLevel, pointI)
{
if (levels[0] > maxLevel[pointI])
{
candidates[candidateI] = pt[pointI];
candidateMap[candidateI] = pointI;
candidateI++;
}
}
candidates.setSize(candidateI);
candidateMap.setSize(candidateI);
// Do the expensive nearest test only for the candidate points.
List<searchableSurface::volumeType> volType;
allGeometry_[shells_[shellI]].getVolumeType(candidates, volType);
forAll(volType, i)
{
label pointI = candidateMap[i];
if
(
(
modes_[shellI] == INSIDE
&& volType[i] == searchableSurface::INSIDE
)
|| (
modes_[shellI] == OUTSIDE
&& volType[i] == searchableSurface::OUTSIDE
)
)
{
maxLevel[pointI] = levels[0];
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::shellSurfaces::shellSurfaces
(
const searchableSurfaces& allGeometry,
const PtrList<dictionary>& shellDicts
)
:
allGeometry_(allGeometry)
{
shells_.setSize(shellDicts.size());
modes_.setSize(shellDicts.size());
distances_.setSize(shellDicts.size());
levels_.setSize(shellDicts.size());
forAll(shellDicts, shellI)
{
const dictionary& dict = shellDicts[shellI];
const word name = dict.lookup("name");
const word type = dict.lookup("type");
shells_[shellI] = allGeometry_.findSurfaceID(name);
if (shells_[shellI] == -1)
{
FatalErrorIn
(
"shellSurfaces::shellSurfaces"
"(const searchableSurfaces&, const PtrList<dictionary>&)"
) << "No surface called " << name << endl
<< "Valid surfaces are " << allGeometry_.names()
<< exit(FatalError);
}
modes_[shellI] = refineModeNames_.read(dict.lookup("refineMode"));
// Read pairs of distance+level
setAndCheckLevels(shellI, dict.lookup("levels"));
}
// Orient shell surfaces before any searching is done. Note that this
// only needs to be done for inside or outside. Orienting surfaces
// constructs lots of addressing which we want to avoid.
orient();
}
Foam::shellSurfaces::shellSurfaces
(
const searchableSurfaces& allGeometry,
const dictionary& shellsDict
)
:
allGeometry_(allGeometry)
{
shells_.setSize(shellsDict.size());
modes_.setSize(shellsDict.size());
distances_.setSize(shellsDict.size());
levels_.setSize(shellsDict.size());
label shellI = 0;
forAllConstIter(dictionary, shellsDict, iter)
{
shells_[shellI] = allGeometry_.findSurfaceID(iter().keyword());
if (shells_[shellI] == -1)
{
FatalErrorIn
(
"shellSurfaces::shellSurfaces"
"(const searchableSurfaces&, const dictionary>&"
) << "No surface called " << iter().keyword() << endl
<< "Valid surfaces are " << allGeometry_.names()
<< exit(FatalError);
}
const dictionary& dict = shellsDict.subDict(iter().keyword());
modes_[shellI] = refineModeNames_.read(dict.lookup("mode"));
// Read pairs of distance+level
setAndCheckLevels(shellI, dict.lookup("levels"));
shellI++;
}
// Orient shell surfaces before any searching is done. Note that this
// only needs to be done for inside or outside. Orienting surfaces
// constructs lots of addressing which we want to avoid.
orient();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Highest shell level
Foam::label Foam::shellSurfaces::maxLevel() const
{
label overallMax = 0;
forAll(levels_, shellI)
{
overallMax = max(overallMax, max(levels_[shellI]));
}
return overallMax;
}
void Foam::shellSurfaces::findHigherLevel
(
const pointField& pt,
const labelList& ptLevel,
labelList& maxLevel
) const
{
// Maximum level of any shell. Start off with level of point.
maxLevel = ptLevel;
forAll(shells_, shellI)
{
findHigherLevel(pt, shellI, maxLevel);
}
}
// ************************************************************************* //

View file

@ -0,0 +1,181 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::shellSurfaces
Description
Encapsulates queries for volume refinement ('refine all cells within
shell').
SourceFiles
shellSurfaces.C
\*---------------------------------------------------------------------------*/
#ifndef shellSurfaces_H
#define shellSurfaces_H
#include "searchableSurface.H"
#include "Tuple2.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class searchableSurfaces;
/*---------------------------------------------------------------------------*\
Class shellSurfaces Declaration
\*---------------------------------------------------------------------------*/
class shellSurfaces
{
public:
// Public data types
//- Volume refinement controls
enum refineMode
{
INSIDE, // Refine all inside shell
OUTSIDE, // ,, outside
DISTANCE // Refine based on distance to shell
};
private:
// Private data
//- Reference to all geometry.
const searchableSurfaces& allGeometry_;
//- Indices of surfaces that are shells
labelList shells_;
//- Per shell whether to refine inside or outside
List<refineMode> modes_;
//- Per shell the list of ranges
List<scalarField> distances_;
//- Per shell per distance the refinement level
labelListList levels_;
// Private data
//- refineMode names
static const NamedEnum<refineMode, 3> refineModeNames_;
// Private Member Functions
//- Helper function for initialisation.
void setAndCheckLevels
(
const label shellI,
const List<Tuple2<scalar, label> >&
);
void orient();
void findHigherLevel
(
const pointField& pt,
const label shellI,
labelList& maxLevel
) const;
public:
// Constructors
//- Construct from components
shellSurfaces
(
const searchableSurfaces& allGeometry,
const labelList& shells,
const List<refineMode>& modes,
const List<scalarField>& distances,
const labelListList& levels
);
//- Construct from geometry and dictionaries
shellSurfaces
(
const searchableSurfaces& allGeometry,
const PtrList<dictionary>& shellDicts
);
//- Construct from geometry and dictionary
shellSurfaces
(
const searchableSurfaces& allGeometry,
const dictionary& shellsDict
);
// Member Functions
// Access
//const List<scalarField>& distances() const
//{
// return distances_;
//}
//
////- Per shell per distance the refinement level
//const labelListList& levels() const
//{
// return levels_;
//}
// Query
//- Highest shell level
label maxLevel() const;
//- Find shell level higher than ptLevel
void findHigherLevel
(
const pointField& pt,
const labelList& ptLevel,
labelList& maxLevel
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,261 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "ExactParticle.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class ParticleType>
template<class TrackingData>
Foam::label Foam::ExactParticle<ParticleType>::track
(
const vector& endPosition,
TrackingData& td
)
{
this->facei_ = -1;
// Tracks to endPosition or stop on boundary
while (!this->onBoundary() && this->stepFraction_ < 1.0 - SMALL)
{
this->stepFraction_ +=
trackToFace(endPosition, td)
*(1.0 - this->stepFraction_);
}
return this->facei_;
}
template<class ParticleType>
Foam::label Foam::ExactParticle<ParticleType>::track
(
const vector& endPosition
)
{
int dummyTd;
return track(endPosition, dummyTd);
}
template<class ParticleType>
template<class TrackingData>
Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace
(
const vector& endPosition,
TrackingData& td
)
{
const polyMesh& mesh = this->cloud().pMesh();
const labelList& cFaces = mesh.cells()[this->celli_];
point intersection(vector::zero);
scalar trackFraction = VGREAT;
label hitFacei = -1;
const vector vec = endPosition-this->position_;
forAll(cFaces, i)
{
label facei = cFaces[i];
if (facei != this->face())
{
pointHit inter = mesh.faces()[facei].fastIntersection
(
this->position_,
vec,
mesh.faceCentres()[facei],
mesh.points(),
intersection::HALF_RAY
);
if (inter.hit() && inter.distance() < trackFraction)
{
trackFraction = inter.distance();
hitFacei = facei;
intersection = inter.hitPoint();
}
}
}
if (hitFacei == -1)
{
// Did not find any intersection. Fall back to original approximate
// algorithm
return Particle<ParticleType>::trackToFace
(
endPosition,
td
);
}
if (trackFraction >= (1.0-SMALL))
{
// Nearest intersection beyond endPosition so we hit endPosition.
trackFraction = 1.0;
this->position_ = endPosition;
this->facei_ = -1;
return 1.0;
}
else
{
this->position_ = intersection;
this->facei_ = hitFacei;
}
// Normal situation (trackFraction 0..1). Straight copy
// of Particle::trackToFace.
bool internalFace = this->cloud().internalFace(this->facei_);
// change cell
if (internalFace) // Internal face
{
if (this->celli_ == mesh.faceOwner()[this->facei_])
{
this->celli_ = mesh.faceNeighbour()[this->facei_];
}
else if (this->celli_ == mesh.faceNeighbour()[this->facei_])
{
this->celli_ = mesh.faceOwner()[this->facei_];
}
else
{
FatalErrorIn
(
"ExactParticle::trackToFace"
"(const vector&, TrackingData&)"
)<< "addressing failure" << nl
<< abort(FatalError);
}
}
else
{
ParticleType& p = static_cast<ParticleType&>(*this);
// Soft-sphere algorithm ignores the boundary
if (p.softImpact())
{
trackFraction = 1.0;
this->position_ = endPosition;
}
label patchi = this->patch(this->facei_);
const polyPatch& patch = mesh.boundaryMesh()[patchi];
if (isA<wedgePolyPatch>(patch))
{
p.hitWedgePatch
(
static_cast<const wedgePolyPatch&>(patch), td
);
}
else if (isA<symmetryPolyPatch>(patch))
{
p.hitSymmetryPatch
(
static_cast<const symmetryPolyPatch&>(patch), td
);
}
else if (isA<cyclicPolyPatch>(patch))
{
p.hitCyclicPatch
(
static_cast<const cyclicPolyPatch&>(patch), td
);
}
else if (isA<processorPolyPatch>(patch))
{
p.hitProcessorPatch
(
static_cast<const processorPolyPatch&>(patch), td
);
}
else if (isA<wallPolyPatch>(patch))
{
p.hitWallPatch
(
static_cast<const wallPolyPatch&>(patch), td
);
}
else if (isA<polyPatch>(patch))
{
p.hitPatch
(
static_cast<const polyPatch&>(patch), td
);
}
else
{
FatalErrorIn
(
"ExactParticle::trackToFace"
"(const vector& endPosition, scalar& trackFraction)"
)<< "patch type " << patch.type() << " not suported" << nl
<< abort(FatalError);
}
}
// If the trackFraction = 0 something went wrong.
// Either the particle is flipping back and forth across a face perhaps
// due to velocity interpolation errors or it is in a "hole" in the mesh
// caused by face warpage.
// In both cases resolve the positional ambiguity by moving the particle
// slightly towards the cell-centre.
if (trackFraction < SMALL)
{
this->position_ +=
1.0e-6*(mesh.cellCentres()[this->celli_] - this->position_);
}
return trackFraction;
}
template<class ParticleType>
Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace
(
const vector& endPosition
)
{
int dummyTd;
return trackToFace(endPosition, dummyTd);
}
template<class ParticleType>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const ExactParticle<ParticleType>& p
)
{
return operator<<(os, static_cast<const Particle<ParticleType>&>(p));
}
// ************************************************************************* //

View file

@ -0,0 +1,192 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::ExactParticle
Description
Special version of Particle to do tracking on non-convex cells.
\*---------------------------------------------------------------------------*/
#ifndef ExactParticle_H
#define ExactParticle_H
#include "face.H"
#include "Particle.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class ExactParticle>
class Cloud;
// Forward declaration of friend functions and operators
template<class ParticleType>
class ExactParticle;
template<class ParticleType>
Ostream& operator<<
(
Ostream&,
const ExactParticle<ParticleType>&
);
/*---------------------------------------------------------------------------*\
Class ExactParticle Declaration
\*---------------------------------------------------------------------------*/
template<class ParticleType>
class ExactParticle
:
public Particle<ParticleType>
{
public:
friend class Cloud<ParticleType>;
// Constructors
//- Construct from components
ExactParticle
(
const Cloud<ParticleType>& cloud,
const vector& position,
const label celli
)
:
Particle<ParticleType>(cloud, position, celli)
{}
//- Construct from Istream
ExactParticle
(
const Cloud<ParticleType>& cloud,
Istream& is,
bool readFields = true
)
:
Particle<ParticleType>(cloud, is, readFields)
{}
//- Factory class to read-construct particles used for parallel transfer
class iNew
{
// Private data
const Cloud<ParticleType>& cloud_;
public:
iNew(const Cloud<ParticleType>& cloud)
:
cloud_(cloud)
{}
autoPtr<ParticleType> operator()(Istream& is) const
{
return autoPtr<ParticleType>
(
new ParticleType(cloud_, is)
);
}
};
// Destructor
virtual ~ExactParticle()
{}
// Member Functions
//- Track particle to end of trajectory
// or until it hits the boundary.
// On entry 'stepFraction()' should be set to the fraction of the
// time-step at which the tracking starts and on exit it contains
// the fraction of the time-step completed.
// Returns the boundary face index if the track stops at the
// boundary, -1 otherwise.
template<class TrackingData>
label track
(
const vector& endPosition,
TrackingData& td
);
//- Calls the templated track with dummy TrackingData
label track(const vector& endPosition);
//- Track particle to a given position and returns 1.0 if the
// trajectory is completed without hitting a face otherwise
// stops at the face and returns the fraction of the trajectory
// completed.
// on entry 'stepFraction()' should be set to the fraction of the
// time-step at which the tracking starts.
template<class TrackingData>
scalar trackToFace
(
const vector& endPosition,
TrackingData& td
);
//- Calls the templated trackToFace with dummy TrackingData
scalar trackToFace(const vector& endPosition);
// Ostream Operator
friend Ostream& operator<< <ParticleType>
(
Ostream&,
const ExactParticle<ParticleType>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "ExactParticle.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,282 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*----------------------------------------------------------------------------*/
#include "trackedParticle.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct from components
Foam::trackedParticle::trackedParticle
(
const Cloud<trackedParticle>& c,
const vector& position,
const label celli,
const point& end,
const label level,
const label i,
const label j
)
:
ExactParticle<trackedParticle>(c, position, celli),
end_(end),
level_(level),
i_(i),
j_(j)
{}
//- Construct from Istream
Foam::trackedParticle::trackedParticle
(
const Cloud<trackedParticle>& c,
Istream& is,
bool readFields
)
:
ExactParticle<trackedParticle>(c, is, readFields)
{
if (readFields)
{
if (is.format() == IOstream::ASCII)
{
is >> end_;
level_ = readLabel(is);
i_ = readLabel(is);
j_ = readLabel(is);
}
else
{
is.read
(
reinterpret_cast<char*>(&end_),
sizeof(end_) + sizeof(level_) + sizeof(i_) + sizeof(j_)
);
}
}
// Check state of Istream
is.check
(
"trackedParticle::trackedParticle"
"(const Cloud<trackedParticle>&, Istream&, bool)"
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::trackedParticle::move(trackedParticle::trackData& td)
{
td.switchProcessor = false;
td.keepParticle = true;
scalar deltaT = cloud().pMesh().time().deltaT().value();
scalar tEnd = (1.0 - stepFraction())*deltaT;
scalar dtMax = tEnd;
while (td.keepParticle && !td.switchProcessor && tEnd > SMALL)
{
// set the lagrangian time-step
scalar dt = min(dtMax, tEnd);
// mark visited cell with max level.
td.maxLevel()[cell()] = max(td.maxLevel()[cell()], level_);
dt *= trackToFace(end_, td);
tEnd -= dt;
stepFraction() = 1.0 - tEnd/deltaT;
}
return td.keepParticle;
}
bool Foam::trackedParticle::hitPatch
(
const polyPatch&,
trackedParticle::trackData& td,
const label patchI
)
{
return false;
}
bool Foam::trackedParticle::hitPatch
(
const polyPatch&,
int&,
const label
)
{
return false;
}
void Foam::trackedParticle::hitWedgePatch
(
const wedgePolyPatch&,
trackedParticle::trackData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::trackedParticle::hitWedgePatch
(
const wedgePolyPatch&,
int&
)
{}
void Foam::trackedParticle::hitSymmetryPatch
(
const symmetryPolyPatch&,
trackedParticle::trackData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::trackedParticle::hitSymmetryPatch
(
const symmetryPolyPatch&,
int&
)
{}
void Foam::trackedParticle::hitCyclicPatch
(
const cyclicPolyPatch&,
trackedParticle::trackData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::trackedParticle::hitCyclicPatch
(
const cyclicPolyPatch&,
int&
)
{}
void Foam::trackedParticle::hitProcessorPatch
(
const processorPolyPatch&,
trackedParticle::trackData& td
)
{
// Remove particle
td.switchProcessor = true;
}
void Foam::trackedParticle::hitProcessorPatch
(
const processorPolyPatch&,
int&
)
{}
void Foam::trackedParticle::hitWallPatch
(
const wallPolyPatch& wpp,
trackedParticle::trackData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::trackedParticle::hitWallPatch
(
const wallPolyPatch& wpp,
int&
)
{}
void Foam::trackedParticle::hitPatch
(
const polyPatch& wpp,
trackedParticle::trackData& td
)
{
// Remove particle
td.keepParticle = false;
}
void Foam::trackedParticle::hitPatch
(
const polyPatch& wpp,
int&
)
{}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const trackedParticle& p)
{
if (os.format() == IOstream::ASCII)
{
os << static_cast<const ExactParticle<trackedParticle>&>(p)
<< token::SPACE << p.end_
<< token::SPACE << p.level_
<< token::SPACE << p.i_
<< token::SPACE << p.j_;
}
else
{
os << static_cast<const ExactParticle<trackedParticle>&>(p);
os.write
(
reinterpret_cast<const char*>(&p.end_),
sizeof(p.end_) + sizeof(p.level_) + sizeof(p.i_) + sizeof(p.j_)
);
}
// Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const trackedParticle&)");
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,290 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::trackedParticle
Description
Particle class that marks cells it passes through. Used to mark cells
visited by feature edges. Uses ExactParticle tracking class so
will work on concave cells.
SourceFiles
trackedParticle.C
\*---------------------------------------------------------------------------*/
#ifndef trackedParticle_H
#define trackedParticle_H
#include "ExactParticle.H"
#include "autoPtr.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class trackedParticleCloud;
/*---------------------------------------------------------------------------*\
Class trackedParticle Declaration
\*---------------------------------------------------------------------------*/
class trackedParticle
:
public ExactParticle<trackedParticle>
{
// Private data
//- end point to track to
point end_;
//- level of this particle
label level_;
//- passive label
label i_;
//- passive label
label j_;
public:
friend class Cloud<trackedParticle>;
//- Class used to pass tracking data to the trackToFace function
class trackData
{
//- Reference to the cloud containing this particle
Cloud<trackedParticle>& cloud_;
labelList& maxLevel_;
public:
bool switchProcessor;
bool keepParticle;
// Constructors
trackData(Cloud<trackedParticle>& cloud, labelList& maxLevel)
:
cloud_(cloud),
maxLevel_(maxLevel)
{}
// Member functions
Cloud<trackedParticle>& cloud()
{
return cloud_;
}
labelList& maxLevel()
{
return maxLevel_;
}
};
// Constructors
//- Construct from components
trackedParticle
(
const Cloud<trackedParticle>& c,
const vector& position,
const label celli,
const point& end,
const label level,
const label i,
const label j
);
//- Construct from Istream
trackedParticle
(
const Cloud<trackedParticle>& c,
Istream& is,
bool readFields = true
);
//- Construct and return a clone
autoPtr<trackedParticle> clone() const
{
return autoPtr<trackedParticle>(new trackedParticle(*this));
}
// Member Functions
//- point to track to
point& end()
{
return end_;
}
//- transported label
label& i()
{
return i_;
}
//- transported label
label& j()
{
return j_;
}
// 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&,
trackedParticle::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&,
trackedParticle::trackData& td
);
void hitWedgePatch
(
const wedgePolyPatch&,
int&
);
//- Overridable function to handle the particle hitting a
// symmetryPlane
void hitSymmetryPatch
(
const symmetryPolyPatch&,
trackedParticle::trackData& td
);
void hitSymmetryPatch
(
const symmetryPolyPatch&,
int&
);
//- Overridable function to handle the particle hitting a cyclic
void hitCyclicPatch
(
const cyclicPolyPatch&,
trackedParticle::trackData& td
);
void hitCyclicPatch
(
const cyclicPolyPatch&,
int&
);
//- Overridable function to handle the particle hitting a
//- processorPatch
void hitProcessorPatch
(
const processorPolyPatch&,
trackedParticle::trackData& td
);
void hitProcessorPatch
(
const processorPolyPatch&,
int&
);
//- Overridable function to handle the particle hitting a wallPatch
void hitWallPatch
(
const wallPolyPatch&,
trackedParticle::trackData& td
);
void hitWallPatch
(
const wallPolyPatch&,
int&
);
//- Overridable function to handle the particle hitting a polyPatch
void hitPatch
(
const polyPatch&,
trackedParticle::trackData& td
);
void hitPatch
(
const polyPatch&,
int&
);
// Ostream Operator
friend Ostream& operator<<(Ostream&, const trackedParticle&);
};
template<>
inline bool contiguous<trackedParticle>()
{
return true;
}
//template<>
//void Cloud<trackedParticle>::readFields();
//
//template<>
//void Cloud<trackedParticle>::writeFields() const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -21,38 +21,23 @@ License
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
InClass
Foam::blockList
Description
SourceFiles
blockList.C
\*---------------------------------------------------------------------------*/
#ifndef blockList_H
#define blockList_H
#include "block.H"
#include "PtrList.H"
#include "trackedParticle.H"
#include "Cloud.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
typedef PtrList<block> blockList;
defineParticleTypeNameAndDebug(trackedParticle, 0);
defineTemplateTypeNameAndDebug(Cloud<trackedParticle>, 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,25 @@
curvedEdges/BSpline.C
curvedEdges/CatmullRomSpline.C
curvedEdges/polyLine.C
curvedEdges/arcEdge.C
curvedEdges/curvedEdge.C
curvedEdges/lineEdge.C
curvedEdges/polyLineEdge.C
curvedEdges/lineDivide.C
curvedEdges/splineEdge.C
curvedEdges/ellipseEdge.C
blockDescriptor/blockDescriptor.C
blockDescriptor/blockDescriptorEdges.C
block/block.C
block/blockCreate.C
blockMesh/blockMesh.C
blockMesh/blockMeshCreate.C
blockMesh/blockMeshTopology.C
blockMesh/blockMeshCheck.C
blockMesh/blockMeshMerge.C
LIB = $(FOAM_LIBBIN)/libblockMesh

View file

@ -0,0 +1,9 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude
LIB_LIBS = \
-lmeshTools \
-lODE \
-ldynamicMesh

View file

@ -0,0 +1,107 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "block.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::block::block
(
const pointField& blockPointField,
const curvedEdgeList& edges,
Istream& is
)
:
blockDescriptor(blockPointField, edges, is),
vertices_(0),
cells_(0),
boundaryPatches_(0)
{}
Foam::block::block(const blockDescriptor& blockDesc)
:
blockDescriptor(blockDesc),
vertices_(0),
cells_(0),
boundaryPatches_(0)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::block::~block()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::pointField& Foam::block::points() const
{
if (vertices_.empty())
{
createPoints();
}
return vertices_;
}
const Foam::labelListList& Foam::block::cells() const
{
if (cells_.empty())
{
createCells();
}
return cells_;
}
const Foam::labelListListList& Foam::block::boundaryPatches() const
{
if (boundaryPatches_.empty())
{
createBoundary();
}
return boundaryPatches_;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const block& b)
{
os << b.points() << nl
<< b.cells() << nl
<< b.boundaryPatches() << endl;
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::block
Description
Creates a single block of cells from point coordinates, numbers of
cells in each direction and an expansion ratio.
Note
The vertices and cells for filling the block are demand-driven.
SourceFiles
block.C
blockCreate.C
\*---------------------------------------------------------------------------*/
#ifndef block_H
#define block_H
#include "pointField.H"
#include "labelList.H"
#include "blockDescriptor.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class Istream;
class Ostream;
// Forward declaration of friend functions and operators
class block;
Ostream& operator<<(Ostream&, const block&);
/*---------------------------------------------------------------------------*\
Class block Declaration
\*---------------------------------------------------------------------------*/
class block
:
public blockDescriptor
{
// Private data
//- List of vertices
mutable pointField vertices_;
//- List of cells
mutable labelListList cells_;
//- Boundary patches
mutable labelListListList boundaryPatches_;
// Private Member Functions
//- Creates vertices for cells filling the block
void createPoints() const;
//- Creates cells for filling the block
void createCells() const;
//- Creates boundary patch faces for the block
void createBoundary() const;
//- Disallow default bitwise copy construct
block(const block&);
//- Disallow default bitwise assignment
void operator=(const block&);
public:
// Constructors
//- Construct from components with Istream
block
(
const pointField& blockPointField,
const curvedEdgeList&,
Istream&
);
//- Construct from a block definition
block(const blockDescriptor&);
//- Clone
autoPtr<block> clone() const
{
notImplemented("block::clone()");
return autoPtr<block>(NULL);
}
//- Destructor
~block();
// Member Functions
// Access
//- Return the block definition
inline const blockDescriptor& blockDef() const
{
return *this;
}
//- Vertex label offset for a particular i,j,k position
label vtxLabel(label i, label j, label k) const;
//- Return the points for filling the block
const pointField& points() const;
//- Return the cells for filling the block
const labelListList& cells() const;
//- Return the boundary patch faces for the block
const labelListListList& boundaryPatches() const;
// Edit
//- Clear geometry (internal points, cells, boundaryPatches)
void clearGeom();
// Ostream Operator
friend Ostream& operator<<(Ostream&, const block&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,477 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "block.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::block::vtxLabel(label i, label j, label k) const
{
return
(
i
+ j * (meshDensity().x() + 1)
+ k * (meshDensity().x() + 1) * (meshDensity().y() + 1)
);
}
void Foam::block::createPoints() const
{
// set local variables for mesh specification
const label ni = meshDensity().x();
const label nj = meshDensity().y();
const label nk = meshDensity().z();
const point& p000 = blockPoint(0);
const point& p100 = blockPoint(1);
const point& p110 = blockPoint(2);
const point& p010 = blockPoint(3);
const point& p001 = blockPoint(4);
const point& p101 = blockPoint(5);
const point& p111 = blockPoint(6);
const point& p011 = blockPoint(7);
// list of edge point and weighting factors
const List< List<point> >& p = blockEdgePoints();
const scalarListList& w = blockEdgeWeights();
//
// generate vertices
//
vertices_.clear();
vertices_.setSize(nPoints());
for (label k = 0; k <= nk; k++)
{
for (label j = 0; j <= nj; j++)
{
for (label i = 0; i <= ni; i++)
{
const label vertexNo = vtxLabel(i, j, k);
// points on edges
vector edgex1 = p000 + (p100 - p000)*w[0][i];
vector edgex2 = p010 + (p110 - p010)*w[1][i];
vector edgex3 = p011 + (p111 - p011)*w[2][i];
vector edgex4 = p001 + (p101 - p001)*w[3][i];
vector edgey1 = p000 + (p010 - p000)*w[4][j];
vector edgey2 = p100 + (p110 - p100)*w[5][j];
vector edgey3 = p101 + (p111 - p101)*w[6][j];
vector edgey4 = p001 + (p011 - p001)*w[7][j];
vector edgez1 = p000 + (p001 - p000)*w[8][k];
vector edgez2 = p100 + (p101 - p100)*w[9][k];
vector edgez3 = p110 + (p111 - p110)*w[10][k];
vector edgez4 = p010 + (p011 - p010)*w[11][k];
// calculate the importance factors for all edges
// x-direction
scalar impx1 =
(
(1.0 - w[0][i])*(1.0 - w[4][j])*(1.0 - w[8][k])
+ w[0][i]*(1.0 - w[5][j])*(1.0 - w[9][k])
);
scalar impx2 =
(
(1.0 - w[1][i])*w[4][j]*(1.0 - w[11][k])
+ w[1][i]*w[5][j]*(1.0 - w[10][k])
);
scalar impx3 =
(
(1.0 - w[2][i])*w[7][j]*w[11][k]
+ w[2][i]*w[6][j]*w[10][k]
);
scalar impx4 =
(
(1.0 - w[3][i])*(1.0 - w[7][j])*w[8][k]
+ w[3][i]*(1.0 - w[6][j])*w[9][k]
);
scalar magImpx = impx1 + impx2 + impx3 + impx4;
impx1 /= magImpx;
impx2 /= magImpx;
impx3 /= magImpx;
impx4 /= magImpx;
// y-direction
scalar impy1 =
(
(1.0 - w[4][j])*(1.0 - w[0][i])*(1.0 - w[8][k])
+ w[4][j]*(1.0 - w[1][i])*(1.0 - w[11][k])
);
scalar impy2 =
(
(1.0 - w[5][j])*w[0][i]*(1.0 - w[9][k])
+ w[5][j]*w[1][i]*(1.0 - w[10][k])
);
scalar impy3 =
(
(1.0 - w[6][j])*w[3][i]*w[9][k]
+ w[6][j]*w[2][i]*w[10][k]
);
scalar impy4 =
(
(1.0 - w[7][j])*(1.0 - w[3][i])*w[8][k]
+ w[7][j]*(1.0 - w[2][i])*w[11][k]
);
scalar magImpy = impy1 + impy2 + impy3 + impy4;
impy1 /= magImpy;
impy2 /= magImpy;
impy3 /= magImpy;
impy4 /= magImpy;
// z-direction
scalar impz1 =
(
(1.0 - w[8][k])*(1.0 - w[0][i])*(1.0 - w[4][j])
+ w[8][k]*(1.0 - w[3][i])*(1.0 - w[7][j])
);
scalar impz2 =
(
(1.0 - w[9][k])*w[0][i]*(1.0 - w[5][j])
+ w[9][k]*w[3][i]*(1.0 - w[6][j])
);
scalar impz3 =
(
(1.0 - w[10][k])*w[1][i]*w[5][j]
+ w[10][k]*w[2][i]*w[6][j]
);
scalar impz4 =
(
(1.0 - w[11][k])*(1.0 - w[1][i])*w[4][j]
+ w[11][k]*(1.0 - w[2][i])*w[7][j]
);
scalar magImpz = impz1 + impz2 + impz3 + impz4;
impz1 /= magImpz;
impz2 /= magImpz;
impz3 /= magImpz;
impz4 /= magImpz;
// calculate the correction vectors
vector corx1 = impx1*(p[0][i] - edgex1);
vector corx2 = impx2*(p[1][i] - edgex2);
vector corx3 = impx3*(p[2][i] - edgex3);
vector corx4 = impx4*(p[3][i] - edgex4);
vector cory1 = impy1*(p[4][j] - edgey1);
vector cory2 = impy2*(p[5][j] - edgey2);
vector cory3 = impy3*(p[6][j] - edgey3);
vector cory4 = impy4*(p[7][j] - edgey4);
vector corz1 = impz1*(p[8][k] - edgez1);
vector corz2 = impz2*(p[9][k] - edgez2);
vector corz3 = impz3*(p[10][k] - edgez3);
vector corz4 = impz4*(p[11][k] - edgez4);
// multiply by the importance factor
// x-direction
edgex1 *= impx1;
edgex2 *= impx2;
edgex3 *= impx3;
edgex4 *= impx4;
// y-direction
edgey1 *= impy1;
edgey2 *= impy2;
edgey3 *= impy3;
edgey4 *= impy4;
// z-direction
edgez1 *= impz1;
edgez2 *= impz2;
edgez3 *= impz3;
edgez4 *= impz4;
// add the contributions
vertices_[vertexNo] =
(
edgex1 + edgex2 + edgex3 + edgex4
+ edgey1 + edgey2 + edgey3 + edgey4
+ edgez1 + edgez2 + edgez3 + edgez4
) / 3.0;
vertices_[vertexNo] +=
(
corx1 + corx2 + corx3 + corx4
+ cory1 + cory2 + cory3 + cory4
+ corz1 + corz2 + corz3 + corz4
);
}
}
}
}
void Foam::block::createCells() const
{
const label ni = meshDensity().x();
const label nj = meshDensity().y();
const label nk = meshDensity().z();
//
// generate cells
//
cells_.clear();
cells_.setSize(nCells());
label cellNo = 0;
for (label k = 0; k < nk; k++)
{
for (label j = 0; j < nj; j++)
{
for (label i = 0; i < ni; i++)
{
cells_[cellNo].setSize(8);
cells_[cellNo][0] = vtxLabel(i, j, k);
cells_[cellNo][1] = vtxLabel(i+1, j, k);
cells_[cellNo][2] = vtxLabel(i+1, j+1, k);
cells_[cellNo][3] = vtxLabel(i, j+1, k);
cells_[cellNo][4] = vtxLabel(i, j, k+1);
cells_[cellNo][5] = vtxLabel(i+1, j, k+1);
cells_[cellNo][6] = vtxLabel(i+1, j+1, k+1);
cells_[cellNo][7] = vtxLabel(i, j+1, k+1);
cellNo++;
}
}
}
}
void Foam::block::createBoundary() const
{
const label ni = meshDensity().x();
const label nj = meshDensity().y();
const label nk = meshDensity().z();
//
// generate boundaries on each side of the hex
//
boundaryPatches_.clear();
boundaryPatches_.setSize(6);
// x-direction
label wallLabel = 0;
label wallCellLabel = 0;
// x-min
boundaryPatches_[wallLabel].setSize(nj*nk);
for (label k = 0; k < nk; k++)
{
for (label j = 0; j < nj; j++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(0, j, k);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(0, j, k + 1);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(0, j + 1, k + 1);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(0, j + 1, k);
// update the counter
wallCellLabel++;
}
}
// x-max
wallLabel++;
wallCellLabel = 0;
boundaryPatches_[wallLabel].setSize(nj*nk);
for (label k = 0; k < nk; k++)
{
for (label j = 0; j < nj; j++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(ni, j, k);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(ni, j+1, k);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(ni, j+1, k+1);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(ni, j, k+1);
// update the counter
wallCellLabel++;
}
}
// y-direction
// y-min
wallLabel++;
wallCellLabel = 0;
boundaryPatches_[wallLabel].setSize(ni*nk);
for (label i = 0; i < ni; i++)
{
for (label k = 0; k < nk; k++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(i, 0, k);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(i + 1, 0, k);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(i + 1, 0, k + 1);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(i, 0, k + 1);
// update the counter
wallCellLabel++;
}
}
// y-max
wallLabel++;
wallCellLabel = 0;
boundaryPatches_[wallLabel].setSize(ni*nk);
for (label i = 0; i < ni; i++)
{
for (label k = 0; k < nk; k++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(i, nj, k);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(i, nj, k + 1);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(i + 1, nj, k + 1);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(i + 1, nj, k);
// update the counter
wallCellLabel++;
}
}
// z-direction
// z-min
wallLabel++;
wallCellLabel = 0;
boundaryPatches_[wallLabel].setSize(ni*nj);
for (label i = 0; i < ni; i++)
{
for (label j = 0; j < nj; j++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(i, j, 0);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(i, j + 1, 0);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(i + 1, j + 1, 0);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(i + 1, j, 0);
// update the counter
wallCellLabel++;
}
}
// z-max
wallLabel++;
wallCellLabel = 0;
boundaryPatches_[wallLabel].setSize(ni*nj);
for (label i = 0; i < ni; i++)
{
for (label j = 0; j < nj; j++)
{
boundaryPatches_[wallLabel][wallCellLabel].setSize(4);
// set the points
boundaryPatches_[wallLabel][wallCellLabel][0] =
vtxLabel(i, j, nk);
boundaryPatches_[wallLabel][wallCellLabel][1] =
vtxLabel(i + 1, j, nk);
boundaryPatches_[wallLabel][wallCellLabel][2] =
vtxLabel(i + 1, j + 1, nk);
boundaryPatches_[wallLabel][wallCellLabel][3] =
vtxLabel(i, j + 1, nk);
// update the counter
wallCellLabel++;
}
}
}
void Foam::block::clearGeom()
{
vertices_.clear();
cells_.clear();
boundaryPatches_.clear();
}
// ************************************************************************* //

View file

@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::blockList
Description
A PtrList of blocks
\*---------------------------------------------------------------------------*/
#ifndef blockList_H
#define blockList_H
#include "block.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef PtrList<block> blockList;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,322 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "blockDescriptor.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::blockDescriptor::blockDescriptor
(
const cellShape& bshape,
const pointField& blockPointField,
const curvedEdgeList& edges,
const Vector<label>& meshDensity,
const UList<scalar>& expand,
const word& zoneName
)
:
blockPointField_(blockPointField),
curvedEdges_(edges),
blockShape_(bshape),
meshDensity_(meshDensity),
edgePoints_(12),
edgeWeights_(12),
expand_(expand),
zoneName_(zoneName)
{
if (expand_.size() != 12)
{
FatalErrorIn
(
"blockDescriptor::blockDescriptor"
"(const cellShape&, const pointField& blockPointField, "
"const curvedEdgeList&, const Vector<label>& meshDensity, "
"const scalarList& expand, const word& zoneName)"
) << "Unknown definition of expansion ratios"
<< exit(FatalError);
}
// create a list of edges
makeBlockEdges();
}
Foam::blockDescriptor::blockDescriptor
(
const pointField& blockPointField,
const curvedEdgeList& edges,
Istream& is
)
:
blockPointField_(blockPointField),
curvedEdges_(edges),
blockShape_(is),
meshDensity_(),
edgePoints_(12),
edgeWeights_(12),
expand_(12, 1.0),
zoneName_()
{
// Examine next token
token t(is);
// Optional zone name
if (t.isWord())
{
zoneName_ = t.wordToken();
// Examine next token
is >> t;
}
is.putBack(t);
if (t.isPunctuation())
{
// new-style: read a list of 3 values
if (t.pToken() == token::BEGIN_LIST)
{
is >> meshDensity_;
}
else
{
FatalIOErrorIn
(
"blockDescriptor::blockDescriptor"
"(const pointField&, const curvedEdgeList&, Istream&)",
is
) << "incorrect token while reading n, expected '(', found "
<< t.info()
<< exit(FatalIOError);
}
}
else
{
// old-style: read three labels
is >> meshDensity_.x()
>> meshDensity_.y()
>> meshDensity_.z();
}
is >> t;
if (!t.isWord())
{
is.putBack(t);
}
scalarList expRatios(is);
if (expRatios.size() == 1)
{
// identical in x/y/z-directions
expand_ = expRatios[0];
}
else if (expRatios.size() == 3)
{
// x-direction
expand_[0] = expRatios[0];
expand_[1] = expRatios[0];
expand_[2] = expRatios[0];
expand_[3] = expRatios[0];
// y-direction
expand_[4] = expRatios[1];
expand_[5] = expRatios[1];
expand_[6] = expRatios[1];
expand_[7] = expRatios[1];
// z-direction
expand_[8] = expRatios[2];
expand_[9] = expRatios[2];
expand_[10] = expRatios[2];
expand_[11] = expRatios[2];
}
else if (expRatios.size() == 12)
{
expand_ = expRatios;
}
else
{
FatalErrorIn
(
"blockDescriptor::blockDescriptor"
"(const pointField&, const curvedEdgeList&, Istream&)"
) << "Unknown definition of expansion ratios: " << expRatios
<< exit(FatalError);
}
// create a list of edges
makeBlockEdges();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::blockDescriptor::~blockDescriptor()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::pointField& Foam::blockDescriptor::blockPointField() const
{
return blockPointField_;
}
const Foam::cellShape& Foam::blockDescriptor::blockShape() const
{
return blockShape_;
}
const Foam::List< Foam::List< Foam::point > >&
Foam::blockDescriptor::blockEdgePoints() const
{
return edgePoints_;
}
const Foam::scalarListList& Foam::blockDescriptor::blockEdgeWeights() const
{
return edgeWeights_;
}
const Foam::Vector<Foam::label>& Foam::blockDescriptor::meshDensity() const
{
return meshDensity_;
}
const Foam::word& Foam::blockDescriptor::zoneName() const
{
return zoneName_;
}
Foam::label Foam::blockDescriptor::nPoints() const
{
return
(
(meshDensity_.x() + 1)
* (meshDensity_.y() + 1)
* (meshDensity_.z() + 1)
);
}
Foam::label Foam::blockDescriptor::nCells() const
{
return
(
meshDensity_.x()
* meshDensity_.y()
* meshDensity_.z()
);
}
const Foam::point& Foam::blockDescriptor::blockPoint(const label i) const
{
return blockPointField_[blockShape_[i]];
}
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const blockDescriptor& bd)
{
const cellShape& bshape = bd.blockShape();
const labelList& blockLabels = bshape;
os << bshape.model().name() << " (";
forAll(blockLabels, labelI)
{
if (labelI)
{
os << ' ';
}
os << blockLabels[labelI];
}
os << ')';
if (bd.zoneName().size())
{
os << ' ' << bd.zoneName();
}
os << ' ' << bd.meshDensity()
<< " simpleGrading (";
const scalarList& expand = bd.expand_;
// can we use a compact notation?
if
(
// x-direction
(
expand[0] == expand[1]
&& expand[0] == expand[2]
&& expand[0] == expand[3]
)
&& // y-direction
(
expand[4] == expand[5]
&& expand[4] == expand[6]
&& expand[4] == expand[7]
)
&& // z-direction
(
expand[8] == expand[9]
&& expand[8] == expand[10]
&& expand[8] == expand[11]
)
)
{
os << expand[0] << ' ' << expand[4] << ' ' << expand[8];
}
else
{
forAll(expand, edgeI)
{
if (edgeI)
{
os << ' ';
}
os << expand[edgeI];
}
}
os << ")";
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,187 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::blockDescriptor
Description
Takes the description of the block and the list of curved edges and
creates a list of points on edges together with the weighting factors
SourceFiles
blockDescriptor.C
blockDescriptorEdges.C
\*---------------------------------------------------------------------------*/
#ifndef blockDescriptor_H
#define blockDescriptor_H
#include "cellShape.H"
#include "pointField.H"
#include "scalarList.H"
#include "curvedEdgeList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class Istream;
class Ostream;
// Forward declaration of friend functions and operators
class blockMesh;
class blockDescriptor;
Ostream& operator<<(Ostream&, const blockDescriptor&);
/*---------------------------------------------------------------------------*\
Class blockDescriptor Declaration
\*---------------------------------------------------------------------------*/
class blockDescriptor
{
// Private data
//- Reference to point field defining the block mesh
const pointField& blockPointField_;
//- Reference to a list of curved edges
const curvedEdgeList& curvedEdges_;
//- Block shape
cellShape blockShape_;
//- The number of cells in the i,j,k directions
Vector<label> meshDensity_;
//- Block edge points
List< List<point> > edgePoints_;
//- Block edge weighting factors
scalarListList edgeWeights_;
//- Expansion ratios in all directions
scalarList expand_;
//- Name of the zone (empty string if none)
word zoneName_;
// Private Member Functions
//- Set the points/weights for all edges
void makeBlockEdges();
//- Set the edge points/weights
void setEdge(label edgeI, label start, label end, label dim);
// Private Member Functions
//- Disallow default bitwise assignment
void operator=(const blockDescriptor&);
public:
// Constructors
//- Construct from components. Optional cellSet/zone name.
blockDescriptor
(
const cellShape&,
const pointField& blockPointField,
const curvedEdgeList&,
const Vector<label>& meshDensity,
const UList<scalar>& expand,
const word& zoneName = ""
);
//- Construct from Istream
blockDescriptor
(
const pointField& blockPointField,
const curvedEdgeList&,
Istream&
);
//- Clone
autoPtr<blockDescriptor> clone() const
{
notImplemented("blockDescriptor::clone()");
return autoPtr<blockDescriptor>(NULL);
}
//- Destructor
~blockDescriptor();
// Member Functions
// Access
//- Reference to point field defining the block mesh
const pointField& blockPointField() const;
//- Return the block shape
const cellShape& blockShape() const;
//- Return the block points along each edge
const List< List<point> >& blockEdgePoints() const;
//- Return the weightings along each edge
const scalarListList& blockEdgeWeights() const;
//- Return the mesh density (number of cells) in the i,j,k directions
const Vector<label>& meshDensity() const;
//- Return the (optional) zone name
const word& zoneName() const;
//- Return the number of points
label nPoints() const;
//- Return the number of cells
label nCells() const;
//- Return block point at local label i
const point& blockPoint(const label i) const;
// IOstream Operators
friend Ostream& operator<<(Ostream&, const blockDescriptor&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,157 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "blockDescriptor.H"
#include "lineEdge.H"
#include "lineDivide.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//! \cond fileScope
// Calculate the geometric expension factor from the expansion ratio
inline scalar calcGexp(const scalar expRatio, const label dim)
{
return dim > 1 ? pow(expRatio, 1.0/(dim - 1)) : 0.0;
}
//! \endcond
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::blockDescriptor::makeBlockEdges()
{
const label ni = meshDensity_.x();
const label nj = meshDensity_.y();
const label nk = meshDensity_.z();
// these edges correspond to the "hex" cellModel
// x-direction
setEdge(0, 0, 1, ni);
setEdge(1, 3, 2, ni);
setEdge(2, 7, 6, ni);
setEdge(3, 4, 5, ni);
// y-direction
setEdge(4, 0, 3, nj);
setEdge(5, 1, 2, nj);
setEdge(6, 5, 6, nj);
setEdge(7, 4, 7, nj);
// z-direction
setEdge(8, 0, 4, nk);
setEdge(9, 1, 5, nk);
setEdge(10, 2, 6, nk);
setEdge(11, 3, 7, nk);
}
void Foam::blockDescriptor::setEdge
(
label edgeI,
label start,
label end,
label dim
)
{
// set reference to the list of labels defining the block
const labelList& blockLabels = blockShape_;
// set reference to global list of points
const pointField blockPoints = blockShape_.points(blockPointField_);
// Set the edge points/weights
// The edge is a straight-line if it is not in the list of curvedEdges
// calc geometric expension factor from the expansion ratio
const scalar gExp = calcGexp(expand_[edgeI], dim);
forAll(curvedEdges_, cedgeI)
{
const curvedEdge& cedge = curvedEdges_[cedgeI];
int cmp = cedge.compare(blockLabels[start], blockLabels[end]);
if (cmp)
{
if (cmp > 0)
{
// curve has the same orientation
// divide the line
lineDivide divEdge(cedge, dim, gExp);
edgePoints_[edgeI] = divEdge.points();
edgeWeights_[edgeI] = divEdge.lambdaDivisions();
}
else
{
// curve has the opposite orientation
// divide the line
lineDivide divEdge(cedge, dim, 1.0/(gExp+SMALL));
const pointField& p = divEdge.points();
const scalarList& d = divEdge.lambdaDivisions();
edgePoints_[edgeI].setSize(p.size());
edgeWeights_[edgeI].setSize(d.size());
label pMax = p.size() - 1;
forAll(p, pI)
{
edgePoints_[edgeI][pI] = p[pMax - pI];
edgeWeights_[edgeI][pI] = 1.0 - d[pMax - pI];
}
}
// found curved-edge: done
return;
}
}
// not found: divide the edge as a straight line
lineDivide divEdge
(
lineEdge(blockPoints, start, end),
dim,
gExp
);
edgePoints_[edgeI] = divEdge.points();
edgeWeights_[edgeI] = divEdge.lambdaDivisions();
}
// ************************************************************************* //

View file

@ -0,0 +1,191 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "blockMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
bool Foam::blockMesh::blockMesh::verboseOutput(false);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::blockMesh::blockMesh(const IOdictionary& dict, const word& regionName)
:
blockPointField_(dict.lookup("vertices")),
scaleFactor_(1.0),
topologyPtr_(createTopology(dict, regionName))
{
calcMergeInfo();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::blockMesh::~blockMesh()
{
delete topologyPtr_;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::blockMesh::verbose(const bool on)
{
verboseOutput = on;
}
const Foam::pointField& Foam::blockMesh::blockPointField() const
{
return blockPointField_;
}
const Foam::polyMesh& Foam::blockMesh::topology() const
{
if (!topologyPtr_)
{
FatalErrorIn("blockMesh::topology() const")
<< "topologyPtr_ not allocated"
<< exit(FatalError);
}
return *topologyPtr_;
}
Foam::PtrList<Foam::dictionary> Foam::blockMesh::patchDicts() const
{
const polyPatchList& patchTopologies = topology().boundaryMesh();
PtrList<dictionary> patchDicts(patchTopologies.size());
forAll(patchTopologies, patchI)
{
OStringStream os;
patchTopologies[patchI].write(os);
IStringStream is(os.str());
patchDicts.set(patchI, new dictionary(is));
}
return patchDicts;
}
Foam::scalar Foam::blockMesh::scaleFactor() const
{
return scaleFactor_;
}
const Foam::pointField& Foam::blockMesh::points() const
{
if (points_.empty())
{
createPoints();
}
return points_;
}
const Foam::cellShapeList& Foam::blockMesh::cells() const
{
if (cells_.empty())
{
createCells();
}
return cells_;
}
const Foam::faceListList& Foam::blockMesh::patches() const
{
if (patches_.empty())
{
createPatches();
}
return patches_;
}
Foam::wordList Foam::blockMesh::patchNames() const
{
return topology().boundaryMesh().names();
}
//Foam::wordList Foam::blockMesh::patchTypes() const
//{
// return topology().boundaryMesh().types();
//}
//
//
//Foam::wordList Foam::blockMesh::patchPhysicalTypes() const
//{
// return topology().boundaryMesh().physicalTypes();
//}
Foam::label Foam::blockMesh::numZonedBlocks() const
{
label num = 0;
forAll(*this, blockI)
{
if (operator[](blockI).zoneName().size())
{
num++;
}
}
return num;
}
void Foam::blockMesh::writeTopology(Ostream& os) const
{
const pointField& pts = topology().points();
forAll(pts, pI)
{
const point& pt = pts[pI];
os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
}
const edgeList& edges = topology().edges();
forAll(edges, eI)
{
const edge& e = edges[eI];
os << "l " << e.start() + 1 << ' ' << e.end() + 1 << endl;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,223 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::blockMesh
Description
A multi-block mesh generator
Note
The vertices, cells and patches for filling the blocks are demand-driven.
SourceFiles
blockMesh.C
blockMeshCheck.C
blockMeshCreate.C
blockMeshMerge.C
blockMeshTopology.C
\*---------------------------------------------------------------------------*/
#ifndef blockMesh_H
#define blockMesh_H
#include "blockList.H"
#include "polyMesh.H"
#include "IOdictionary.H"
#include "curvedEdgeList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class blockMesh Declaration
\*---------------------------------------------------------------------------*/
class blockMesh
:
public blockList
{
// Private data
static bool verboseOutput;
//- Point field defining the block mesh (corners)
pointField blockPointField_;
//- The list of curved edges
curvedEdgeList edges_;
//- The scaling factor to convert to metres
scalar scaleFactor_;
//- The blocks themselves (the topology) as a polyMesh
polyMesh* topologyPtr_;
label nPoints_;
//- The sum of all cells in each block
label nCells_;
//- The point offset added to each block
labelList blockOffsets_;
//- The merge points information
labelList mergeList_;
mutable pointField points_;
mutable cellShapeList cells_;
mutable faceListList patches_;
// Private Member Functions
bool blockLabelsOK
(
const label blockLabel,
const pointField& points,
const cellShape& blockShape
) const;
bool patchLabelsOK
(
const label patchLabel,
const pointField& points,
const faceList& patchShapes
) const;
bool readPatches
(
const dictionary& meshDescription,
faceListList& tmpBlocksPatches,
wordList& patchNames,
wordList& patchTypes,
wordList& nbrPatchNames
);
bool readBoundary
(
const dictionary& meshDescription,
wordList& patchNames,
faceListList& tmpBlocksPatches,
PtrList<dictionary>& patchDicts
);
void createCellShapes(cellShapeList& tmpBlockCells);
polyMesh* createTopology(const IOdictionary&, const word& regionName);
void checkBlockMesh(const polyMesh&) const;
//- Determine the merge info and the final number of cells/points
void calcMergeInfo();
faceList createPatchFaces(const polyPatch& patchTopologyFaces) const;
void createPoints() const;
void createCells() const;
void createPatches() const;
//- as copy (not implemented)
blockMesh(const blockMesh&);
public:
// Constructors
//- Construct from IOdictionary
blockMesh(const IOdictionary&, const word& regionName);
//- Destructor
~blockMesh();
// Member Functions
// Access
//- Reference to point field defining the block mesh
// these points have not been scaled by scaleFactor
const pointField& blockPointField() const;
const polyMesh& topology() const;
const curvedEdgeList& edges() const
{
return edges_;
}
//- The scaling factor used to convert to metres
scalar scaleFactor() const;
//- The points for the entire mesh
// these points have been scaled by scaleFactor
const pointField& points() const;
const cellShapeList& cells() const;
const faceListList& patches() const;
//- Get patch information from the topology mesh
PtrList<dictionary> patchDicts() const;
wordList patchNames() const;
// wordList patchTypes() const;
//
// wordList patchPhysicalTypes() const;
//- Number of blocks with specified zones
label numZonedBlocks() const;
// Edit
//- Clear geometry (internal points, cells, boundaryPatches)
void clearGeom();
//- Enable/disable verbose information about the progress
static void verbose(const bool on=true);
// Write
//- Writes edges of blockMesh in OBJ format.
void writeTopology(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,236 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "blockMesh.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Check the blockMesh topology
void Foam::blockMesh::checkBlockMesh(const polyMesh& bm) const
{
if (verboseOutput)
{
Info<< nl << "Check topology" << endl;
}
bool ok = true;
const pointField& points = bm.points();
const faceList& faces = bm.faces();
const cellList& cells = bm.cells();
const polyPatchList& patches = bm.boundaryMesh();
label nBoundaryFaces = 0;
forAll(cells, celli)
{
nBoundaryFaces += cells[celli].nFaces();
}
nBoundaryFaces -= 2*bm.nInternalFaces();
label nDefinedBoundaryFaces = 0;
forAll(patches, patchi)
{
nDefinedBoundaryFaces += patches[patchi].size();
}
if (verboseOutput)
{
Info<< nl << tab << "Basic statistics" << nl
<< tab << tab << "Number of internal faces : "
<< bm.nInternalFaces() << nl
<< tab << tab << "Number of boundary faces : "
<< nBoundaryFaces << nl
<< tab << tab << "Number of defined boundary faces : "
<< nDefinedBoundaryFaces << nl
<< tab << tab << "Number of undefined boundary faces : "
<< nBoundaryFaces - nDefinedBoundaryFaces << nl;
if ((nBoundaryFaces - nDefinedBoundaryFaces) > 0)
{
Info<< tab << tab << tab
<< "(Warning : only leave undefined the front and back planes "
<< "of 2D planar geometries!)" << endl;
}
Info<< tab << "Checking patch -> block consistency" << endl;
}
forAll(patches, patchi)
{
const faceList& Patch = patches[patchi];
forAll(Patch, patchFacei)
{
const face& patchFace = Patch[patchFacei];
bool patchFaceOK = false;
forAll(cells, celli)
{
const labelList& cellFaces = cells[celli];
forAll(cellFaces, cellFacei)
{
if (patchFace == faces[cellFaces[cellFacei]])
{
patchFaceOK = true;
if
(
(
patchFace.normal(points)
& faces[cellFaces[cellFacei]].normal(points)
) < 0.0
)
{
Info<< tab << tab
<< "Face " << patchFacei
<< " of patch " << patchi
<< " (" << patches[patchi].name() << ")"
<< " points inwards"
<< endl;
ok = false;
}
}
}
}
if (!patchFaceOK)
{
Info<< tab << tab
<< "Face " << patchFacei
<< " of patch " << patchi
<< " (" << patches[patchi].name() << ")"
<< " does not match any block faces" << endl;
ok = false;
}
}
}
if (verboseOutput)
{
Info<< endl;
}
if (!ok)
{
FatalErrorIn("blockMesh::checkBlockMesh(const polyMesh& bm)")
<< "Block mesh topology incorrect, stopping mesh generation!"
<< exit(FatalError);
}
}
bool Foam::blockMesh::blockLabelsOK
(
const label blockLabel,
const pointField& points,
const cellShape& blockShape
) const
{
bool ok = true;
forAll(blockShape, blockI)
{
if (blockShape[blockI] < 0)
{
ok = false;
WarningIn
(
"bool Foam::blockMesh::blockLabelsOK(...)"
) << "out-of-range point label " << blockShape[blockI]
<< " (min = 0"
<< ") in block " << blockLabel << endl;
}
else if (blockShape[blockI] >= points.size())
{
ok = false;
WarningIn
(
"bool Foam::blockMesh::blockLabelsOK(...)"
) << "out-of-range point label " << blockShape[blockI]
<< " (max = " << points.size() - 1
<< ") in block " << blockLabel << endl;
}
}
return ok;
}
bool Foam::blockMesh::patchLabelsOK
(
const label patchLabel,
const pointField& points,
const faceList& patchFaces
) const
{
bool ok = true;
forAll(patchFaces, faceI)
{
const labelList& f = patchFaces[faceI];
forAll(f, fp)
{
if (f[fp] < 0)
{
ok = false;
WarningIn
(
"bool Foam::blockMesh::patchLabelsOK(...)"
) << "out-of-range point label " << f[fp]
<< " (min = 0"
<< ") on patch " << patchLabel
<< ", face " << faceI << endl;
}
else if (f[fp] >= points.size())
{
ok = false;
WarningIn
(
"bool Foam::blockMesh::patchLabelsOK(...)"
) << "out-of-range point label " << f[fp]
<< " (max = " << points.size() - 1
<< ") on patch " << patchLabel
<< ", face " << faceI << endl;
}
}
}
return ok;
}
// ************************************************************************* //

View file

@ -0,0 +1,293 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "blockMesh.H"
#include "cellModeller.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::blockMesh::createPoints() const
{
const blockList& blocks = *this;
if (verboseOutput)
{
Info<< "Creating points with scale " << scaleFactor_ << endl;
}
//
// generate points
//
points_.clear();
points_.setSize(nPoints_);
forAll(blocks, blockI)
{
const pointField& blockPoints = blocks[blockI].points();
if (verboseOutput)
{
const Vector<label>& density = blocks[blockI].meshDensity();
label v0 = blocks[blockI].vtxLabel(0, 0, 0);
label vi1 = blocks[blockI].vtxLabel(1, 0, 0);
scalar diStart = mag(blockPoints[vi1]-blockPoints[v0]);
label vinM1 = blocks[blockI].vtxLabel(density.x()-1, 0, 0);
label vin = blocks[blockI].vtxLabel(density.x(), 0, 0);
scalar diFinal = mag(blockPoints[vin]-blockPoints[vinM1]);
label vj1 = blocks[blockI].vtxLabel(0, 1, 0);
scalar djStart = mag(blockPoints[vj1]-blockPoints[v0]);
label vjnM1 = blocks[blockI].vtxLabel(0, density.y()-1, 0);
label vjn = blocks[blockI].vtxLabel(0, density.y(), 0);
scalar djFinal = mag(blockPoints[vjn]-blockPoints[vjnM1]);
label vk1 = blocks[blockI].vtxLabel(0, 0, 1);
scalar dkStart = mag(blockPoints[vk1]-blockPoints[v0]);
label vknM1 = blocks[blockI].vtxLabel(0, 0, density.z()-1);
label vkn = blocks[blockI].vtxLabel(0, 0, density.z());
scalar dkFinal = mag(blockPoints[vkn]-blockPoints[vknM1]);
Info<< " Block " << blockI << " cell size :" << nl
<< " i : " << scaleFactor_*diStart << " .. "
<< scaleFactor_*diFinal << nl
<< " j : " << scaleFactor_*djStart << " .. "
<< scaleFactor_*djFinal << nl
<< " k : " << scaleFactor_*dkStart << " .. "
<< scaleFactor_*dkFinal << nl
<< endl;
}
forAll(blockPoints, blockPointI)
{
points_
[
mergeList_
[
blockOffsets_[blockI] + blockPointI
]
] = scaleFactor_ * blockPoints[blockPointI];
}
}
}
void Foam::blockMesh::createCells() const
{
const blockList& blocks = *this;
const cellModel& hex = *(cellModeller::lookup("hex"));
if (verboseOutput)
{
Info<< "Creating cells" << endl;
}
//
// generate cells
//
cells_.clear();
cells_.setSize(nCells_);
label cellLabel = 0;
forAll(blocks, blockI)
{
const labelListList& blockCells = blocks[blockI].cells();
forAll(blockCells, blockCellI)
{
labelList cellPoints(blockCells[blockCellI].size());
forAll(cellPoints, cellPointI)
{
cellPoints[cellPointI] =
mergeList_
[
blockCells[blockCellI][cellPointI]
+ blockOffsets_[blockI]
];
}
// Construct collapsed cell and add to list
cells_[cellLabel] = cellShape(hex, cellPoints, true);
cellLabel++;
}
}
}
Foam::faceList Foam::blockMesh::createPatchFaces
(
const polyPatch& patchTopologyFaces
) const
{
const blockList& blocks = *this;
labelList blockLabels = patchTopologyFaces.polyPatch::faceCells();
label nFaces = 0;
forAll(patchTopologyFaces, patchTopologyFaceLabel)
{
const label blockI = blockLabels[patchTopologyFaceLabel];
faceList blockFaces = blocks[blockI].blockShape().faces();
forAll(blockFaces, blockFaceLabel)
{
if
(
blockFaces[blockFaceLabel]
== patchTopologyFaces[patchTopologyFaceLabel]
)
{
nFaces +=
blocks[blockI].boundaryPatches()[blockFaceLabel].size();
}
}
}
faceList patchFaces(nFaces);
face quadFace(4);
label faceLabel = 0;
forAll(patchTopologyFaces, patchTopologyFaceLabel)
{
const label blockI = blockLabels[patchTopologyFaceLabel];
faceList blockFaces = blocks[blockI].blockShape().faces();
forAll(blockFaces, blockFaceLabel)
{
if
(
blockFaces[blockFaceLabel]
== patchTopologyFaces[patchTopologyFaceLabel]
)
{
const labelListList& blockPatchFaces =
blocks[blockI].boundaryPatches()[blockFaceLabel];
forAll(blockPatchFaces, blockFaceLabel)
{
// Lookup the face points
// and collapse duplicate point labels
quadFace[0] =
mergeList_
[
blockPatchFaces[blockFaceLabel][0]
+ blockOffsets_[blockI]
];
label nUnique = 1;
for
(
label facePointLabel = 1;
facePointLabel < 4;
facePointLabel++
)
{
quadFace[nUnique] =
mergeList_
[
blockPatchFaces[blockFaceLabel][facePointLabel]
+ blockOffsets_[blockI]
];
if (quadFace[nUnique] != quadFace[nUnique-1])
{
nUnique++;
}
}
if (quadFace[nUnique-1] == quadFace[0])
{
nUnique--;
}
if (nUnique == 4)
{
patchFaces[faceLabel++] = quadFace;
}
else if (nUnique == 3)
{
patchFaces[faceLabel++] = face
(
labelList::subList(quadFace, 3)
);
}
// else the face has collapsed to an edge or point
}
}
}
}
patchFaces.setSize(faceLabel);
return patchFaces;
}
void Foam::blockMesh::createPatches() const
{
const polyPatchList& topoPatches = topology().boundaryMesh();
if (verboseOutput)
{
Info<< "Creating patches" << endl;
}
//
// generate points
//
patches_.clear();
patches_.setSize(topoPatches.size());
forAll(topoPatches, patchI)
{
patches_[patchI] = createPatchFaces(topoPatches[patchI]);
}
}
void Foam::blockMesh::clearGeom()
{
blockList& blocks = *this;
forAll(blocks, blockI)
{
blocks[blockI].clearGeom();
}
}
// ************************************************************************* //

View file

@ -1,25 +1,25 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
This file is part of OpenFOAM.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
foam-extend 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.
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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
@ -27,13 +27,38 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::labelList Foam::blockMesh::createMergeList()
void Foam::blockMesh::calcMergeInfo()
{
Info<< nl << "Creating merge list " << flush;
const blockList& blocks = *this;
labelList MergeList(nPoints_, -1);
if (verboseOutput)
{
Info<< "Creating block offsets" << endl;
}
blockOffsets_.setSize(blocks.size());
nPoints_ = 0;
nCells_ = 0;
forAll(blocks, blockI)
{
blockOffsets_[blockI] = nPoints_;
nPoints_ += blocks[blockI].nPoints();
nCells_ += blocks[blockI].nCells();
}
if (verboseOutput)
{
Info<< "Creating merge list " << flush;
}
// set unused to -1
mergeList_.setSize(nPoints_);
mergeList_ = -1;
blockMesh& blocks = *this;
const pointField& blockPoints = topology().points();
const cellList& blockCells = topology().cells();
@ -45,6 +70,7 @@ Foam::labelList Foam::blockMesh::createMergeList()
const labelList& faceNeighbourBlocks = topology().faceNeighbour();
forAll(blockFaces, blockFaceLabel)
{
label blockPlabel = faceOwnerBlocks[blockFaceLabel];
@ -73,10 +99,10 @@ Foam::labelList Foam::blockMesh::createMergeList()
if (!foundFace)
{
FatalErrorIn("blockMesh::createMergeList()")
FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Cannot find merge face for block " << blockPlabel
<< exit(FatalError);
};
}
const labelListList& blockPfaceFaces =
blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
@ -92,7 +118,7 @@ Foam::labelList Foam::blockMesh::createMergeList()
// the size of the block.
boundBox bb(blockCells[blockPlabel].points(blockFaces, blockPoints));
const scalar mergeSqrDist = SMALL*magSqr(bb.span());
const scalar mergeSqrDist = magSqr(SMALL*bb.span());
// This is an N^2 algorithm
@ -129,17 +155,17 @@ Foam::labelList Foam::blockMesh::createMergeList()
label minPP2 = min(PpointLabel, PpointLabel2);
if (MergeList[PpointLabel] != -1)
if (mergeList_[PpointLabel] != -1)
{
minPP2 = min(minPP2, MergeList[PpointLabel]);
minPP2 = min(minPP2, mergeList_[PpointLabel]);
}
if (MergeList[PpointLabel2] != -1)
if (mergeList_[PpointLabel2] != -1)
{
minPP2 = min(minPP2, MergeList[PpointLabel2]);
minPP2 = min(minPP2, mergeList_[PpointLabel2]);
}
MergeList[PpointLabel] = MergeList[PpointLabel2]
mergeList_[PpointLabel] = mergeList_[PpointLabel2]
= minPP2;
}
else
@ -182,22 +208,23 @@ Foam::labelList Foam::blockMesh::createMergeList()
if (!foundFace)
{
FatalErrorIn("blockMesh::createMergeList()")
FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Cannot find merge face for block " << blockNlabel
<< exit(FatalError);
};
}
const labelListList& blockNfaceFaces =
blocks[blockNlabel].boundaryPatches()[blockNfaceLabel];
if (blockPfaceFaces.size() != blockNfaceFaces.size())
{
FatalErrorIn("blockMesh::createMergeList()")
FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Inconsistent number of faces between block pair "
<< blockPlabel << " and " << blockNlabel
<< exit(FatalError);
}
// N-squared point search over all points of all faces of
// master block over all point of all faces of slave block
forAll(blockPfaceFaces, blockPfaceFaceLabel)
@ -211,8 +238,6 @@ Foam::labelList Foam::blockMesh::createMergeList()
forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
{
bool found = false;
forAll(blockNfaceFaces, blockNfaceFaceLabel)
{
const labelList& blockNfaceFacePoints
@ -232,7 +257,6 @@ Foam::labelList Foam::blockMesh::createMergeList()
)
{
// Found a new pair
found = true;
cp[blockPfaceFacePointLabel] =
blockNfaceFacePoints[blockNfaceFacePointLabel];
@ -247,17 +271,17 @@ Foam::labelList Foam::blockMesh::createMergeList()
label minPN = min(PpointLabel, NpointLabel);
if (MergeList[PpointLabel] != -1)
if (mergeList_[PpointLabel] != -1)
{
minPN = min(minPN, MergeList[PpointLabel]);
minPN = min(minPN, mergeList_[PpointLabel]);
}
if (MergeList[NpointLabel] != -1)
if (mergeList_[NpointLabel] != -1)
{
minPN = min(minPN, MergeList[NpointLabel]);
minPN = min(minPN, mergeList_[NpointLabel]);
}
MergeList[PpointLabel] = MergeList[NpointLabel]
mergeList_[PpointLabel] = mergeList_[NpointLabel]
= minPN;
}
}
@ -267,7 +291,7 @@ Foam::labelList Foam::blockMesh::createMergeList()
{
if (cp[blockPfaceFacePointLabel] == -1)
{
FatalErrorIn("blockMesh::createMergeList()")
FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Inconsistent point locations between block pair "
<< blockPlabel << " and " << blockNlabel << nl
<< " probably due to inconsistent grading."
@ -321,6 +345,8 @@ Foam::labelList Foam::blockMesh::createMergeList()
}
}
// FIXME? - there seems to be some logic missing here
label blockNfaceLabel;
for
(
@ -339,6 +365,9 @@ Foam::labelList Foam::blockMesh::createMergeList()
}
}
// FIXME? - there seems to be some logic missing here
const labelListList& blockPfaceFaces =
blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
@ -361,34 +390,41 @@ Foam::labelList Foam::blockMesh::createMergeList()
if
(
MergeList[PpointLabel]
!= MergeList[NpointLabel]
mergeList_[PpointLabel]
!= mergeList_[NpointLabel]
)
{
changedPointMerge = true;
MergeList[PpointLabel]
= MergeList[NpointLabel]
mergeList_[PpointLabel]
= mergeList_[NpointLabel]
= min
(
MergeList[PpointLabel],
MergeList[NpointLabel]
mergeList_[PpointLabel],
mergeList_[NpointLabel]
);
}
}
}
}
Info << "." << flush;
if (verboseOutput)
{
Info<< "." << flush;
}
if (nPasses > 100)
{
FatalErrorIn("blockMesh::createMergeList()")
FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Point merging failed after max number of passes."
<< abort(FatalError);
}
}
while (changedPointMerge);
Info << endl;
if (verboseOutput)
{
Info<< endl;
}
forAll(blockInternalFaces, blockFaceLabel)
{
@ -423,10 +459,10 @@ Foam::labelList Foam::blockMesh::createMergeList()
if (!foundFace)
{
FatalErrorIn("blockMesh::createMergeList()")
FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Cannot find merge face for block " << blockPlabel
<< exit(FatalError);
};
}
foundFace = false;
label blockNfaceLabel;
@ -450,10 +486,10 @@ Foam::labelList Foam::blockMesh::createMergeList()
if (!foundFace)
{
FatalErrorIn("blockMesh::createMergeList()")
FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Cannot find merge face for block " << blockNlabel
<< exit(FatalError);
};
}
const labelListList& blockPfaceFaces =
blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
@ -472,9 +508,9 @@ Foam::labelList Foam::blockMesh::createMergeList()
blockPfaceFacePoints[blockPfaceFacePointLabel]
+ blockOffsets_[blockPlabel];
if (MergeList[PpointLabel] == -1)
if (mergeList_[PpointLabel] == -1)
{
FatalErrorIn("blockMesh::createMergeList()")
FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Unable to merge point "
<< blockPfaceFacePointLabel
<< ' ' << blockPpoints[blockPfaceFacePointLabel]
@ -498,9 +534,9 @@ Foam::labelList Foam::blockMesh::createMergeList()
blockNfaceFacePoints[blockNfaceFacePointLabel]
+ blockOffsets_[blockNlabel];
if (MergeList[NpointLabel] == -1)
if (mergeList_[NpointLabel] == -1)
{
FatalErrorIn("blockMesh::createMergeList()")
FatalErrorIn("blockMesh::calcMergeInfo()")
<< "unable to merge point "
<< blockNfaceFacePointLabel
<< ' ' << blockNpoints[blockNfaceFacePointLabel]
@ -519,33 +555,31 @@ Foam::labelList Foam::blockMesh::createMergeList()
// given old point label
label newPointLabel = 0;
forAll(MergeList, pointLabel)
forAll(mergeList_, pointLabel)
{
if (MergeList[pointLabel] > pointLabel)
if (mergeList_[pointLabel] > pointLabel)
{
FatalErrorIn("blockMesh::createMergeList()")
FatalErrorIn("blockMesh::calcMergeInfo()")
<< "ouch" << exit(FatalError);
}
if
(
(MergeList[pointLabel] == -1)
|| MergeList[pointLabel] == pointLabel
mergeList_[pointLabel] == -1
|| mergeList_[pointLabel] == pointLabel
)
{
MergeList[pointLabel] = newPointLabel;
mergeList_[pointLabel] = newPointLabel;
newPointLabel++;
}
else
{
MergeList[pointLabel] = MergeList[MergeList[pointLabel]];
mergeList_[pointLabel] = mergeList_[mergeList_[pointLabel]];
}
}
nPoints_ = newPointLabel;
return MergeList;
}
// ************************************************************************* //

View file

@ -0,0 +1,608 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "blockMesh.H"
#include "Time.H"
#include "preservePatchTypes.H"
#include "emptyPolyPatch.H"
#include "cyclicPolyPatch.H"
bool Foam::blockMesh::readPatches
(
const dictionary& meshDescription,
faceListList& tmpBlocksPatches,
wordList& patchNames,
wordList& patchTypes,
wordList& nbrPatchNames
)
{
bool topologyOK = true;
ITstream& patchStream(meshDescription.lookup("patches"));
// read number of patches in mesh
label nPatches = 0;
token firstToken(patchStream);
if (firstToken.isLabel())
{
nPatches = firstToken.labelToken();
tmpBlocksPatches.setSize(nPatches);
patchNames.setSize(nPatches);
patchTypes.setSize(nPatches);
nbrPatchNames.setSize(nPatches);
}
else
{
patchStream.putBack(firstToken);
}
// Read beginning of blocks
patchStream.readBegin("patches");
nPatches = 0;
token lastToken(patchStream);
while
(
!(
lastToken.isPunctuation()
&& lastToken.pToken() == token::END_LIST
)
)
{
if (tmpBlocksPatches.size() <= nPatches)
{
tmpBlocksPatches.setSize(nPatches + 1);
patchNames.setSize(nPatches + 1);
patchTypes.setSize(nPatches + 1);
nbrPatchNames.setSize(nPatches + 1);
}
patchStream.putBack(lastToken);
patchStream
>> patchTypes[nPatches]
>> patchNames[nPatches];
// Read patch faces
patchStream >> tmpBlocksPatches[nPatches];
// Catch multiple patches asap.
for (label i = 0; i < nPatches; i++)
{
if (patchNames[nPatches] == patchNames[i])
{
FatalErrorIn
(
"blockMesh::createTopology(IOdictionary&)"
) << "Duplicate patch " << patchNames[nPatches]
<< " at line " << patchStream.lineNumber()
<< ". Exiting !" << nl
<< exit(FatalError);
}
}
topologyOK = topologyOK && patchLabelsOK
(
nPatches,
blockPointField_,
tmpBlocksPatches[nPatches]
);
nPatches++;
// Split old style cyclics
if (patchTypes[nPatches-1] == cyclicPolyPatch::typeName)
{
word halfA = patchNames[nPatches-1] + "_half0";
word halfB = patchNames[nPatches-1] + "_half1";
WarningIn("blockMesh::createTopology(IOdictionary&)")
<< "Old-style cyclic definition."
<< " Splitting patch "
<< patchNames[nPatches-1] << " into two halves "
<< halfA << " and " << halfB << endl
<< " Alternatively use new 'boundary' dictionary syntax."
<< endl;
// Add extra patch
if (tmpBlocksPatches.size() <= nPatches)
{
tmpBlocksPatches.setSize(nPatches + 1);
patchNames.setSize(nPatches + 1);
patchTypes.setSize(nPatches + 1);
nbrPatchNames.setSize(nPatches + 1);
}
// Update halfA info
patchNames[nPatches-1] = halfA;
nbrPatchNames[nPatches-1] = halfB;
// Update halfB info
patchTypes[nPatches] = patchTypes[nPatches-1];
patchNames[nPatches] = halfB;
nbrPatchNames[nPatches] = halfA;
// Split faces
if ((tmpBlocksPatches[nPatches-1].size() % 2) != 0)
{
FatalErrorIn
(
"blockMesh::createTopology(IOdictionary&)"
) << "Size of cyclic faces is not a multiple of 2 :"
<< tmpBlocksPatches[nPatches-1]
<< exit(FatalError);
}
label sz = tmpBlocksPatches[nPatches-1].size()/2;
faceList unsplitFaces(tmpBlocksPatches[nPatches-1], true);
tmpBlocksPatches[nPatches-1] = faceList
(
SubList<face>(unsplitFaces, sz)
);
tmpBlocksPatches[nPatches] = faceList
(
SubList<face>(unsplitFaces, sz, sz)
);
nPatches++;
}
patchStream >> lastToken;
}
patchStream.putBack(lastToken);
// Read end of blocks
patchStream.readEnd("patches");
return topologyOK;
}
bool Foam::blockMesh::readBoundary
(
const dictionary& meshDescription,
wordList& patchNames,
faceListList& tmpBlocksPatches,
PtrList<dictionary>& patchDicts
)
{
bool topologyOK = true;
// Read like boundary file
const PtrList<entry> patchesInfo
(
meshDescription.lookup("boundary")
);
patchNames.setSize(patchesInfo.size());
tmpBlocksPatches.setSize(patchesInfo.size());
patchDicts.setSize(patchesInfo.size());
forAll(tmpBlocksPatches, patchI)
{
const entry& patchInfo = patchesInfo[patchI];
if (!patchInfo.isDict())
{
FatalIOErrorIn("blockMesh::readBoundary(..)", meshDescription)
<< "Entry " << patchInfo << " in boundary section is not a"
<< " valid dictionary." << exit(FatalIOError);
}
patchNames[patchI] = patchInfo.keyword();
// Construct dictionary
patchDicts.set(patchI, new dictionary(patchInfo.dict()));
// Read block faces
patchDicts[patchI].lookup("faces") >> tmpBlocksPatches[patchI];
topologyOK = topologyOK && patchLabelsOK
(
patchI,
blockPointField_,
tmpBlocksPatches[patchI]
);
}
return topologyOK;
}
void Foam::blockMesh::createCellShapes
(
cellShapeList& tmpBlockCells
)
{
const blockMesh& blocks = *this;
tmpBlockCells.setSize(blocks.size());
forAll(blocks, blockI)
{
tmpBlockCells[blockI] = cellShape(blocks[blockI].blockShape());
if (tmpBlockCells[blockI].mag(blockPointField_) < 0.0)
{
WarningIn
(
"blockMesh::createTopology(IOdictionary&)"
) << "negative volume block : " << blockI
<< ", probably defined inside-out" << endl;
}
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::polyMesh* Foam::blockMesh::createTopology
(
const IOdictionary& meshDescription,
const word& regionName
)
{
bool topologyOK = true;
blockList& blocks = *this;
word defaultPatchName = "defaultFaces";
word defaultPatchType = emptyPolyPatch::typeName;
// get names/types for the unassigned patch faces
// this is a bit heavy handed (and ugly), but there is currently
// no easy way to rename polyMesh patches subsequently
if (const dictionary* dictPtr = meshDescription.subDictPtr("defaultPatch"))
{
dictPtr->readIfPresent("name", defaultPatchName);
dictPtr->readIfPresent("type", defaultPatchType);
}
// optional 'convertToMeters' or 'scale' scaling factor
if (!meshDescription.readIfPresent("convertToMeters", scaleFactor_))
{
meshDescription.readIfPresent("scale", scaleFactor_);
}
//
// get the non-linear edges in mesh
//
if (meshDescription.found("edges"))
{
if (verboseOutput)
{
Info<< "Creating curved edges" << endl;
}
ITstream& is(meshDescription.lookup("edges"));
// read number of edges in mesh
label nEdges = 0;
token firstToken(is);
if (firstToken.isLabel())
{
nEdges = firstToken.labelToken();
edges_.setSize(nEdges);
}
else
{
is.putBack(firstToken);
}
// Read beginning of edges
is.readBegin("edges");
nEdges = 0;
token lastToken(is);
while
(
!(
lastToken.isPunctuation()
&& lastToken.pToken() == token::END_LIST
)
)
{
if (edges_.size() <= nEdges)
{
edges_.setSize(nEdges + 1);
}
is.putBack(lastToken);
edges_.set
(
nEdges,
curvedEdge::New(blockPointField_, is)
);
nEdges++;
is >> lastToken;
}
is.putBack(lastToken);
// Read end of edges
is.readEnd("edges");
}
else if (verboseOutput)
{
Info<< "No non-linear edges defined" << endl;
}
//
// Create the blocks
//
if (verboseOutput)
{
Info<< "Creating topology blocks" << endl;
}
{
ITstream& is(meshDescription.lookup("blocks"));
// read number of blocks in mesh
label nBlocks = 0;
token firstToken(is);
if (firstToken.isLabel())
{
nBlocks = firstToken.labelToken();
blocks.setSize(nBlocks);
}
else
{
is.putBack(firstToken);
}
// Read beginning of blocks
is.readBegin("blocks");
nBlocks = 0;
token lastToken(is);
while
(
!(
lastToken.isPunctuation()
&& lastToken.pToken() == token::END_LIST
)
)
{
if (blocks.size() <= nBlocks)
{
blocks.setSize(nBlocks + 1);
}
is.putBack(lastToken);
blocks.set
(
nBlocks,
new block
(
blockPointField_,
edges_,
is
)
);
topologyOK = topologyOK && blockLabelsOK
(
nBlocks,
blockPointField_,
blocks[nBlocks].blockShape()
);
nBlocks++;
is >> lastToken;
}
is.putBack(lastToken);
// Read end of blocks
is.readEnd("blocks");
}
polyMesh* blockMeshPtr = NULL;
//
// Create the patches
//
if (verboseOutput)
{
Info<< "Creating topology patches" << endl;
}
if (meshDescription.found("patches"))
{
Info<< nl << "Reading patches section" << endl;
faceListList tmpBlocksPatches;
wordList patchNames;
wordList patchTypes;
wordList nbrPatchNames;
topologyOK = topologyOK && readPatches
(
meshDescription,
tmpBlocksPatches,
patchNames,
patchTypes,
nbrPatchNames
);
if (!topologyOK)
{
FatalErrorIn("blockMesh::createTopology(IOdictionary&)")
<< "Cannot create mesh due to errors in topology, exiting !"
<< nl << exit(FatalError);
}
Info<< nl << "Creating block mesh topology" << endl;
cellShapeList tmpBlockCells(blocks.size());
createCellShapes(tmpBlockCells);
Info<< nl << "Reading physicalType from existing boundary file" << endl;
PtrList<dictionary> patchDicts(patchNames.size());
word defaultFacesType;
preservePatchTypes
(
meshDescription.time(),
meshDescription.time().constant(),
polyMesh::meshSubDir,
patchNames,
patchDicts,
defaultPatchName,
defaultPatchType
);
// Add cyclic info (might not be present from older file)
forAll(patchDicts, patchI)
{
if (!patchDicts.set(patchI))
{
patchDicts.set(patchI, new dictionary());
}
dictionary& dict = patchDicts[patchI];
// Add but not override type
if (!dict.found("type"))
{
dict.add("type", patchTypes[patchI], false);
}
else if (word(dict.lookup("type")) != patchTypes[patchI])
{
IOWarningIn
(
"blockMesh::createTopology(IOdictionary&)",
meshDescription
) << "For patch " << patchNames[patchI]
<< " overriding type '" << patchTypes[patchI]
<< "' with '" << word(dict.lookup("type"))
<< "' (read from boundary file)"
<< endl;
}
// Override neighbourpatch name
if (nbrPatchNames[patchI] != word::null)
{
dict.set("neighbourPatch", nbrPatchNames[patchI]);
}
}
blockMeshPtr = new polyMesh
(
IOobject
(
regionName,
meshDescription.time().constant(),
meshDescription.time(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
xferCopy(blockPointField_), // copy these points, do NOT move
tmpBlockCells,
tmpBlocksPatches,
patchNames,
patchDicts,
defaultPatchName,
defaultPatchType
);
}
else if (meshDescription.found("boundary"))
{
wordList patchNames;
faceListList tmpBlocksPatches;
PtrList<dictionary> patchDicts;
topologyOK = topologyOK && readBoundary
(
meshDescription,
patchNames,
tmpBlocksPatches,
patchDicts
);
if (!topologyOK)
{
FatalErrorIn("blockMesh::createTopology(IOdictionary&)")
<< "Cannot create mesh due to errors in topology, exiting !"
<< nl << exit(FatalError);
}
Info<< nl << "Creating block mesh topology" << endl;
cellShapeList tmpBlockCells(blocks.size());
createCellShapes(tmpBlockCells);
// Extract
blockMeshPtr = new polyMesh
(
IOobject
(
regionName,
meshDescription.time().constant(),
meshDescription.time(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
xferCopy(blockPointField_), // copy these points, do NOT move
tmpBlockCells,
tmpBlocksPatches,
patchNames,
patchDicts,
defaultPatchName,
defaultPatchType
);
}
checkBlockMesh(*blockMeshPtr);
return blockMeshPtr;
}
// ************************************************************************* //

View file

@ -1,25 +1,25 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
This file is part of OpenFOAM.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
foam-extend 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.
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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
@ -45,11 +45,11 @@ Foam::point Foam::BSpline::position(const scalar mu) const
// endpoints
if (mu < SMALL)
{
return points_[0];
return points().first();
}
else if (mu > 1 - SMALL)
{
return points_[points_.size()-1];
return points().last();
}
scalar lambda = mu;
@ -67,11 +67,11 @@ Foam::point Foam::BSpline::position
// out-of-bounds
if (segment < 0)
{
return points_[0];
return points().first();
}
else if (segment > nSegments())
{
return points_[points_.size()-1];
return points().last();
}
const point& p0 = points()[segment];

View file

@ -1,25 +1,25 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
This file is part of OpenFOAM.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
foam-extend 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.
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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::BSpline
@ -30,14 +30,14 @@ Description
In this implementation, the end tangents are created automatically
by reflection.
In matrix form, the @e local interpolation on the interval t=[0..1] is
In matrix form, the \e local interpolation on the interval t=[0..1] is
described as follows:
@verbatim
\verbatim
P(t) = 1/6 * [ t^3 t^2 t 1 ] * [ -1 3 -3 1 ] * [ P-1 ]
[ 3 -6 3 0 ] [ P0 ]
[ -3 0 3 0 ] [ P1 ]
[ 1 4 1 0 ] [ P2 ]
@endverbatim
\endverbatim
Where P-1 and P2 represent the neighbouring points or the extrapolated
end points. Simple reflection is used to automatically create the end
@ -47,12 +47,11 @@ Description
segments. In rare cases (sections with very high curvatures), the
resulting distribution may be sub-optimal.
A future implementation could also handle closed splines.
SeeAlso
CatmullRomSpline
ToDo
A future implementation could also handle closed splines.
SourceFiles
BSpline.C

View file

@ -1,25 +1,25 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
This file is part of OpenFOAM.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
foam-extend 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.
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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
@ -45,11 +45,11 @@ Foam::point Foam::CatmullRomSpline::position(const scalar mu) const
// endpoints
if (mu < SMALL)
{
return points()[0];
return points().first();
}
else if (mu > 1 - SMALL)
{
return points()[points().size()-1];
return points().last();
}
scalar lambda = mu;
@ -67,11 +67,11 @@ Foam::point Foam::CatmullRomSpline::position
// out-of-bounds
if (segment < 0)
{
return points()[0];
return points().first();
}
else if (segment > nSegments())
{
return points()[points().size()-1];
return points().last();
}
const point& p0 = points()[segment];

View file

@ -1,25 +1,25 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
This file is part of OpenFOAM.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
foam-extend 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.
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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::CatmullRomSpline
@ -31,14 +31,14 @@ Description
In this implementation, the end tangents are created automatically
by reflection.
In matrix form, the @e local interpolation on the interval t=[0..1] is
In matrix form, the \e local interpolation on the interval t=[0..1] is
described as follows:
@verbatim
\verbatim
P(t) = 1/2 * [ t^3 t^2 t 1 ] * [ -1 3 -3 1 ] * [ P-1 ]
[ 2 -5 4 -1 ] [ P0 ]
[ -1 0 1 0 ] [ P1 ]
[ 0 2 0 0 ] [ P2 ]
@endverbatim
\endverbatim
Where P-1 and P2 represent the neighbouring points or the extrapolated
end points. Simple reflection is used to automatically create the end
@ -48,13 +48,12 @@ Description
segments. In rare cases (sections with very high curvatures), the
resulting distribution may be sub-optimal.
A future implementation could also handle closed splines.
SeeAlso
http://www.algorithmist.net/catmullrom.html provides a nice
introduction
ToDo
A future implementation could also handle closed splines.
SourceFiles
CatmullRomSpline.C
@ -109,7 +108,7 @@ public:
// 0 <= lambda <= 1 on the given segment
point position(const label segment, const scalar lambda) const;
//- Return the length of the curve - not implemented
//- Return the length of the curve
scalar length() const;
};

View file

@ -1,30 +1,30 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
This file is part of OpenFOAM.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
foam-extend 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.
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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "arcEdge.H"
#include "mathematicalConstants.H"
#include "unitConversion.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -70,8 +70,7 @@ Foam::cylindricalCS Foam::arcEdge::calcAngle()
vector r3(p3_ - centre);
// find angles
angle_ = (acos((r3 & r1)/(mag(r3) * mag(r1))))
* 180.0/mathematicalConstant::pi;
angle_ = radToDeg(acos((r3 & r1)/(mag(r3) * mag(r1))));
// check if the vectors define an exterior or an interior arcEdge
if (((r1 ^ r2) & (r1 ^ r3)) < 0.0)
@ -158,7 +157,7 @@ Foam::point Foam::arcEdge::position(const scalar lambda) const
Foam::scalar Foam::arcEdge::length() const
{
return (angle_ * radius_) * mathematicalConstant::pi/180.0;
return degToRad(angle_*radius_);
}

View file

@ -1,25 +1,25 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
This file is part of OpenFOAM.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
foam-extend 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.
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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::arcEdge
@ -89,9 +89,8 @@ public:
arcEdge(const pointField& points, Istream&);
// Destructor
virtual ~arcEdge(){}
//- Destructor
virtual ~arcEdge(){}
// Member Functions

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