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
227 p.x() = readUnvScalar(
line.substr(0, 25));
228 p.y() = readUnvScalar(
line.substr(25, 25));
229 p.z() = readUnvScalar(
line.substr(50, 25));
245 if (indizes.
size() < (celli+1))
249 indizes[celli] = val;
269 label maxUnvPoint = 0;
270 forAll(unvPointID, pointi)
272 maxUnvPoint =
Foam::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;
623label findPatch(
const List<labelHashSet>& dofGroups,
const face&
f)
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"
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 =
Foam::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);
846 List<faceList> patchFaceVerts;
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)
951 List<labelHashSet> dofGroups(dofVertIndices.
size());
953 forAll(dofVertIndices, patchi)
955 const labelList& foamVerts = dofVertIndices[patchi];
956 dofGroups[patchi].insert(foamVerts);
959 List<DynamicList<face>> dynPatchFaces(dofVertIndices.
size());
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(patchFaceVerts, patchi)
1005 faceList& patchFaces = patchFaceVerts[patchi];
1006 const labelList& faceIndices = patchFaceIndices[patchi];
1010 bool duplicateFaces =
false;
1015 if (boundaryFaceToIndex.found(faceIndices[i]))
1017 label bFacei = boundaryFaceToIndex[faceIndices[i]];
1019 if (own[bFacei] != -1 && nei[bFacei] == -1)
1021 patchFaces[cnt] = boundaryFaces[bFacei];
1023 if (alreadyOnBoundary.
found(bFacei))
1025 duplicateFaces =
true;
1031 if (cnt != patchFaces.
size() || duplicateFaces)
1033 isAPatch[patchi] =
false;
1037 if (cnt != patchFaces.
size())
1040 <<
"For patch " << patchi <<
" there were "
1041 << patchFaces.
size()-cnt
1042 <<
" faces not used because they seem"
1043 <<
" to be internal. "
1044 <<
"This seems to be a face or a cell-zone"
1051 << patchi <<
" has faces that are already "
1052 <<
" in use on other boundary-patches,"
1053 <<
" Assuming faceZoneset." <<
endl;
1059 if (cellCorrespondence[faceIndices[0]] >= 0)
1065 if (cellCorrespondence[faceIndices[0]] < 0)
1068 <<
"The face index " << faceIndices[i]
1069 <<
" was not found amongst the cells."
1070 <<
" This kills the theory that "
1075 theCells[i] = cellCorrespondence[faceIndices[i]];
1085 theFaces[i] = boundaryFaceToIndex[faceIndices[i]];
1096 label bFacei = boundaryFaceToIndex[faceIndices[i]];
1097 alreadyOnBoundary.
insert(bFacei);
1107 polyPoints /= lengthScale;
1111 if (
args.found(
"dump"))
1113 Info<<
"Writing boundary faces to OBJ file boundaryFaces.obj"
1122 rawSurface.localPoints(),
1123 rawSurface.localFaces()
1124 ).write(
runTime.path()/
"boundaryFaces.obj");
1128 Info<<
"\nConstructing mesh with non-default patches of size:" <<
nl;
1134 if (isAPatch[patchi])
1137 << patchFaceVerts[patchi].
size() <<
nl;
1139 usedPatchFaceVerts.
append(patchFaceVerts[patchi]);
1143 usedPatchFaceVerts.
shrink();
1156 std::move(polyPoints),
1162 polyPatch::typeName,
1169 if (faceZones.
size() || cellZones.
size())
1171 Info <<
"Adding cell and face zones" <<
endl;
1173 List<pointZone*>
pZones(0);
1174 List<faceZone*> fZones(faceZones.
size());
1175 List<cellZone*> cZones(cellZones.
size());
1177 if (cellZones.
size())
1194 if (faceZones.
size())
1212 const label old = oldIndizes[i];
1229 const face&
f = boundaryFaces[old];
1230 if (
mag(centers[j]-
f.centre(
points)) < SMALL)
1244 (c1 == own[j] && c2 == nei[j])
1245 || (c2 == own[j] && c1 == nei[j])
1253 assert(noveau > -1);
1254 indizes[i] = noveau;
1258 faceZones.
toc()[cnt],
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void transfer(List< T > &list)
Transfer contents of the argument List into this.
void setSize(const label n)
Alias for resize().
void append(const T &val)
Copy append an element to the end of this list.
void push_back(const T &val)
Copy append an element to the end of this list.
DynamicList< T, SizeMin > & shrink()
Calls shrink_to_fit() and returns a reference to the DynamicList.
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
Same as contains().
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 as an ISstream, normally using std::ifstream for the actual input.
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.
static unsigned int minPrecision(unsigned int prec) noexcept
Set the minimum default precision.
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)
Transfer the contents of the argument List into this list and annul the argument list.
void setSize(label n)
Alias for resize().
void clear()
Clear the list, i.e. set size to zero.
A HashTable to objects of type <T> with a label key.
bool found(const T &val, label pos=0) const
Same as contains().
void size(const label n)
Older name for setAddressableSize.
T & last()
Access last element of the list, position [size()-1].
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
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.
static void addNote(const string ¬e)
Add extra notes for the usage information.
Maps a geometry to a set of cell primitives.
static const cellModel & ref(const modelType model)
Look up reference to cellModel by enumeration. Fatal on failure.
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.
static int compare(const face &a, const face &b)
Compare faces.
A class for handling file names.
Mesh consisting of general polyhedral cells.
static word defaultRegion
Return the default region name.
A class for handling words, derived from Foam::string.
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
IOporosityModelList pZones(mesh)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
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.
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].
List< word > wordList
List of word.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
Map< label > invertToMap(const labelUList &values)
Create inverse mapping, which is a lookup table into the given list.
List< label > labelList
A List of labels.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
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 within a list.
List< face > faceList
List of faces.
IOstream & hex(IOstream &io)
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
MeshedSurface< face > meshedSurface
pointField vertices(const blockVertexList &bvl)
void sort(UList< T > &list)
Sort the list.
errorManip< error > abort(error &err)
vector point
Point is a vector.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
vectorField pointField
pointField is a vectorField.
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.