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.push_back(verti-1);
96 const label elemCount,
98 Map<label>& elemToFoam
101 const label begElem = foamToElem.size();
102 const label endElem = begElem + elemCount;
104 foamToElem.resize(foamToElem.size()+elemCount);
108 elemToFoam.reserve(elemToFoam.size()+elemCount);
110 for (label elemi = begElem; elemi < endElem; ++elemi)
114 foamToElem[elemi] = id;
115 elemToFoam.insert(
id, elemi);
121 for (label elemi = begElem; elemi < endElem; ++elemi)
123 foamToElem[elemi] = elemi;
131 const cellModel& model,
132 DynamicList<label>& verts,
158 if (model.mag(verts,
points) < 0)
160 if (verts.size() == 8)
163 std::swap(verts[0], verts[4]);
164 std::swap(verts[1], verts[5]);
165 std::swap(verts[2], verts[6]);
166 std::swap(verts[3], verts[7]);
168 else if (verts.size() == 4)
171 std::swap(verts[0], verts[1]);
173 else if (verts.size() == 5)
176 std::swap(verts[1], verts[3]);
178 else if (verts.size() == 6)
181 std::swap(verts[0], verts[3]);
182 std::swap(verts[1], verts[4]);
183 std::swap(verts[2], verts[5]);
192 const bool read_node_ids,
193 const bool read_elem_ids,
197 Map<label>& nodeIdToPoints,
202 Map<label>& elemIdToCells,
207 Map<label>& elemIdToFaces
215 DynamicList<label> verts;
225 while (buffer.empty() && is.good());
231 else if (buffer.contains(
"BEGIN TIME STEP"))
236 else if (buffer.contains(
"END TIME STEP"))
248 const auto keyword(
split[0].str());
250 if (keyword ==
"part")
254 else if (keyword ==
"node_ids")
258 for (label pointi = 0; pointi <
nPoints; ++pointi)
264 else if (keyword ==
"coordinates")
270 <<
" starting at line " << is.lineNumber()
271 <<
" position " << is.stdStream().tellg() <<
endl;
285 else if (keyword ==
"tetra4")
292 <<
" position " << is.stdStream().tellg() <<
endl;
304 const label startElemi =
cells.size();
305 cells.resize(startElemi+elemCount);
309 for (
auto& cellFaces : myElements)
311 readVerts(is, 4, nodeIdToPoints, verts);
314 setHandedness(model, verts,
points);
316 cellFaces = cellShape(model, verts).faces();
319 else if (keyword ==
"pyramid5")
326 <<
" position " << is.stdStream().tellg() <<
endl;
338 const label startElemi =
cells.size();
339 cells.resize(startElemi+elemCount);
343 for (
auto& cellFaces : myElements)
345 readVerts(is, 5, nodeIdToPoints, verts);
348 setHandedness(model, verts,
points);
350 cellFaces = cellShape(model, verts).faces();
353 else if (keyword ==
"penta6")
360 <<
" position " << is.stdStream().tellg() <<
endl;
372 const label startElemi =
cells.size();
373 cells.resize(startElemi+elemCount);
377 for (
auto& cellFaces : myElements)
379 readVerts(is, 6, nodeIdToPoints, verts);
382 setHandedness(model, verts,
points);
384 cellFaces = cellShape(model, verts).faces();
387 else if (keyword ==
"hexa8")
394 <<
" position " << is.stdStream().tellg() <<
endl;
406 const label startElemi =
cells.size();
407 cells.resize(startElemi+elemCount);
411 for (
auto& cellFaces : myElements)
413 readVerts(is, 8, nodeIdToPoints, verts);
416 setHandedness(model, verts,
points);
418 cellFaces = cellShape(model, verts).faces();
421 else if (keyword ==
"nfaced")
428 <<
" position " << is.stdStream().tellg() <<
endl;
440 const label startElemi =
cells.size();
441 cells.resize(startElemi+elemCount);
444 for (
auto& cellFaces : myElements)
448 cellFaces.resize(nFaces);
451 for (
auto& cellFaces : myElements)
453 for (face&
f : cellFaces)
461 for (
faceList& cellFaces : myElements)
463 for (face&
f : cellFaces)
465 readVerts(is,
f.size(), nodeIdToPoints, verts);
466 f.labelList::operator=(verts);
473 for (
const face&
f : myElements[elemi])
475 for (label pointi :
f)
477 if (pointi < 0 || pointi >=
points.size())
482 <<
" indexes outside points:" <<
points.size()
489 else if (keyword ==
"tria3")
496 <<
" position " << is.stdStream().tellg() <<
endl;
508 const label startElemi =
cells.size();
509 faces.resize(startElemi+elemCount, face(3));
512 for (face&
f : myElements)
514 readVerts(is,
f.size(), nodeIdToPoints, verts);
515 f.labelList::operator=(verts);
518 else if (keyword ==
"quad4")
525 <<
" position " << is.stdStream().tellg() <<
endl;
537 const label startElemi =
cells.size();
538 faces.resize(startElemi+elemCount, face(4));
541 for (face&
f : myElements)
543 readVerts(is,
f.size(), nodeIdToPoints, verts);
544 f.labelList::operator=(verts);
547 else if (keyword ==
"nsided")
554 <<
" position " << is.stdStream().tellg() <<
endl;
566 const label startElemi =
cells.size();
567 faces.resize(startElemi+elemCount);
570 for (face&
f : myElements)
577 for (face&
f : myElements)
579 readVerts(is,
f.size(), nodeIdToPoints, verts);
580 f.labelList::operator=(verts);
586 <<
" from line " << buffer
587 <<
" starting at line " << is.lineNumber()
588 <<
" position " << is.stdStream().tellg() <<
endl;
601 const scalar scaleFactor
607 ensightReadFile is(geometryFile_);
614 Info<<
"Ensight : " << buffer <<
nl;
618 Info<<
"Ensight : " << buffer <<
nl;
621 bool read_node_ids =
false;
622 bool read_elem_ids =
false;
627 List<string> partNames;
629 DynamicList<label> partIDs;
630 PtrList<pointField> partPoints;
631 PtrList<labelList> partNodeIDs;
632 PtrList<Map<label>> partPointIDs;
636 PtrList<faceListList> partCells;
638 PtrList<labelList> partCellIDs;
639 PtrList<Map<label>> partCellElemIDs;
641 PtrList<faceList> partFaces;
643 PtrList<labelList> partFaceIDs;
644 PtrList<Map<label>> partFaceElemIDs;
648 SubStrings<string>
split;
657 while (buffer.empty() && is.good());
658 if (buffer.contains(
"END TIME STEP"))
670 const auto keyword(
split[0].str());
672 if (keyword ==
"extents")
680 is.read(
min.x()); is.read(
max.x());
681 is.read(
min.y()); is.read(
max.y());
682 is.read(
min.z()); is.read(
max.z());
686 else if (keyword ==
"node")
689 std::string op(
split[2]);
690 if (op ==
"given" || op ==
"ignore")
693 read_node_ids =
true;
696 else if (keyword ==
"element")
699 std::string op(
split[2]);
700 if (op ==
"given" || op ==
"ignore")
703 read_elem_ids =
true;
706 else if (keyword ==
"part")
708 bool finished =
false;
712 is.read(partIDs.emplace_back());
713 is.read(partNames.emplace_back());
716 <<
"Reading part " << partIDs.back()
717 <<
" name " << partNames.back()
719 <<
" position " << is.stdStream().tellg() <<
endl;
722 finished = readGoldPart
728 partPoints.emplace_back(),
729 partNodeIDs.emplace_back(),
730 partPointIDs.emplace_back(),
733 partCells.emplace_back(),
734 partCellIDs.emplace_back(),
735 partCellElemIDs.emplace_back(),
738 partFaces.emplace_back(),
739 partFaceIDs.emplace_back(),
740 partFaceElemIDs.emplace_back()
743 partPoints.back() *= scaleFactor;
746 <<
"For part " << partIDs.back()
747 <<
" read cells " << partCells.back().size()
748 <<
" faces " << partFaces.back().size()
824 extents.add(partPoints[parti]);
825 nPoints += partPoints[parti].size();
827 const scalar mergeDist = mergeTol_*extents.mag();
829 Pout<<
"Merging points closer than " << mergeDist
830 <<
" calculated from bounding box " << extents
831 <<
" and mergeTol " << mergeTol_
836 const auto& pPoints = partPoints[parti];
837 auto& pPointMap = pointToMerged[parti];
838 pPointMap.setSize(pPoints.size(), -1);
840 Pout<<
"Matching part " << parti
841 <<
" name " << partNames[parti]
842 <<
" points " << pPoints.size()
843 <<
" to current merged points " << points_.size()
849 pPointMap =
identity(pPoints.size());
865 forAll(from0To1, partPointi)
867 const label pointi = from0To1[partPointi];
870 pPointMap[partPointi] = pointi;
878 const label nOldPoints = points_.size();
879 points_.setSize(nOldPoints+nAdded);
881 forAll(from0To1, partPointi)
883 if (from0To1[partPointi] == -1)
885 const label
newPointi = nOldPoints+nAdded++;
886 points_[
newPointi] = pPoints[partPointi];
894 nodeIds_.setSize(points_.size());
895 forAll(partNodeIDs, parti)
897 const auto& pPointMap = pointToMerged[parti];
898 UIndirectList<label>(nodeIds_, pPointMap) = partNodeIDs[parti];
901 Pout<<
"Merged from " <<
nPoints <<
" down to " << points_.size()
902 <<
" points" <<
endl;
907 labelList cellOffsets(partCells.size()+1);
913 nCells += partCells[parti].size();
914 cellOffsets[parti+1] = nCells;
917 cellFaces_.setSize(nCells);
918 cellTableId_.setSize(nCells);
919 elementIds_.setSize(nCells, -1);
924 const auto&
cells = partCells[parti];
926 SubList<faceList> cellSlice
946 ) = partCellIDs[parti];
949 const auto& pointMap = pointToMerged[parti];
951 for (
auto& cellFaces : cellSlice)
953 for (
auto&
f : cellFaces)
965 cellTable_.setMaterial(parti,
"fluid");
966 cellTable_.setName(parti,
"part" +
Foam::name(partIDs[parti]));
973 HashTable<cellFaceIdentifier, face, face::symmHasher> vertsToCell
984 const auto& cFaces = cellFaces_[celli];
987 const face&
f = rotateFace(cFaces[cFacei], rotatedFace);
989 const auto fFnd = vertsToCell.find(
f);
993 vertsToCell.erase(fFnd);
997 vertsToCell.insert(
f, cellFaceIdentifier(celli, cFacei));
1003 labelList patchToPart(partNames.size());
1007 if (partFaces[parti].size())
1009 Pout<<
"Using part " << parti
1010 <<
" name " << partNames[parti]
1019 patchTypes_.setSize(
nPatches,
"wall");
1021 forAll(patchNames_, patchi)
1023 const label parti = patchToPart[patchi];
1025 Pout<<
"Matching part " << parti
1026 <<
" name " << partNames[parti]
1027 <<
" faces " << partFaces[parti].size()
1029 <<
" to merged faces " << vertsToCell.size()
1030 <<
", merged points " << points_.size()
1035 const auto& pointMap = pointToMerged[parti];
1036 const auto& faces = partFaces[parti];
1038 auto& partCellAndFace = boundaryIds_[patchi];
1039 partCellAndFace.setSize(faces.size());
1041 label patchFacei = 0;
1044 if (faces[facei].empty())
1046 Pout<<
"Ignoring empty face:" << facei <<
endl;
1051 const face newF(pointMap, faces[facei]);
1053 const auto cAndF = vertsToCell.find
1064 partCellAndFace[patchFacei++] = cAndF.val();
1065 vertsToCell.erase(cAndF);
1078 partCellAndFace.setSize(patchFacei);
1080 patchPhysicalTypes_.setSize(
nPatches,
"wall");
1084 if (vertsToCell.size())
1087 boundaryIds_.emplace_back(vertsToCell.size());
1089 auto& cellAndFaces = boundaryIds_.back();
1093 cellAndFaces[i++] = iter.val();
1097 patchTypes_.push_back(
"empty");
1098 patchNames_.push_back(
"defaultFaces");
1099 patchPhysicalTypes_.push_back(
"empty");
1100 patchStarts_.push_back(0);
1101 patchSizes_.push_back(0);
1103 Pout<<
"Introducing default patch " << patchNames_.size()-1
1104 <<
" name " << patchNames_.back() <<
endl;
1115 const fileName& geomFile,
1116 const objectRegistry& registry,
1117 const scalar mergeTol,
1118 const scalar scaleFactor,
1119 const bool setHandedness
1122 meshReader(geomFile, scaleFactor),
1123 mergeTol_(mergeTol),
1124 setHandedness_(setHandedness)
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
List< faceList > faceListList
List of faceList.
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.
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
SubList< faceList > subList
Declare type of subList.
List< labelList > labelListList
List of labelList.
Determine correspondence between points. See below.
#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.
List< face > faceList
List of faces.
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.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
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.
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 within a list.
vector point
Point is a vector.
#define WarningInFunction
Report a warning using Foam::Warning.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::SubStrings< StringType > splitSpace(const StringType &str, std::string::size_type pos=0)
Split string into sub-strings at whitespace (TAB, NL, VT, FF, CR, SPC)
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.
forAllConstIters(mixture.phases(), phase)