60 const string SEPARATOR(
" -1");
62 bool isSeparator(
const std::string&
line)
64 return line.substr(0, 6) == SEPARATOR;
88 tag =
line.substr(0, 6);
90 }
while (tag == SEPARATOR);
105 if (isSeparator(
line))
128 if (isSeparator(
line))
136 scalar readUnvScalar(
const std::string& unvString)
140 s.replaceAll(
"d",
"E");
141 s.replaceAll(
"D",
"E");
143 return readScalar(
s);
165 string units(
line.substr(10, 20));
169 Info<<
"unitType:" << unitType <<
endl;
174 lengthScale = readUnvScalar(
line.substr(0, 25));
175 forceScale = readUnvScalar(
line.substr(25, 25));
176 tempScale = readUnvScalar(
line.substr(50, 25));
179 tempOffset = readUnvScalar(
line.substr(0, 25));
181 Info<<
"Unit factors:" <<
nl 182 <<
" Length scale : " << lengthScale <<
nl 183 <<
" Force scale : " << forceScale <<
nl 184 <<
" Temperature scale : " << tempScale <<
nl 185 <<
" Temperature offset : " << tempOffset <<
nl 200 static bool hasWarned =
false;
213 else if (pointi !=
points.
size()+1 && !hasWarned)
218 <<
"Points not in order starting at point " << pointi
224 pt[0] = readUnvScalar(
line.substr(0, 25));
225 pt[1] = readUnvScalar(
line.substr(25, 25));
226 pt[2] = readUnvScalar(
line.substr(50, 25));
228 unvPointID.
append(pointi);
245 if (indizes.
size() < (celli+1))
249 indizes[celli] = val;
269 label maxUnvPoint = 0;
270 forAll(unvPointID, pointi)
272 maxUnvPoint =
max(maxUnvPoint, unvPointID[pointi]);
290 if (isSeparator(
line))
295 label celli, feID, physProp, matProp, colour, nNodes;
299 >> celli >> feID >> physProp >> matProp >> colour >> nNodes;
301 if (foundFeType.
insert(feID))
303 Info<<
"First occurrence of element type " << feID
304 <<
" for cell " << celli <<
" at line " 314 else if (feID == 171)
319 else if (feID == 41 || feID == 91)
327 >> cVerts[0] >> cVerts[1] >> cVerts[2];
328 boundaryFaces.
append(cVerts);
329 boundaryFaceIndices.
append(celli);
331 else if (feID == 44 || feID == 94)
339 >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3];
340 boundaryFaces.
append(cVerts);
341 boundaryFaceIndices.
append(celli);
343 else if (feID == 111)
351 >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3];
354 cellMaterial.
append(physProp);
355 addAndExtend(cellCorrespondence,celli,cellMaterial.
size()-1);
357 if (cellVerts.
last().
size() != cVerts.size())
360 <<
" element:" << celli
362 <<
" collapsed from " << cVerts <<
nl 363 <<
" to:" << cellVerts.
last()
367 else if (feID == 112)
375 >> cVerts[0] >> cVerts[1] >> cVerts[2]
376 >> cVerts[3] >> cVerts[4] >> cVerts[5];
379 cellMaterial.
append(physProp);
380 addAndExtend(cellCorrespondence,celli,cellMaterial.
size()-1);
382 if (cellVerts.
last().
size() != cVerts.size())
385 <<
" element:" << celli
387 <<
" collapsed from " << cVerts <<
nl 388 <<
" to:" << cellVerts.
last()
392 else if (feID == 115)
400 >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3]
401 >> cVerts[4] >> cVerts[5] >> cVerts[6] >> cVerts[7];
404 cellMaterial.
append(physProp);
405 addAndExtend(cellCorrespondence,celli,cellMaterial.
size()-1);
407 if (cellVerts.
last().
size() != cVerts.size())
410 <<
" element:" << celli
412 <<
" collapsed from " << cVerts <<
nl 413 <<
" to:" << cellVerts.
last()
417 else if (feID == 118)
427 >> cVerts[0] >> dummy >> cVerts[1] >> dummy >> cVerts[2];
432 lineStr >> dummy>> cVerts[3];
436 cellMaterial.
append(physProp);
437 addAndExtend(cellCorrespondence,celli,cellMaterial.
size()-1);
439 if (cellVerts.
last().
size() != cVerts.size())
442 <<
" element:" << celli
444 <<
" collapsed from " << cVerts <<
nl 445 <<
" to:" << cellVerts.
last()
451 if (skippedElements.
insert(feID))
454 <<
"Cell type " << feID <<
" not supported" <<
endl;
464 boundaryFaceIndices.
shrink();
465 cellCorrespondence.
shrink();
467 Info<<
"Read " << cellVerts.
size() <<
" cells" 468 <<
" and " << boundaryFaces.
size() <<
" boundary faces." <<
endl;
470 if (!cellVerts.
size())
473 <<
"There are no cells in the mesh." <<
endl 474 <<
" Note: 2D meshes are not supported."<<
endl;
486 Info<<
"Starting reading patches at line " << is.
lineNumber() <<
'.' 494 if (isSeparator(
line))
500 label
group, constraintSet, restraintSet, loadSet, dofSet,
501 tempSet, contactSet, nFaces;
503 >>
group >> constraintSet >> restraintSet >> loadSet
504 >> dofSet >> tempSet >> contactSet >> nFaces;
510 <<
" named " << groupName
511 <<
" trying to read " << nFaces <<
" patch face indices." 515 label groupType = -1;
518 while (nFaces < groupIndices.size())
525 if (nFaces == groupIndices.size()-1)
530 for (label i = 0; i < nRead; i++)
534 lineStr >> groupType >> tag >> nodeLeaf >>
component;
536 groupIndices[nFaces++] = tag;
545 patchFaceIndices.
append(groupIndices);
550 <<
"When reading patches expect entity type code 8" 551 <<
nl <<
" Skipping group code " << groupType
557 patchFaceIndices.
shrink();
570 Info<<
"Starting reading constraints at line " << is.
lineNumber() <<
'.' 590 <<
" trying to read vertex indices." 599 if (isSeparator(
line))
627 if (dofGroups[patchi].
found(
f[0]))
629 bool allInGroup =
true;
632 for (label fp = 1; fp <
f.
size(); fp++)
634 if (!dofGroups[patchi].
found(
f[fp]))
652 int main(
int argc,
char *argv[])
656 "Convert I-Deas unv format to OpenFOAM" 663 "Dump boundary faces as boundaryFaces.obj (for debugging)" 675 <<
"Cannot open file " << ideasName
681 const bool verbose =
false;
684 scalar lengthScale = 1;
685 scalar forceScale = 1;
686 scalar tempScale = 1;
687 scalar tempOffset = 0;
709 while (inFile.good())
711 label tag = readTag(inFile);
718 Info<<
"Processing tag:" << tag <<
endl;
738 readPoints(inFile,
points, unvPointID);
774 Info<<
"Skipping tag " << tag <<
" on line " 775 << inFile.lineNumber() <<
endl;
784 label maxUnvPoint = 0;
785 forAll(unvPointID, pointi)
787 maxUnvPoint =
max(maxUnvPoint, unvPointID[pointi]);
801 static_cast<labelList&>(cellVerts[celli])
805 if (foamVerts.
found(-1))
809 <<
" unv vertices " << cellVerts[celli]
810 <<
" has some undefined vertices " << foamVerts
815 cellVerts[celli].
transfer(foamVerts);
820 forAll(boundaryFaces, bFacei)
824 if (foamVerts.
found(-1))
827 <<
"Boundary face " << bFacei
828 <<
" unv vertices " << boundaryFaces[bFacei]
829 <<
" has some undefined vertices " << foamVerts
834 boundaryFaces[bFacei].
transfer(foamVerts);
857 forAll(boundaryFaces, bfacei)
859 face sortedVerts(boundaryFaces[bfacei]);
861 faceToFaceID.insert(sortedVerts, bfacei);
866 const cellShape& shape = cellVerts[celli];
872 const label bfacei = faceToFaceID.lookup(sortedVerts, -1);
894 if (own[facei] == -1 && nei[facei] != -1)
897 boundaryFaces[facei].flip();
898 std::swap(own[facei], nei[facei]);
904 Info <<
"Found " << nReverse <<
" reversed boundary faces out of " 912 if (own[facei] != -1 && nei[facei] != -1)
922 Info <<
"Of " << boundaryFaces.
size() <<
" so-called" 923 <<
" boundary faces " << cnt <<
" belong to two cells " 924 <<
"and are therefore internal" <<
endl;
932 if (dofVertIndices.
size())
940 Info<<
"Using " << dofVertIndices.
size()
941 <<
" DOF sets to detect boundary faces."<<
endl;
944 forAll(dofVertIndices, patchi)
953 forAll(dofVertIndices, patchi)
955 const labelList& foamVerts = dofVertIndices[patchi];
956 dofGroups[patchi].insert(foamVerts);
963 const cellShape& shape = cellVerts[celli];
967 label patchi = findPatch(dofGroups,
f);
971 dynPatchFaces[patchi].append(
f);
977 patchFaceVerts.
setSize(dynPatchFaces.size());
979 forAll(dynPatchFaces, patchi)
981 patchFaceVerts[patchi].
transfer(dynPatchFaces[patchi]);
992 Info<<
"Sorting boundary faces according to group (patch)" <<
endl;
1001 forAll(boundaryFaceIndices, i)
1003 boundaryFaceToIndex.insert(boundaryFaceIndices[i], i);
1006 forAll(patchFaceVerts, patchi)
1010 faceList& patchFaces = patchFaceVerts[patchi];
1011 const labelList& faceIndices = patchFaceIndices[patchi];
1015 bool duplicateFaces =
false;
1020 if (boundaryFaceToIndex.found(faceIndices[i]))
1022 label bFacei = boundaryFaceToIndex[faceIndices[i]];
1024 if (own[bFacei] != -1 && nei[bFacei] == -1)
1026 patchFaces[cnt] = boundaryFaces[bFacei];
1028 if (alreadyOnBoundary.
found(bFacei))
1030 duplicateFaces =
true;
1036 if (cnt != patchFaces.
size() || duplicateFaces)
1038 isAPatch[patchi] =
false;
1042 if (cnt != patchFaces.
size())
1045 <<
"For patch " << patchi <<
" there were " 1046 << patchFaces.
size()-cnt
1047 <<
" faces not used because they seem" 1048 <<
" to be internal. " 1049 <<
"This seems to be a face or a cell-zone" 1056 << patchi <<
" has faces that are already " 1057 <<
" in use on other boundary-patches," 1058 <<
" Assuming faceZoneset." <<
endl;
1064 if (cellCorrespondence[faceIndices[0]] >= 0)
1070 if (cellCorrespondence[faceIndices[0]] < 0)
1073 <<
"The face index " << faceIndices[i]
1074 <<
" was not found amongst the cells." 1075 <<
" This kills the theory that " 1080 theCells[i] = cellCorrespondence[faceIndices[i]];
1090 theFaces[i] = boundaryFaceToIndex[faceIndices[i]];
1101 label bFacei = boundaryFaceToIndex[faceIndices[i]];
1102 alreadyOnBoundary.
insert(bFacei);
1112 polyPoints /= lengthScale;
1118 Info<<
"Writing boundary faces to OBJ file boundaryFaces.obj" 1127 rawSurface.localPoints(),
1128 rawSurface.localFaces()
1133 Info<<
"\nConstructing mesh with non-default patches of size:" <<
nl;
1139 if (isAPatch[patchi])
1142 << patchFaceVerts[patchi].
size() <<
nl;
1144 usedPatchFaceVerts.
append(patchFaceVerts[patchi]);
1148 usedPatchFaceVerts.
shrink();
1161 std::move(polyPoints),
1167 polyPatch::typeName,
1174 if (faceZones.
size() || cellZones.
size())
1176 Info <<
"Adding cell and face zones" <<
endl;
1182 if (cellZones.
size())
1199 if (faceZones.
size())
1217 const label old = oldIndizes[i];
1219 label
c1 = -1,
c2 = -1;
1241 const face&
f = boundaryFaces[old];
1242 if (
mag(centers[j]-
f.centre(
points)) < SMALL)
1256 (
c1 == own[j] &&
c2 == nei[j])
1257 || (
c2 == own[j] &&
c1 == nei[j])
1265 assert(noveau > -1);
1266 indizes[i] = noveau;
1270 faceZones.
toc()[cnt],
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
static void addNote(const string ¬e)
Add extra notes for the usage information.
void size(const label n)
Older name for setAddressableSize.
fileName path() const
Return path = rootPath/caseName. Same as TimePaths::path()
A class for handling file names.
errorManipArg< error, int > exit(error &err, const int errNo=1)
A face is a list of labels corresponding to mesh vertices.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
IOstream & hex(IOstream &io)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
void append(const T &val)
Append an element at the end of the list.
bool found(const Key &key) const
Same as contains()
virtual const labelList & faceNeighbour() const
Return face neighbour.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
An analytical geometric cellShape.
constexpr char nl
The newline '\n' character (0x0a)
const dimensionedScalar c2
Second radiation constant: default SI units: [m.K].
Ostream & endl(Ostream &os)
Add newline and flush stream.
bool found(const T &val, label pos=0) const
Same as contains()
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
static unsigned int defaultPrecision() noexcept
Return the default precision.
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
static void noParallel()
Remove the parallel options.
constexpr char tab
The tab '\t' character(0x09)
void setSize(const label n)
Same as resize()
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
virtual const pointField & points() const
Return raw points.
#define forAll(list, i)
Loop across all elements in list.
static const cellModel & ref(const modelType model)
Look up reference to cellModel by enumeration. Fatal on failure.
constexpr const char *const group
Group name for atomic constants.
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
pointField vertices(const blockVertexList &bvl)
label size() const noexcept
The number of elements in table.
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
faceList faces() const
Faces of this cell.
void setSize(const label n)
Alias for resize()
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
void removeFiles(const fileName &instanceDir) const
Remove all files from mesh instance.
void clear()
Clear the list, i.e. set size to zero.
A class for handling words, derived from Foam::string.
MeshedSurface< face > meshedSurface
void sort(UList< T > &list)
Sort the list.
static word defaultRegion
Return the default region name.
A topoSetCellSource to select all cells based on usage in given faceSet(s), e.g. select cells that ar...
wordList patchNames(nPatches)
void addZones(PtrList< pointZone > &&pz, PtrList< faceZone > &&fz, PtrList< cellZone > &&cz)
Add mesh zones.
virtual const labelList & faceOwner() const
Return face owner.
void append(const T &val)
Copy append an element to the end of this list.
A HashTable similar to std::unordered_map.
errorManip< error > abort(error &err)
virtual bool write(const bool writeOnProc=true) const
Write mesh using IO settings from time.
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
const word & constant() const noexcept
Return constant name.
DynamicList< T, SizeMin > & shrink()
Calls shrink_to_fit() and returns a reference to the DynamicList.
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Input from file stream, using an ISstream.
T & last()
Access last element of the list, position [size()-1].
label lineNumber() const noexcept
Const access to the current stream line number.
const vectorField & faceCentres() const
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
List< word > wordList
List of word.
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
Ostream & flush(Ostream &os)
Flush stream.
T get(const label index) const
Get a value from the argument at index.
#define WarningInFunction
Report a warning using Foam::Warning.
Input from string buffer, using a ISstream. Always UNCOMPRESSED.
bool good() const noexcept
True if next operation might succeed.
Maps a geometry to a set of cell primitives.
void transfer(List< T > &list)
Transfer contents of the argument List into this.
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
const cellZoneMesh & cellZones() const noexcept
Return cell zone mesh.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
messageStream Info
Information stream (stdout output on master, null elsewhere)
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Mesh consisting of general polyhedral cells.
A subset of mesh faces organised as a primitive patch.
List< Key > toc() const
The table of contents (the keys) in unsorted order.
static int compare(const face &a, const face &b)
Compare faces.
A class for managing temporary objects.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Foam::argList args(argc, argv)
Defines the attributes of an object for which implicit objectRegistry management is supported...
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
bool found(const word &optName) const
Return true if the named option is found.
IOporosityModelList pZones(mesh)