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; using namespace Foam;
#include "argList.H" #include "argList.H"
#include "objectRegistry.H"
#include "Time.H" #include "Time.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "emptyPolyPatch.H" #include "emptyPolyPatch.H"
@ -63,11 +62,16 @@ label maxNodei = 0;
SLPtrList<labelList> slCellLabels; SLPtrList<labelList> slCellLabels;
SLList<label> slCellMap; SLList<label> slCellMap;
SLList<label> slCellType;
label maxCelli = 0; label maxCelli = 0;
PtrList<SLList<label> > slPatchCells; PtrList<SLList<label> > slPatchCells;
PtrList<SLList<label> > slPatchCellFaces; PtrList<SLList<label> > slPatchCellFaces;
// Cell types
Map<word> cellTypes;
label currentTypei = -1;
// Dummy yywrap to keep yylex happy at compile time. // Dummy yywrap to keep yylex happy at compile time.
// It is called by yylex but is not used as the mechanism to change file. // 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] alpha [_A-Za-z]
digit [0-9] digit [0-9]
dec_digit [0-9]
octal_digit [0-7]
hex_digit [0-9a-fA-F]
identifier {alpha}({alpha}|{digit})* identifier {alpha}({alpha}|{digit})*
integer {dec_digit}+ integer {digit}+
label [1-9]{dec_digit}* label [1-9]{digit}*
exponent_part [eE][-+]?{digit}+ exponent_part [eE][-+]?{digit}+
fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?)) fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
double (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part})) floatNum (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
x {double} x {floatNum}
y {double} y {floatNum}
z {double} z {floatNum}
value {double} value {floatNum}
node ^{space}"N"{cspace} node ^{space}"N"{cspace}
element ^{space}"EN"{cspace} element ^{space}"EN"{cspace}
bface ^{space}"SFE"{cspace} bface ^{space}"SFE"{cspace}
elementTypeName ^{space}"ET"{cspace}
elementType ^{space}"TYPE"{cspace}
%% %%
@ -163,6 +166,7 @@ bface ^{space}"SFE"{cspace}
slCellMap.append(celli); slCellMap.append(celli);
slCellLabels.append(new labelList(labels)); 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. ------ Ignore remaining space and \n s. Any other characters are errors.
\* ------------------------------------------------------------------------- */ \* ------------------------------------------------------------------------- */
@ -234,6 +269,29 @@ bface ^{space}"SFE"{cspace}
#include <fstream> #include <fstream>
using std::ifstream; 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[]) int main(int argc, char *argv[])
{ {
argList::noParallel(); argList::noParallel();
@ -264,20 +322,15 @@ int main(int argc, char *argv[])
} }
yyFlexLexer lexer(&ansysStream); yyFlexLexer lexer(&ansysStream);
while(lexer.yylex() != 0) while (lexer.yylex() != 0)
{} {}
Info << "Creating points" << endl; Info<< "Creating points" << endl;
pointField points(slPoints.size()); pointField points(slPoints.size());
label i=0; label i = 0;
for forAllConstIter(SLList<point>, slPoints, pointIter)
(
SLList<point>::iterator pointIter = slPoints.begin();
pointIter != slPoints.end();
++pointIter
)
{ {
// Scale points for the given scale factor // Scale points for the given scale factor
points[i++] = scaleFactor * pointIter(); points[i++] = scaleFactor * pointIter();
@ -286,28 +339,18 @@ int main(int argc, char *argv[])
labelList pointMap(maxNodei+1); labelList pointMap(maxNodei+1);
i=0; i = 0;
for forAllConstIter(SLList<label>, slPointMap, pointMapIter)
(
SLList<label>::iterator pointMapIter = slPointMap.begin();
pointMapIter != slPointMap.end();
++pointMapIter
)
{ {
pointMap[pointMapIter()] = i++; pointMap[pointMapIter()] = i++;
} }
Info << "Creating cells" << endl; Info<< "Creating cells" << endl;
labelList cellMap(maxCelli+1); labelList cellMap(maxCelli+1);
i=0; i = 0;
for forAllConstIter(SLList<label>, slCellMap, cellMapIter)
(
SLList<label>::iterator cellMapIter = slCellMap.begin();
cellMapIter != slCellMap.end();
++cellMapIter
)
{ {
cellMap[cellMapIter()] = i++; cellMap[cellMapIter()] = i++;
} }
@ -326,12 +369,7 @@ int main(int argc, char *argv[])
cellShapeList cellShapes(slCellLabels.size()); cellShapeList cellShapes(slCellLabels.size());
label nCells = 0; label nCells = 0;
for forAllConstIter(SLPtrList<labelList>, slCellLabels, cellIter)
(
SLPtrList<labelList>::iterator cellIter = slCellLabels.begin();
cellIter != slCellLabels.end();
++cellIter
)
{ {
if // Tetrahedron 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 // Warning: tet face order has changed between version 1.9.6 and 2.0
// //
label faceIndex[7][6] = 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}, // 1
{-1, -1, -1, -1, -1, -1}, // 2 {-1, -1, -1, -1, -1, -1}, // 2
{-1, -1, -1, -1, -1, -1}, // 3 {-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 { 0, 4, 3, -1, 2, 1}, // prism
{ 4, 2, 1, 3, 0, 5}, // hex { 4, 2, 1, 3, 0, 5}, // hex
}; };
Info << "Creating boundary patches" << endl; Info<< "Creating boundary patches" << endl;
faceListList boundary(slPatchCells.size()); faceListList boundary(slPatchCells.size());
wordList patchNames(slPatchCells.size()); wordList patchNames(slPatchCells.size());
@ -429,12 +495,14 @@ int main(int argc, char *argv[])
++cellIter, ++faceIter ++cellIter, ++faceIter
) )
{ {
const cellShape& shape = cellShapes[cellMap[cellIter()]];
patchFaces.append patchFaces.append
( (
cellShapes[cellMap[cellIter()] ].faces() shape.faces()
[ [
faceIndex faceIndex
[cellShapes[cellMap[cellIter()] ].nFaces()] [shape.nFaces()]
[faceIter()-1] [faceIter()-1]
] ]
); );
@ -442,34 +510,85 @@ int main(int argc, char *argv[])
boundary[patchI] = patchFaces; boundary[patchI] = patchFaces;
patchNames[patchI] = word("patch") + name(patchI + 1); 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; << ": " << 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 " << "Ansys file format does not provide information about the type of "
<< "the patch (eg. wall, symmetry plane, cyclic etc)." << endl << "the patch (eg. wall, symmetry plane, cyclic etc)." << endl
<< "All the patches have been created " << "All the patches have been created "
<< "as type patch. Please reset after mesh conversion as necessary." << "as type patch. Please reset after mesh conversion as necessary."
<< endl; << endl;
wordList patchTypes(boundary.size(), polyPatch::typeName); PtrList<dictionary> patchDicts;
word defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName;
wordList patchPhysicalTypes(boundary.size());
preservePatchTypes preservePatchTypes
( (
runTime, runTime,
runTime.constant(), runTime.constant(),
polyMesh::defaultRegion, polyMesh::meshSubDir,
patchNames, patchNames,
patchTypes, patchDicts,
defaultFacesName, defaultFacesName,
defaultFacesType, defaultFacesType
patchPhysicalTypes
); );
// 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 polyMesh pShapeMesh
( (
IOobject IOobject
@ -480,18 +599,101 @@ int main(int argc, char *argv[])
), ),
xferMove(points), xferMove(points),
cellShapes, cellShapes,
boundary, patchFaces,
patchNames, patchNames,
patchTypes, patchDicts,
defaultFacesName, defaultFacesName,
defaultFacesType, defaultFacesType
patchPhysicalTypes
); );
// 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(); pShapeMesh.write();
Info<< nl << "end" << endl; Info<< nl << "end" << endl;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -230,17 +230,28 @@ void sammMesh::readBoundary()
patchPhysicalTypes_.setSize(patchTypes_.size()); patchPhysicalTypes_.setSize(patchTypes_.size());
PtrList<dictionary> patchDicts;
preservePatchTypes preservePatchTypes
( (
runTime_, runTime_,
runTime_.constant(), runTime_.constant(),
polyMesh::defaultRegion, polyMesh::meshSubDir,
patchNames_, patchNames_,
patchTypes_, patchDicts,
defaultFacesName_, defaultFacesName_,
defaultFacesType_, defaultFacesType_
patchPhysicalTypes_
); );
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()); patchPhysicalTypes_.setSize(patchTypes_.size());
PtrList<dictionary> patchDicts;
preservePatchTypes preservePatchTypes
( (
runTime_, runTime_,
runTime_.constant(), runTime_.constant(),
polyMesh::defaultRegion, polyMesh::meshSubDir,
patchNames_, patchNames_,
patchTypes_, patchDicts,
defaultFacesName_, defaultFacesName_,
defaultFacesType_, defaultFacesType_
patchPhysicalTypes_
); );
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 blockMeshApp.C
EXE = $(FOAM_APPBIN)/blockMesh EXE = $(FOAM_APPBIN)/blockMesh

View file

@ -1,11 +1,9 @@
EXE_INC = \ EXE_INC = \
-I$(curvedEdges) \ -I$(LIB_SRC)/mesh/blockMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude -I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lblockMesh \
-lmeshTools \ -lmeshTools \
-lODE \
-lfiniteVolume \
-ldynamicMesh -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 | \\ / O peration |
\\ / A nd | For copyright notice see file Copyright \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License 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 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 under the terms of the GNU General Public License as published by
Free Software Foundation, either version 3 of the License, or (at your the Free Software Foundation, either version 3 of the License, or
option) any later version. (at your option) any later version.
foam-extend is distributed in the hope that it will be useful, but OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
WITHOUT ANY WARRANTY; without even the implied warranty of ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
General Public License for more details. for more details.
You should have received a copy of the GNU General Public 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/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application Application
blockMesh blockMesh
@ -28,25 +28,24 @@ Description
A multi-block mesh generator. A multi-block mesh generator.
Uses the block mesh description found in Uses the block mesh description found in
@a constant/polyMesh/blockMeshDict \a constant/polyMesh/blockMeshDict
(or @a constant/\<region\>/polyMesh/blockMeshDict). (or \a constant/\<region\>/polyMesh/blockMeshDict).
Usage Usage
- blockMesh [OPTION] - blockMesh [OPTION]
@param -blockTopology \n \param -blockTopology \n
Write the topology as a set of edges in OBJ format. Write the topology as a set of edges in OBJ format.
@param -region \<name\> \n \param -region \<name\> \n
Specify an alternative mesh region. Specify an alternative mesh region.
@param -dict \<dictionary\> \n \param -dict \<filename\> \n
Specify an alternative dictionary for the block mesh description. Specify alternative dictionary for the block mesh description.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "objectRegistry.H"
#include "Time.H" #include "Time.H"
#include "IOdictionary.H" #include "IOdictionary.H"
#include "IOPtrList.H" #include "IOPtrList.H"
@ -150,8 +149,10 @@ int main(int argc, char *argv[])
Info<< nl << "Creating block mesh from\n " Info<< nl << "Creating block mesh from\n "
<< meshDictIoPtr->objectPath() << nl << endl; << meshDictIoPtr->objectPath() << nl << endl;
blockMesh::verbose(true);
IOdictionary meshDict(meshDictIoPtr()); IOdictionary meshDict(meshDictIoPtr());
blockMesh blocks(meshDict); blockMesh blocks(meshDict, regionName);
if (args.optionFound("blockTopology")) 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 defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName; word defaultFacesType = emptyPolyPatch::typeName;
wordList patchPhysicalTypes = blocks.patchPhysicalTypes();
preservePatchTypes
(
runTime,
runTime.constant(),
polyMeshDir,
patchNames,
patchTypes,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
);
polyMesh mesh polyMesh mesh
( (
IOobject IOobject
@ -225,14 +209,13 @@ int main(int argc, char *argv[])
runTime.constant(), runTime.constant(),
runTime runTime
), ),
xferCopy(blocks.points()), xferCopy(blocks.points()), // could we re-use space?
blocks.cells(), blocks.cells(),
blocks.patches(), blocks.patches(),
patchNames, blocks.patchNames(),
patchTypes, blocks.patchDicts(),
defaultFacesName, defaultFacesName,
defaultFacesType, defaultFacesType
patchPhysicalTypes
); );
@ -244,157 +227,11 @@ int main(int argc, char *argv[])
meshDict.lookup("mergePatchPairs") meshDict.lookup("mergePatchPairs")
); );
if (mergePatchPairs.size() > 0) # include "mergePatchPairs.H"
{
// 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();
}
} }
else 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(); label zoneI = iter();
cz[zoneI]= new cellZone cz[zoneI] = new cellZone
( (
iter.key(), iter.key(),
zoneCells[zoneI].shrink(), zoneCells[zoneI].shrink(),
@ -489,9 +326,9 @@ int main(int argc, char *argv[])
} }
// Set the precision of the points data to 10 // 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(); mesh.removeFiles();
if (!mesh.write()) if (!mesh.write())
{ {
@ -500,7 +337,39 @@ int main(int argc, char *argv[])
<< exit(FatalError); << 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; 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 ODE
wmake libso POD wmake libso POD
wmake libso randomProcesses wmake libso randomProcesses
mesh/Allwmake
thermophysicalModels/Allwmake thermophysicalModels/Allwmake
transportModels/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; Info<< "Added " << nMissingFaces << " unmatched faces" << endl;
// Add missing faces to last patch ('Default_Empty' etc.)
if (nMissingFaces > 0) if (nMissingFaces > 0)
{ {
patchSizes_[patchSizes_.size() - 1] = nMissingFaces; patchSizes_.last() = nMissingFaces;
}
else
{
patchStarts_.setSize(patchStarts_.size() - 1);
} }
// reset the size of the face list // reset the size of the face list
meshFaces_.setSize(nCreatedFaces); meshFaces_.setSize(nCreatedFaces);
@ -412,6 +410,8 @@ Foam::meshReader::polyBoundaryPatches(const polyMesh& mesh)
List<polyPatch*> p(nPatches); List<polyPatch*> p(nPatches);
// All patch dictionaries
PtrList<dictionary> patchDicts(patchNames_.size());
// Default boundary patch types // Default boundary patch types
word defaultFacesType(emptyPolyPatch::typeName); word defaultFacesType(emptyPolyPatch::typeName);
@ -422,20 +422,37 @@ Foam::meshReader::polyBoundaryPatches(const polyMesh& mesh)
mesh.instance(), mesh.instance(),
mesh.meshDir(), mesh.meshDir(),
patchNames_, patchNames_,
patchTypes_, patchDicts,
"defaultFaces", "defaultFaces",
defaultFacesType, defaultFacesType
patchPhysicalTypes_
); );
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) forAll(patchStarts_, patchI)
{ {
p[patchI] = polyPatch::New p[patchI] = polyPatch::New
( (
patchTypes_[patchI],
patchNames_[patchI], patchNames_[patchI],
patchSizes_[patchI], patchDicts[patchI],
patchStarts_[patchI],
patchI, patchI,
mesh.boundaryMesh() mesh.boundaryMesh()
).ptr(); ).ptr();

View file

@ -167,6 +167,18 @@ public:
// This can be used (with caution) when interfacing with C code. // This can be used (with caution) when interfacing with C code.
inline T* data(); 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 // 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> template<class T>
inline const T* Foam::UList<T>::cdata() const 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 //- Execute the specified command
int system(const string& 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 } // End namespace Foam

View file

@ -699,6 +699,49 @@ bool Foam::polyBoundaryMesh::writeObject
return regIOobject::writeObject(fmt, ver, IOstream::UNCOMPRESSED); 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 * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //

View file

@ -197,6 +197,18 @@ public:
) const; ) 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 // Ostream operator
friend Ostream& operator<<(Ostream&, const polyBoundaryMesh&); friend Ostream& operator<<(Ostream&, const polyBoundaryMesh&);

View file

@ -30,8 +30,10 @@ License
#include "emptyPolyPatch.H" #include "emptyPolyPatch.H"
#include "globalMeshData.H" #include "globalMeshData.H"
#include "processorPolyPatch.H" #include "processorPolyPatch.H"
#include "meshObjectBase.H" #include "indexedOctree.H"
#include "demandDrivenData.H" #include "treeDataCell.H"
#include "MeshObject.H"
#include "pointMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * 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 namespace Foam
{ {
// Forward declaration of classes
class globalMeshData; class globalMeshData;
class mapPolyMesh; class mapPolyMesh;
@ -202,6 +203,17 @@ private:
const label patchID const label patchID
) const; ) const;
void setTopology
(
const cellShapeList& cellsAsShapes,
const faceListList& boundaryFaces,
const wordList& boundaryPatchNames,
labelList& patchSizes,
labelList& patchStarts,
label& defaultPatchStart,
label& nFaces,
cellList& cells
);
public: public:
@ -264,6 +276,20 @@ public:
const bool syncPar = true 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 // Destructor
@ -521,6 +547,14 @@ public:
//- Remove all files from mesh instance() //- Remove all files from mesh instance()
void removeFiles() const; 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 Foam::polyMesh::polyMesh
( (
const IOobject& io, const IOobject& io,
@ -278,278 +564,27 @@ Foam::polyMesh::polyMesh
// Remove all of the old mesh files if they exist // Remove all of the old mesh files if they exist
removeFiles(instance()); removeFiles(instance());
// Calculate the faces of all cells // Calculate faces and cells
// Initialise maximum possible numer of mesh faces to 0 labelList patchSizes;
label maxFaces = 0; labelList patchStarts;
label defaultPatchStart;
// Set up a list of face shapes for each cell label nFaces;
faceListList cellsFaceShapes(cellsAsShapes.size()); cellList cells;
cellList cells(cellsAsShapes.size()); setTopology
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" cellsAsShapes,
"(\n" boundaryFaces,
" const IOobject&,\n" boundaryPatchNames,
" const Xfer<pointField>&,\n" patchSizes,
" const cellShapeList& cellsAsShapes,\n" patchStarts,
" const faceListList& boundaryFaces,\n" defaultPatchStart,
" const wordList& boundaryPatchTypes,\n" nFaces,
" const wordList& boundaryPatchNames,\n" cells
" 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);
// Warning: Patches can only be added once the face list is // Warning: Patches can only be added once the face list is
// completed, as they hold a subList of the face list // completed, as they hold a subList of the face list
forAll (boundaryFaces, patchI) forAll(boundaryFaces, patchI)
{ {
// add the patch to the list // add the patch to the list
boundary_.set boundary_.set
@ -579,12 +614,53 @@ Foam::polyMesh::polyMesh
label nAllPatches = boundaryFaces.size(); 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...)") WarningIn("polyMesh::polyMesh(... construct from shapes...)")
<< "Found " << nFaces - defaultPatchStart << "Found " << nDefaultFaces
<< " undefined faces in mesh; adding to default patch." << endl; << " 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 boundary_.set
( (
nAllPatches, nAllPatches,
@ -601,6 +677,284 @@ Foam::polyMesh::polyMesh
nAllPatches++; 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
(
patchI,
polyPatch::New
(
boundaryPatchNames[patchI],
patchDict,
patchI,
boundary_
)
);
}
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 // Reset the size of the boundary
boundary_.setSize(nAllPatches); boundary_.setSize(nAllPatches);

View file

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

View file

@ -37,6 +37,7 @@ SourceFiles
#include "fileName.H" #include "fileName.H"
#include "wordList.H" #include "wordList.H"
#include "dictionary.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -52,10 +53,9 @@ void preservePatchTypes
const word& meshInstance, const word& meshInstance,
const fileName& meshDir, const fileName& meshDir,
const wordList& patchNames, const wordList& patchNames,
wordList& patchTypes, PtrList<dictionary>& patchDicts,
const word& defaultFacesName, const word& defaultFacesName,
word& defaultFacesType, word& defaultFacesType
wordList& patchPhysicalTypes
); );
} // End namespace Foam } // 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 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H" #include "autoLayerDriver.H"
#include "blockMesh.H" #include "syncTools.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * 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; forAll(edges, edgeI)
// optional 'convertToMeters' (or 'scale'?)
if (!dict.readIfPresent("convertToMeters", scaleFactor))
{ {
dict.readIfPresent("scale", scaleFactor); if (isMasterEdge.get(meshEdges[edgeI]) == 1)
}
Info<< nl << "Creating points with scale " << scaleFactor << endl;
pointField points(nPoints_);
forAll(blocks, blockLabel)
{ {
const pointField& blockPoints = blocks[blockLabel].points(); const edge& e = edges[edgeI];
//scalar eWeight = edgeWeights[edgeI];
scalar eWeight = 1.0;
label v0 = e[0];
label v1 = e[1];
forAll(blockPoints, blockPointLabel) average[v0] += eWeight*data[v1];
{ average[v1] += eWeight*data[v0];
points
[
mergeList_
[
blockPointLabel
+ blockOffsets_[blockLabel]
]
] = scaleFactor * blockPoints[blockPointLabel];
} }
} }
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 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::curvedEdgeList
Description
A PtrList of curvedEdges
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef curvedEdgeList_H #include "pointData.H"
#define curvedEdgeList_H
#include "curvedEdge.H" // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Foam::Ostream& Foam::operator<<(Ostream& os, const pointData& wDist)
namespace Foam
{ {
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();
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Foam::Istream& Foam::operator>>(Istream& is, pointData& wDist)
{
typedef PtrList<curvedEdge> curvedEdgeList; return is >> wDist.origin_ >> wDist.distSqr_ >> wDist.s_ >> wDist.v_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* // // ************************************************************************* //

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 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H" #include "snapParameters.H"
#include "blockMesh.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::labelList Foam::blockMesh::createBlockOffsets() // Construct from dictionary
{ Foam::snapParameters::snapParameters(const dictionary& dict, const label dummy)
Info<< nl << "Creating block offsets" << endl; :
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(); // Construct from dictionary
nCells_ = blocks[0].cells().size(); 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; // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
for (blockLabel=1; blockLabel<blocks.size(); blockLabel++)
{
nPoints_ += blocks[blockLabel].points().size();
nCells_ += blocks[blockLabel].cells().size();
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 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
InClass
Foam::blockList
Description
SourceFiles
blockList.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef blockList_H #include "trackedParticle.H"
#define blockList_H #include "Cloud.H"
#include "block.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
typedef PtrList<block> blockList; defineParticleTypeNameAndDebug(trackedParticle, 0);
defineTemplateTypeNameAndDebug(Cloud<trackedParticle>, 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // 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 | \\ / O peration |
\\ / A nd | For copyright notice see file Copyright \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License 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 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 under the terms of the GNU General Public License as published by
Free Software Foundation, either version 3 of the License, or (at your the Free Software Foundation, either version 3 of the License, or
option) any later version. (at your option) any later version.
foam-extend is distributed in the hope that it will be useful, but OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
WITHOUT ANY WARRANTY; without even the implied warranty of ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
General Public License for more details. for more details.
You should have received a copy of the GNU General Public 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/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -27,13 +27,38 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * 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 pointField& blockPoints = topology().points();
const cellList& blockCells = topology().cells(); const cellList& blockCells = topology().cells();
@ -45,6 +70,7 @@ Foam::labelList Foam::blockMesh::createMergeList()
const labelList& faceNeighbourBlocks = topology().faceNeighbour(); const labelList& faceNeighbourBlocks = topology().faceNeighbour();
forAll(blockFaces, blockFaceLabel) forAll(blockFaces, blockFaceLabel)
{ {
label blockPlabel = faceOwnerBlocks[blockFaceLabel]; label blockPlabel = faceOwnerBlocks[blockFaceLabel];
@ -73,10 +99,10 @@ Foam::labelList Foam::blockMesh::createMergeList()
if (!foundFace) if (!foundFace)
{ {
FatalErrorIn("blockMesh::createMergeList()") FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Cannot find merge face for block " << blockPlabel << "Cannot find merge face for block " << blockPlabel
<< exit(FatalError); << exit(FatalError);
}; }
const labelListList& blockPfaceFaces = const labelListList& blockPfaceFaces =
blocks[blockPlabel].boundaryPatches()[blockPfaceLabel]; blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
@ -92,7 +118,7 @@ Foam::labelList Foam::blockMesh::createMergeList()
// the size of the block. // the size of the block.
boundBox bb(blockCells[blockPlabel].points(blockFaces, blockPoints)); 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 // This is an N^2 algorithm
@ -129,17 +155,17 @@ Foam::labelList Foam::blockMesh::createMergeList()
label minPP2 = min(PpointLabel, PpointLabel2); 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; = minPP2;
} }
else else
@ -182,22 +208,23 @@ Foam::labelList Foam::blockMesh::createMergeList()
if (!foundFace) if (!foundFace)
{ {
FatalErrorIn("blockMesh::createMergeList()") FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Cannot find merge face for block " << blockNlabel << "Cannot find merge face for block " << blockNlabel
<< exit(FatalError); << exit(FatalError);
}; }
const labelListList& blockNfaceFaces = const labelListList& blockNfaceFaces =
blocks[blockNlabel].boundaryPatches()[blockNfaceLabel]; blocks[blockNlabel].boundaryPatches()[blockNfaceLabel];
if (blockPfaceFaces.size() != blockNfaceFaces.size()) if (blockPfaceFaces.size() != blockNfaceFaces.size())
{ {
FatalErrorIn("blockMesh::createMergeList()") FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Inconsistent number of faces between block pair " << "Inconsistent number of faces between block pair "
<< blockPlabel << " and " << blockNlabel << blockPlabel << " and " << blockNlabel
<< exit(FatalError); << exit(FatalError);
} }
// N-squared point search over all points of all faces of // N-squared point search over all points of all faces of
// master block over all point of all faces of slave block // master block over all point of all faces of slave block
forAll(blockPfaceFaces, blockPfaceFaceLabel) forAll(blockPfaceFaces, blockPfaceFaceLabel)
@ -211,8 +238,6 @@ Foam::labelList Foam::blockMesh::createMergeList()
forAll(blockPfaceFacePoints, blockPfaceFacePointLabel) forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
{ {
bool found = false;
forAll(blockNfaceFaces, blockNfaceFaceLabel) forAll(blockNfaceFaces, blockNfaceFaceLabel)
{ {
const labelList& blockNfaceFacePoints const labelList& blockNfaceFacePoints
@ -232,7 +257,6 @@ Foam::labelList Foam::blockMesh::createMergeList()
) )
{ {
// Found a new pair // Found a new pair
found = true;
cp[blockPfaceFacePointLabel] = cp[blockPfaceFacePointLabel] =
blockNfaceFacePoints[blockNfaceFacePointLabel]; blockNfaceFacePoints[blockNfaceFacePointLabel];
@ -247,17 +271,17 @@ Foam::labelList Foam::blockMesh::createMergeList()
label minPN = min(PpointLabel, NpointLabel); 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; = minPN;
} }
} }
@ -267,7 +291,7 @@ Foam::labelList Foam::blockMesh::createMergeList()
{ {
if (cp[blockPfaceFacePointLabel] == -1) if (cp[blockPfaceFacePointLabel] == -1)
{ {
FatalErrorIn("blockMesh::createMergeList()") FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Inconsistent point locations between block pair " << "Inconsistent point locations between block pair "
<< blockPlabel << " and " << blockNlabel << nl << blockPlabel << " and " << blockNlabel << nl
<< " probably due to inconsistent grading." << " 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; label blockNfaceLabel;
for for
( (
@ -339,6 +365,9 @@ Foam::labelList Foam::blockMesh::createMergeList()
} }
} }
// FIXME? - there seems to be some logic missing here
const labelListList& blockPfaceFaces = const labelListList& blockPfaceFaces =
blocks[blockPlabel].boundaryPatches()[blockPfaceLabel]; blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
@ -361,34 +390,41 @@ Foam::labelList Foam::blockMesh::createMergeList()
if if
( (
MergeList[PpointLabel] mergeList_[PpointLabel]
!= MergeList[NpointLabel] != mergeList_[NpointLabel]
) )
{ {
changedPointMerge = true; changedPointMerge = true;
MergeList[PpointLabel] mergeList_[PpointLabel]
= MergeList[NpointLabel] = mergeList_[NpointLabel]
= min = min
( (
MergeList[PpointLabel], mergeList_[PpointLabel],
MergeList[NpointLabel] mergeList_[NpointLabel]
); );
} }
} }
} }
} }
Info << "." << flush; if (verboseOutput)
{
Info<< "." << flush;
}
if (nPasses > 100) if (nPasses > 100)
{ {
FatalErrorIn("blockMesh::createMergeList()") FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Point merging failed after max number of passes." << "Point merging failed after max number of passes."
<< abort(FatalError); << abort(FatalError);
} }
} }
while (changedPointMerge); while (changedPointMerge);
Info << endl;
if (verboseOutput)
{
Info<< endl;
}
forAll(blockInternalFaces, blockFaceLabel) forAll(blockInternalFaces, blockFaceLabel)
{ {
@ -423,10 +459,10 @@ Foam::labelList Foam::blockMesh::createMergeList()
if (!foundFace) if (!foundFace)
{ {
FatalErrorIn("blockMesh::createMergeList()") FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Cannot find merge face for block " << blockPlabel << "Cannot find merge face for block " << blockPlabel
<< exit(FatalError); << exit(FatalError);
}; }
foundFace = false; foundFace = false;
label blockNfaceLabel; label blockNfaceLabel;
@ -450,10 +486,10 @@ Foam::labelList Foam::blockMesh::createMergeList()
if (!foundFace) if (!foundFace)
{ {
FatalErrorIn("blockMesh::createMergeList()") FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Cannot find merge face for block " << blockNlabel << "Cannot find merge face for block " << blockNlabel
<< exit(FatalError); << exit(FatalError);
}; }
const labelListList& blockPfaceFaces = const labelListList& blockPfaceFaces =
blocks[blockPlabel].boundaryPatches()[blockPfaceLabel]; blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
@ -472,9 +508,9 @@ Foam::labelList Foam::blockMesh::createMergeList()
blockPfaceFacePoints[blockPfaceFacePointLabel] blockPfaceFacePoints[blockPfaceFacePointLabel]
+ blockOffsets_[blockPlabel]; + blockOffsets_[blockPlabel];
if (MergeList[PpointLabel] == -1) if (mergeList_[PpointLabel] == -1)
{ {
FatalErrorIn("blockMesh::createMergeList()") FatalErrorIn("blockMesh::calcMergeInfo()")
<< "Unable to merge point " << "Unable to merge point "
<< blockPfaceFacePointLabel << blockPfaceFacePointLabel
<< ' ' << blockPpoints[blockPfaceFacePointLabel] << ' ' << blockPpoints[blockPfaceFacePointLabel]
@ -498,9 +534,9 @@ Foam::labelList Foam::blockMesh::createMergeList()
blockNfaceFacePoints[blockNfaceFacePointLabel] blockNfaceFacePoints[blockNfaceFacePointLabel]
+ blockOffsets_[blockNlabel]; + blockOffsets_[blockNlabel];
if (MergeList[NpointLabel] == -1) if (mergeList_[NpointLabel] == -1)
{ {
FatalErrorIn("blockMesh::createMergeList()") FatalErrorIn("blockMesh::calcMergeInfo()")
<< "unable to merge point " << "unable to merge point "
<< blockNfaceFacePointLabel << blockNfaceFacePointLabel
<< ' ' << blockNpoints[blockNfaceFacePointLabel] << ' ' << blockNpoints[blockNfaceFacePointLabel]
@ -519,33 +555,31 @@ Foam::labelList Foam::blockMesh::createMergeList()
// given old point label // given old point label
label newPointLabel = 0; 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); << "ouch" << exit(FatalError);
} }
if if
( (
(MergeList[pointLabel] == -1) mergeList_[pointLabel] == -1
|| MergeList[pointLabel] == pointLabel || mergeList_[pointLabel] == pointLabel
) )
{ {
MergeList[pointLabel] = newPointLabel; mergeList_[pointLabel] = newPointLabel;
newPointLabel++; newPointLabel++;
} }
else else
{ {
MergeList[pointLabel] = MergeList[MergeList[pointLabel]]; mergeList_[pointLabel] = mergeList_[mergeList_[pointLabel]];
} }
} }
nPoints_ = newPointLabel; 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 | \\ / O peration |
\\ / A nd | For copyright notice see file Copyright \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License 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 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 under the terms of the GNU General Public License as published by
Free Software Foundation, either version 3 of the License, or (at your the Free Software Foundation, either version 3 of the License, or
option) any later version. (at your option) any later version.
foam-extend is distributed in the hope that it will be useful, but OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
WITHOUT ANY WARRANTY; without even the implied warranty of ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
General Public License for more details. for more details.
You should have received a copy of the GNU General Public 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/>. 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 // endpoints
if (mu < SMALL) if (mu < SMALL)
{ {
return points_[0]; return points().first();
} }
else if (mu > 1 - SMALL) else if (mu > 1 - SMALL)
{ {
return points_[points_.size()-1]; return points().last();
} }
scalar lambda = mu; scalar lambda = mu;
@ -67,11 +67,11 @@ Foam::point Foam::BSpline::position
// out-of-bounds // out-of-bounds
if (segment < 0) if (segment < 0)
{ {
return points_[0]; return points().first();
} }
else if (segment > nSegments()) else if (segment > nSegments())
{ {
return points_[points_.size()-1]; return points().last();
} }
const point& p0 = points()[segment]; 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 | \\ / O peration |
\\ / A nd | For copyright notice see file Copyright \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License 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 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 under the terms of the GNU General Public License as published by
Free Software Foundation, either version 3 of the License, or (at your the Free Software Foundation, either version 3 of the License, or
option) any later version. (at your option) any later version.
foam-extend is distributed in the hope that it will be useful, but OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
WITHOUT ANY WARRANTY; without even the implied warranty of ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
General Public License for more details. for more details.
You should have received a copy of the GNU General Public 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/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class Class
Foam::BSpline Foam::BSpline
@ -30,14 +30,14 @@ Description
In this implementation, the end tangents are created automatically In this implementation, the end tangents are created automatically
by reflection. 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: described as follows:
@verbatim \verbatim
P(t) = 1/6 * [ t^3 t^2 t 1 ] * [ -1 3 -3 1 ] * [ P-1 ] P(t) = 1/6 * [ t^3 t^2 t 1 ] * [ -1 3 -3 1 ] * [ P-1 ]
[ 3 -6 3 0 ] [ P0 ] [ 3 -6 3 0 ] [ P0 ]
[ -3 0 3 0 ] [ P1 ] [ -3 0 3 0 ] [ P1 ]
[ 1 4 1 0 ] [ P2 ] [ 1 4 1 0 ] [ P2 ]
@endverbatim \endverbatim
Where P-1 and P2 represent the neighbouring points or the extrapolated Where P-1 and P2 represent the neighbouring points or the extrapolated
end points. Simple reflection is used to automatically create the end 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 segments. In rare cases (sections with very high curvatures), the
resulting distribution may be sub-optimal. resulting distribution may be sub-optimal.
A future implementation could also handle closed splines.
SeeAlso SeeAlso
CatmullRomSpline CatmullRomSpline
ToDo
A future implementation could also handle closed splines.
SourceFiles SourceFiles
BSpline.C 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 | \\ / O peration |
\\ / A nd | For copyright notice see file Copyright \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License 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 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 under the terms of the GNU General Public License as published by
Free Software Foundation, either version 3 of the License, or (at your the Free Software Foundation, either version 3 of the License, or
option) any later version. (at your option) any later version.
foam-extend is distributed in the hope that it will be useful, but OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
WITHOUT ANY WARRANTY; without even the implied warranty of ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
General Public License for more details. for more details.
You should have received a copy of the GNU General Public 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/>. 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 // endpoints
if (mu < SMALL) if (mu < SMALL)
{ {
return points()[0]; return points().first();
} }
else if (mu > 1 - SMALL) else if (mu > 1 - SMALL)
{ {
return points()[points().size()-1]; return points().last();
} }
scalar lambda = mu; scalar lambda = mu;
@ -67,11 +67,11 @@ Foam::point Foam::CatmullRomSpline::position
// out-of-bounds // out-of-bounds
if (segment < 0) if (segment < 0)
{ {
return points()[0]; return points().first();
} }
else if (segment > nSegments()) else if (segment > nSegments())
{ {
return points()[points().size()-1]; return points().last();
} }
const point& p0 = points()[segment]; 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 | \\ / O peration |
\\ / A nd | For copyright notice see file Copyright \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License 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 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 under the terms of the GNU General Public License as published by
Free Software Foundation, either version 3 of the License, or (at your the Free Software Foundation, either version 3 of the License, or
option) any later version. (at your option) any later version.
foam-extend is distributed in the hope that it will be useful, but OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
WITHOUT ANY WARRANTY; without even the implied warranty of ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
General Public License for more details. for more details.
You should have received a copy of the GNU General Public 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/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class Class
Foam::CatmullRomSpline Foam::CatmullRomSpline
@ -31,14 +31,14 @@ Description
In this implementation, the end tangents are created automatically In this implementation, the end tangents are created automatically
by reflection. 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: described as follows:
@verbatim \verbatim
P(t) = 1/2 * [ t^3 t^2 t 1 ] * [ -1 3 -3 1 ] * [ P-1 ] P(t) = 1/2 * [ t^3 t^2 t 1 ] * [ -1 3 -3 1 ] * [ P-1 ]
[ 2 -5 4 -1 ] [ P0 ] [ 2 -5 4 -1 ] [ P0 ]
[ -1 0 1 0 ] [ P1 ] [ -1 0 1 0 ] [ P1 ]
[ 0 2 0 0 ] [ P2 ] [ 0 2 0 0 ] [ P2 ]
@endverbatim \endverbatim
Where P-1 and P2 represent the neighbouring points or the extrapolated Where P-1 and P2 represent the neighbouring points or the extrapolated
end points. Simple reflection is used to automatically create the end 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 segments. In rare cases (sections with very high curvatures), the
resulting distribution may be sub-optimal. resulting distribution may be sub-optimal.
A future implementation could also handle closed splines.
SeeAlso SeeAlso
http://www.algorithmist.net/catmullrom.html provides a nice http://www.algorithmist.net/catmullrom.html provides a nice
introduction introduction
ToDo
A future implementation could also handle closed splines.
SourceFiles SourceFiles
CatmullRomSpline.C CatmullRomSpline.C
@ -109,7 +108,7 @@ public:
// 0 <= lambda <= 1 on the given segment // 0 <= lambda <= 1 on the given segment
point position(const label segment, const scalar lambda) const; 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; 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 | \\ / O peration |
\\ / A nd | For copyright notice see file Copyright \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License 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 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 under the terms of the GNU General Public License as published by
Free Software Foundation, either version 3 of the License, or (at your the Free Software Foundation, either version 3 of the License, or
option) any later version. (at your option) any later version.
foam-extend is distributed in the hope that it will be useful, but OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
WITHOUT ANY WARRANTY; without even the implied warranty of ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
General Public License for more details. for more details.
You should have received a copy of the GNU General Public 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/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "arcEdge.H" #include "arcEdge.H"
#include "mathematicalConstants.H" #include "unitConversion.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -70,8 +70,7 @@ Foam::cylindricalCS Foam::arcEdge::calcAngle()
vector r3(p3_ - centre); vector r3(p3_ - centre);
// find angles // find angles
angle_ = (acos((r3 & r1)/(mag(r3) * mag(r1)))) angle_ = radToDeg(acos((r3 & r1)/(mag(r3) * mag(r1))));
* 180.0/mathematicalConstant::pi;
// check if the vectors define an exterior or an interior arcEdge // check if the vectors define an exterior or an interior arcEdge
if (((r1 ^ r2) & (r1 ^ r3)) < 0.0) 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 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 | \\ / O peration |
\\ / A nd | For copyright notice see file Copyright \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License 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 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 under the terms of the GNU General Public License as published by
Free Software Foundation, either version 3 of the License, or (at your the Free Software Foundation, either version 3 of the License, or
option) any later version. (at your option) any later version.
foam-extend is distributed in the hope that it will be useful, but OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
WITHOUT ANY WARRANTY; without even the implied warranty of ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
General Public License for more details. for more details.
You should have received a copy of the GNU General Public 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/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class Class
Foam::arcEdge Foam::arcEdge
@ -89,8 +89,7 @@ public:
arcEdge(const pointField& points, Istream&); arcEdge(const pointField& points, Istream&);
// Destructor //- Destructor
virtual ~arcEdge(){} virtual ~arcEdge(){}

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