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))
613 <<
" read " <<
vertices.size() <<
" vertex indices." <<
endl;
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 "
905 << boundaryFaces.size() <<
endl;
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]);
990 patchFaceVerts.
setSize(patchFaceIndices.size());
992 Info<<
"Sorting boundary faces according to group (patch)" <<
endl;
999 Map<label> boundaryFaceToIndex(boundaryFaceIndices.size());
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];
1013 patchFaces.
setSize(faceIndices.size());
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);
1109 polyPoints.transfer(
points);
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())
1213 << oldIndizes.size() <<
endl;
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],