60const string SEPARATOR(
" -1");
62bool 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))
136scalar 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]);
278 const cellModel& prism = cellModel::ref(cellModel::PRISM);
279 const cellModel& tet = cellModel::ref(cellModel::TET);
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;
507 const word groupName = word::validate(
line);
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]))
652int main(
int argc,
char *argv[])
656 "Convert I-Deas unv format to OpenFOAM"
658 argList::noParallel();
659 argList::addArgument(
".unv file");
660 argList::addBoolOption
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
811 <<
abort(FatalError);
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
830 <<
abort(FatalError);
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);
875 const int cmp = face::compare(
f, boundaryFaces[bfacei]);
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 "
1078 <<
abort(FatalError);
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()
1129 ).write(
runTime.path()/
"boundaryFaces.obj");
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();
1157 polyMesh::defaultRegion,
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],
1284 IOstream::defaultPrecision(
max(10u, IOstream::defaultPrecision()));
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
DynamicList< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
void transfer(List< T > &list)
Transfer contents of the argument List into this.
void setSize(const label n)
Same as resize()
void append(const T &val)
Copy append an element to the end of this list.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
A HashTable similar to std::unordered_map.
List< Key > toc() const
The table of contents (the keys) in unsorted order.
bool found(const Key &key) const
Return true if hashed entry is found in table.
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
label size() const noexcept
The number of elements in table.
Input from file stream, using an ISstream.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
label lineNumber() const noexcept
Const access to the current stream line number.
bool good() const noexcept
True if next operation might succeed.
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Input from string buffer, using a ISstream. Always UNCOMPRESSED.
void transfer(List< T > &list)
void setSize(const label n)
Alias for resize()
void append(const T &val)
Append an element at the end of the list.
A HashTable to objects of type <T> with a label key.
bool found(const T &val, label pos=0) const
True if the value if found in the list.
void size(const label n)
Older name for setAddressableSize.
T & last()
Return the last element of the list.
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.
Maps a geometry to a set of cell primitives.
An analytical geometric cellShape.
faceList faces() const
Faces of this cell.
A topoSetCellSource to select all cells based on usage in given faceSet(s), e.g. select cells that ar...
A subset of mesh faces organised as a primitive patch.
A face is a list of labels corresponding to mesh vertices.
A class for handling file names.
Mesh consisting of general polyhedral cells.
A class for managing temporary objects.
A class for handling words, derived from Foam::string.
IOporosityModelList pZones(mesh)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
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))
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
#define WarningInFunction
Report a warning using Foam::Warning.
void inplaceRenumber(const labelUList &oldToNew, IntListType &lists)
Inplace renumber the values (not the indices) of a list of lists.
constexpr const char *const group
Group name for atomic constants.
const dimensionedScalar c2
Second radiation constant: default SI units: [m.K].
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
messageStream Info
Information stream (stdout output on master, null elsewhere)
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
pointField vertices(const blockVertexList &bvl)
void sort(UList< T > &list)
Sort the list.
errorManip< error > abort(error &err)
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Ostream & flush(Ostream &os)
Flush stream.
constexpr char nl
The newline '\n' character (0x0a)
constexpr char tab
The tab '\t' character(0x09)
wordList patchNames(nPatches)
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.