57 rotatedFace.setSize(
f.size());
60 rotatedFace[i] =
f[fp];
71 const Map<label>& nodeIdToPoints,
72 DynamicList<label>& verts
76 for (label i = 0; i < nVerts; i++)
86 verts.append(verti-1);
98 Map<label>& elemToFoam
101 const label sz = foamToElem.size();
102 foamToElem.resize(sz+nShapes);
105 elemToFoam.resize(sz+nShapes);
106 for (label shapei = 0; shapei < nShapes; shapei++)
110 foamToElem[sz+shapei] = elemi;
111 elemToFoam.insert(elemi, sz+shapei);
116 for (label shapei = 0; shapei < nShapes; shapei++)
118 foamToElem[sz+shapei] = sz+shapei;
126 const cellModel& model,
127 DynamicList<label>& verts,
153 if (model.mag(verts,
points) < 0)
155 if (verts.size() == 8)
158 Swap(verts[0], verts[4]);
159 Swap(verts[1], verts[5]);
160 Swap(verts[2], verts[6]);
161 Swap(verts[3], verts[7]);
163 else if (verts.size() == 4)
166 Swap(verts[0], verts[1]);
168 else if (verts.size() == 5)
171 Swap(verts[1], verts[3]);
173 else if (verts.size() == 6)
176 Swap(verts[0], verts[3]);
177 Swap(verts[1], verts[4]);
178 Swap(verts[2], verts[5]);
187 const bool read_node_ids,
188 const bool read_elem_ids,
192 Map<label>& nodeIdToPoints,
197 Map<label>& elemIdToCells,
202 Map<label>& elemIdToFaces
210 DynamicList<label> verts;
217 is.readKeyword(line);
219 while (line.empty() && is.good());
223 if (
split.size() == 0)
228 if (
split[0] ==
"part")
232 else if (
split[0] ==
"node_ids")
236 for (label i = 0; i <
nPoints; i++)
242 else if (
split[0] ==
"coordinates")
248 <<
" starting at line " << is.lineNumber()
249 <<
" position " << is.stdStream().tellg() <<
endl;
262 for (label pointi = 0; pointi <
nPoints; pointi++)
266 for (label pointi = 0; pointi <
nPoints; pointi++)
270 for (label pointi = 0; pointi <
nPoints; pointi++)
272 is.read(
points[pointi].z());
275 else if (
split[0] ==
"tetra4")
282 <<
" position " << is.stdStream().tellg() <<
endl;
284 const label celli =
cells.size();
285 cells.resize(celli+nShapes);
297 for (label shapei = 0; shapei < nShapes; shapei++)
299 readVerts(is, 4, nodeIdToPoints, verts);
302 setHandedness(model, verts,
points);
304 const cellShape cellVerts(model, verts);
305 cells[celli+shapei] = cellVerts.faces();
308 else if (
split[0] ==
"pyramid5")
315 <<
" position " << is.stdStream().tellg() <<
endl;
317 const label celli =
cells.size();
318 cells.resize(celli+nShapes);
330 for (label shapei = 0; shapei < nShapes; shapei++)
332 readVerts(is, 5, nodeIdToPoints, verts);
335 setHandedness(model, verts,
points);
337 const cellShape cellVerts(model, verts);
338 cells[celli+shapei] = cellVerts.faces();
341 else if (
split[0] ==
"penta6")
348 <<
" position " << is.stdStream().tellg() <<
endl;
350 const label celli =
cells.size();
351 cells.resize(celli+nShapes);
363 for (label shapei = 0; shapei < nShapes; shapei++)
365 readVerts(is, 6, nodeIdToPoints, verts);
368 setHandedness(model, verts,
points);
370 const cellShape cellVerts(model, verts);
371 cells[celli+shapei] = cellVerts.faces();
374 else if (
split[0] ==
"hexa8")
381 <<
" position " << is.stdStream().tellg() <<
endl;
383 const label celli =
cells.size();
384 cells.resize(celli+nShapes);
396 for (label shapei = 0; shapei < nShapes; shapei++)
398 readVerts(is, 8, nodeIdToPoints, verts);
401 setHandedness(model, verts,
points);
403 const cellShape cellVerts(model, verts);
404 cells[celli+shapei] = cellVerts.faces();
407 else if (
split[0] ==
"nfaced")
414 <<
" position " << is.stdStream().tellg() <<
endl;
416 const label celli =
cells.size();
417 cells.resize(celli+nShapes);
428 for (label shapei = 0; shapei < nShapes; shapei++)
433 cellFaces.setSize(nFaces);
436 for (label shapei = 0; shapei < nShapes; shapei++)
439 forAll(cellFaces, cellFacei)
443 cellFaces[cellFacei].setSize(nVerts);
447 for (label shapei = 0; shapei < nShapes; shapei++)
450 forAll(cellFaces, cellFacei)
452 face&
f = cellFaces[cellFacei];
453 readVerts(is,
f.size(), nodeIdToPoints, verts);
454 f.labelList::operator=(verts);
458 if (
f[fp] < 0 ||
f[fp] >=
points.size())
462 <<
" indexes outside points:" <<
points.size()
469 else if (
split[0] ==
"tria3")
476 <<
" position " << is.stdStream().tellg() <<
endl;
478 const label facei = faces.size();
489 faces.setSize(facei+nShapes);
491 for (label shapei = 0; shapei < nShapes; shapei++)
493 auto&
f = faces[facei+shapei];
495 readVerts(is,
f.size(), nodeIdToPoints, verts);
496 f.labelList::operator=(verts);
499 else if (
split[0] ==
"quad4")
506 <<
" position " << is.stdStream().tellg() <<
endl;
508 const label facei = faces.size();
519 faces.setSize(facei+nShapes);
521 for (label shapei = 0; shapei < nShapes; shapei++)
523 auto&
f = faces[facei+shapei];
525 readVerts(is,
f.size(), nodeIdToPoints, verts);
526 f.labelList::operator=(verts);
529 else if (
split[0] ==
"nsided")
536 <<
" position " << is.stdStream().tellg() <<
endl;
538 const label facei = faces.size();
549 faces.setSize(facei+nShapes);
551 for (label shapei = 0; shapei < nShapes; shapei++)
553 auto&
f = faces[facei+shapei];
559 for (label shapei = 0; shapei < nShapes; shapei++)
561 auto&
f = faces[facei+shapei];
562 readVerts(is,
f.size(), nodeIdToPoints, verts);
563 f.labelList::operator=(verts);
569 <<
" from line " << line
570 <<
" starting at line " << is.lineNumber()
571 <<
" position " << is.stdStream().tellg() <<
endl;
584 const scalar scaleFactor
587 ensightReadFile is(geometryFile_);
590 is.readBinaryHeader();
594 Info<<
"Ensight : " << header <<
endl;
596 Info<<
"Ensight : " << header <<
endl;
599 bool read_node_ids =
false;
600 bool read_elem_ids =
false;
605 List<string> partNames;
607 DynamicList<label> partIDs;
608 PtrList<pointField> partPoints;
609 PtrList<labelList> partNodeIDs;
610 PtrList<Map<label>> partPointIDs;
614 PtrList<faceListList> partCells;
616 PtrList<labelList> partCellIDs;
617 PtrList<Map<label>> partCellElemIDs;
619 PtrList<faceList> partFaces;
621 PtrList<labelList> partFaceIDs;
622 PtrList<Map<label>> partFaceElemIDs;
631 is.readKeyword(line);
633 while (line.empty() && is.good());
636 if (
split[0] ==
"extents")
647 <<
"Read extents " << boundBox(
min,
max)
650 else if (
split[0] ==
"node")
654 if (op ==
"given" || op ==
"ignore")
657 read_node_ids =
true;
660 else if (
split[0] ==
"element")
664 if (op ==
"given" || op ==
"ignore")
667 read_elem_ids =
true;
670 else if (
split[0] ==
"part")
672 bool finished =
false;
677 partIDs.append(partIndex);
680 partNames.setSize(partIDs.size());
683 partPointIDs.append(
new Map<label>());
687 partCellElemIDs.append(
new Map<label>());
691 partFaceElemIDs.append(
new Map<label>());
693 is.read(partNames.last());
696 <<
"Reading part " << partIndex
697 <<
" name " << partNames.last()
699 <<
" position " << is.stdStream().tellg() <<
endl;
702 finished = readGoldPart
715 partCellElemIDs.last(),
720 partFaceElemIDs.last()
723 partPoints.last() *= scaleFactor;
726 <<
"For part " << partIndex
727 <<
" read cells " << partCells.last().size()
728 <<
" faces " << partFaces.last().size()
804 extents.add(partPoints[parti]);
805 nPoints += partPoints[parti].size();
807 const scalar mergeDist = mergeTol_*extents.mag();
809 Pout<<
"Merging points closer than " << mergeDist
810 <<
" calculated from bounding box " << extents
811 <<
" and mergeTol " << mergeTol_
816 const auto& pPoints = partPoints[parti];
817 auto& pPointMap = pointToMerged[parti];
818 pPointMap.setSize(pPoints.size(), -1);
820 Pout<<
"Matching part " << parti
821 <<
" name " << partNames[parti]
822 <<
" points " << pPoints.size()
823 <<
" to current merged points " << points_.size()
829 pPointMap =
identity(pPoints.size());
845 forAll(from0To1, partPointi)
847 const label pointi = from0To1[partPointi];
850 pPointMap[partPointi] = pointi;
858 const label nOldPoints = points_.size();
859 points_.setSize(nOldPoints+nAdded);
861 forAll(from0To1, partPointi)
863 if (from0To1[partPointi] == -1)
865 const label
newPointi = nOldPoints+nAdded++;
866 points_[
newPointi] = pPoints[partPointi];
874 nodeIds_.setSize(points_.size());
875 forAll(partNodeIDs, parti)
877 const auto& pPointMap = pointToMerged[parti];
878 UIndirectList<label>(nodeIds_, pPointMap) = partNodeIDs[parti];
881 Pout<<
"Merged from " <<
nPoints <<
" down to " << points_.size()
882 <<
" points" <<
endl;
887 labelList cellOffsets(partCells.size()+1);
893 nCells += partCells[parti].size();
894 cellOffsets[parti+1] = nCells;
897 cellFaces_.setSize(nCells);
898 cellTableId_.setSize(nCells);
899 elementIds_.setSize(nCells, -1);
904 const auto&
cells = partCells[parti];
906 SubList<faceList> cellSlice
926 ) = partCellIDs[parti];
929 const auto& pointMap = pointToMerged[parti];
931 for (
auto& cellFaces : cellSlice)
933 for (
auto&
f : cellFaces)
945 cellTable_.setMaterial(parti,
"fluid");
946 cellTable_.setName(parti,
"part" +
Foam::name(partIDs[parti]));
953 HashTable<cellFaceIdentifier, face, face::symmHasher> vertsToCell
964 const auto& cFaces = cellFaces_[celli];
967 const face&
f = rotateFace(cFaces[cFacei], rotatedFace);
969 const auto fFnd = vertsToCell.find(
f);
973 vertsToCell.erase(fFnd);
977 vertsToCell.insert(
f, cellFaceIdentifier(celli, cFacei));
987 if (partFaces[parti].size())
989 Pout<<
"Using part " << parti
990 <<
" name " << partNames[parti]
999 patchTypes_.setSize(
nPatches,
"wall");
1001 forAll(patchNames_, patchi)
1003 const label parti = patchToPart[patchi];
1005 Pout<<
"Matching part " << parti
1006 <<
" name " << partNames[parti]
1007 <<
" faces " << partFaces[parti].size()
1009 <<
" to merged faces " << vertsToCell.size()
1010 <<
", merged points " << points_.size()
1015 const auto& pointMap = pointToMerged[parti];
1016 const auto& faces = partFaces[parti];
1018 auto& partCellAndFace = boundaryIds_[patchi];
1019 partCellAndFace.setSize(faces.size());
1021 label patchFacei = 0;
1024 if (faces[facei].empty())
1026 Pout<<
"Ignoring empty face:" << facei <<
endl;
1031 const face newF(pointMap, faces[facei]);
1033 const auto cAndF = vertsToCell.find
1054 partCellAndFace[patchFacei++] = cAndF();
1055 vertsToCell.erase(cAndF);
1058 partCellAndFace.setSize(patchFacei);
1060 patchPhysicalTypes_.setSize(
nPatches,
"wall");
1064 if (vertsToCell.size())
1067 boundaryIds_.append(List<cellFaceIdentifier>(0));
1069 auto& cellAndFaces = boundaryIds_.last();
1070 cellAndFaces.setSize(vertsToCell.size());
1072 for (
const auto&
e : vertsToCell)
1074 cellAndFaces[i++] =
e;
1077 patchTypes_.append(
"empty");
1078 patchNames_.append(
"defaultFaces");
1079 patchPhysicalTypes_.append(
"empty");
1080 patchStarts_.append(0);
1081 patchSizes_.append(0);
1083 Pout<<
"Introducing default patch " << patchNames_.size()-1
1084 <<
" name " << patchNames_.last() <<
endl;
1095 const fileName& geomFile,
1096 const objectRegistry& registry,
1097 const scalar mergeTol,
1098 const scalar scaleFactor,
1099 const bool setHandedness
1102 meshReader(geomFile, scaleFactor),
1103 mergeTol_(mergeTol),
1104 setHandedness_(setHandedness)
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
List< labelList > labelListList
A List of labelList.
Ostream & indent(Ostream &os)
Indent stream.
errorManipArg< error, int > exit(error &err, const int errNo=1)
A face is a list of labels corresponding to mesh vertices.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
List< face > faceList
A List of faces.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Determine correspondence between points. See below.
List< faceList > faceListList
A List of faceList.
#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.
label findMin(const ListType &input, label start=0)
Linear search for the index of the min element, similar to std::min_element but for lists and returns...
bool matchPoints(const UList< point > &pts0, const UList< point > &pts1, const UList< scalar > &matchDistance, const bool verbose, labelList &from0To1, const point &origin=point::zero)
Determine correspondence between pointFields. Gets passed.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
defineTypeNameAndDebug(combustionModel, 0)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Geometric merging of points. See below.
Foam::SubStrings< StringType > splitSpace(const StringType &str)
Split string into sub-strings at whitespace (TAB, NL, VT, FF, CR, SPC)
label lineNumber() const noexcept
Const access to the current stream line number.
static bool split(const std::string &line, std::string &key, std::string &val)
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
vector point
Point is a vector.
#define WarningInFunction
Report a warning using Foam::Warning.
void Swap(DynamicList< T, SizeMinA > &a, DynamicList< T, SizeMinB > &b)
messageStream Info
Information stream (stdout output on master, null elsewhere)
List< label > labelList
A List of labels.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.