91 if (
mesh.faces()[facei] ==
f)
98 <<
"Cannot find face " <<
f <<
" in mesh." <<
abort(FatalError);
105int main(
int argc,
char *argv[])
109 "Convert tetgen .ele and .node and .face files to an OpenFOAM mesh"
112 argList::addArgument(
"prefix",
"The prefix for the input tetgen files");
113 argList::addBoolOption
116 "Skip reading .face file for boundary information"
123 const bool readFaceFile = !
args.
found(
"noFaceFile");
125 const fileName nodeFile(prefix +
".node");
126 const fileName eleFile(prefix +
".ele");
127 const fileName faceFile(prefix +
".face");
132 <<
" nodes : " << nodeFile <<
endl
133 <<
" elems : " << eleFile <<
endl
139 <<
" nodes : " << nodeFile <<
endl
140 <<
" elems : " << eleFile <<
endl
141 <<
" faces : " << faceFile <<
endl
144 Info<<
"Reading .face file for boundary information" <<
nl <<
endl;
150 <<
"Cannot read " << nodeFile <<
" or " << eleFile
154 if (readFaceFile && !
isFile(faceFile))
157 <<
"Cannot read " << faceFile <<
endl
158 <<
"Did you run tetgen with -f option?" <<
endl
159 <<
"If you don't want to read the .face file and thus not have"
160 <<
" patches please\nrerun with the -noFaceFile option"
176 nodeStream.getLine(
line);
178 while (
line.starts_with(
'#'));
182 label nNodes, nDims, nNodeAttr;
185 nodeLine >> nNodes >> nDims >> nNodeAttr >> hasRegion;
189 <<
" nodes : " << nNodes <<
endl
190 <<
" nDims : " << nDims <<
endl
191 <<
" nAttr : " << nNodeAttr <<
endl
192 <<
" hasRegion : " << hasRegion <<
endl
207 while (nodeStream.good())
209 nodeStream.getLine(
line);
219 nodeLine >> nodeI >>
x >>
y >> z;
221 for (label i = 0; i < nNodeAttr; i++)
233 nodeToPoint.insert(nodeI, pointi);
237 if (pointi != nNodes)
240 <<
"Only " << pointi <<
" nodes present instead of " << nNodes
241 <<
" from header." <<
exit(FatalIOError);
253 eleStream.getLine(
line);
255 while (
line.starts_with(
'#'));
259 label nTets, nPtsPerTet, nElemAttr;
261 eleLine >> nTets >> nPtsPerTet >> nElemAttr;
265 <<
" tets : " << nTets <<
endl
266 <<
" pointsPerTet : " << nPtsPerTet <<
endl
267 <<
" nAttr : " << nElemAttr <<
endl
273 <<
"Cannot handle tets with "
274 << nPtsPerTet <<
" points per tetrahedron in .ele file" <<
endl
275 <<
"Can only handle tetrahedra with four points"
276 <<
exit(FatalIOError);
282 <<
"Element attributes (third elemenent in .ele header)"
283 <<
" not used" <<
endl;
287 const cellModel& tet = cellModel::ref(cellModel::TET);
294 while (eleStream.good())
296 eleStream.getLine(
line);
305 for (label i = 0; i < 4; i++)
315 for (label i = 0; i < nElemAttr; i++)
333 polyMesh::defaultRegion,
369 faceStream.getLine(
line);
371 while (
line.starts_with(
'#'));
377 faceLine >>
nFaces >> nFaceAttr;
382 <<
" nAttr : " << nFaceAttr <<
endl
389 <<
"Expect boundary markers to be"
390 <<
" present in .face file." <<
endl
391 <<
"This is the second number in the header which is now:"
392 << nFaceAttr <<
exit(FatalIOError);
409 while (faceStream.good())
411 faceStream.getLine(
line);
417 label tetGenFacei, dummy, region;
419 faceLine >> tetGenFacei;
423 for (label i = 0; i < 3; i++)
427 f[2-i] = nodeToPoint[nodeI];
431 if (findFace(
mesh,
f) >=
mesh.nInternalFaces())
433 boundaryFaces[facei] =
f;
444 const auto patchFind = regionToPatch.
cfind(region);
446 if (patchFind.found())
454 Info<<
"Mapping tetgen region " << region
464 for (label i = 1; i < nFaceAttr; i++)
486 Info<<
" region:" << iter.key()
487 <<
'\t' <<
"patch:" << iter.val() <<
nl;
498 patchNames[patchi] = polyPatch::defaultName(patchi);
514 allPatchFaces[patchi].append(boundaryFaces[facei]);
519 forAll(allPatchFaces, patchi)
522 << allPatchFaces[patchi].size() <<
endl;
524 patchFaces[patchi].transfer(allPatchFaces[patchi]);
536 polyMesh::defaultRegion,
553 IOstream::defaultPrecision(
max(10u, IOstream::defaultPrecision()));
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Input from file stream, using an ISstream.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Input from string buffer, using a ISstream. Always UNCOMPRESSED.
void setSize(const label n)
Alias for resize()
A HashTable to objects of type <T> with a label key.
T get(const label index) const
Get a value from the argument at index.
bool found(const word &optName) const
Return true if the named option is found.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Like polyPatch but without reference to mesh. Used in boundaryMesh to hold data on patches....
Maps a geometry to a set of cell primitives.
A face is a list of labels corresponding to mesh vertices.
A class for handling file names.
Mesh consisting of general polyhedral cells.
Cell-face mesh analysis engine.
Tet storage. Null constructable (unfortunately tetrahedron<point, point> is not)
A class for handling words, derived from Foam::string.
Foam::autoPtr< Foam::dynamicFvMesh > meshPtr
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
#define WarningInFunction
Report a warning using Foam::Warning.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
errorManip< error > abort(error &err)
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
errorManipArg< error, int > exit(error &err, const int errNo=1)
constexpr char nl
The newline '\n' character (0x0a)
wordList patchTypes(nPatches)
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]
wordList patchNames(nPatches)
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.