91 void read(
const std::string& fileName, std::size_t boundarySegThresh,
bool verbose =
false)
94 if (verbose) std::cout <<
"Opening " << fileName << std::endl;
95 std::ifstream gridFile(fileName);
97 DUNE_THROW(Dune::InvalidStateException,
"Could not open the given .msh file. Make sure it exists");
101 std::getline(gridFile, line);
102 if (line.find(
"$MeshFormat") == std::string::npos)
103 DUNE_THROW(Dune::InvalidStateException,
"Expected $MeshFormat in the first line of the grid file!");
104 std::getline(gridFile, line);
105 if (line.find_first_of(
"2") != 0)
106 DUNE_THROW(Dune::InvalidStateException,
"Currently only Gmsh mesh file format version 2 is supported!");
109 while (line.find(
"$Nodes") == std::string::npos)
110 std::getline(gridFile, line);
113 std::getline(gridFile, line);
114 const auto numVertices = convertString<std::size_t>(line);
115 gridVertices_.resize(numVertices);
117 std::getline(gridFile, line);
118 std::size_t vertexCount = 0;
119 while (line.find(
"$EndNodes") == std::string::npos)
122 std::istringstream stream(line);
123 std::string buf; stream >> buf;
125 for (
auto& coord : v)
128 if (stream.fail()) DUNE_THROW(Dune::IOError,
"Could not read vertex coordinate");
132 gridVertices_[vertexCount++] = v;
133 std::getline(gridFile, line);
137 if (vertexCount != numVertices)
138 DUNE_THROW(Dune::InvalidStateException,
"Couldn't find as many vertices as stated in the .msh file");
141 while(line.find(
"$Elements") == std::string::npos)
142 std::getline(gridFile, line);
145 std::getline(gridFile, line);
146 const auto numElements = convertString<std::size_t>(line);
149 std::array<std::size_t, numGrids> elementCount;
150 std::fill(elementCount.begin(), elementCount.end(), 0);
154 std::size_t elemCount = 0;
155 std::array<std::size_t, numGrids> gridVertexCount;
156 std::array<std::vector<GridIndexType>, numGrids> gridVertexMap;
157 std::array<std::vector<bool>, numGrids> idxIsAssigned;
158 std::fill(gridVertexCount.begin(), gridVertexCount.end(), 0);
159 std::fill(gridVertexMap.begin(), gridVertexMap.end(), std::vector<GridIndexType>(vertexCount));
160 std::fill(idxIsAssigned.begin(), idxIsAssigned.end(), std::vector<bool>(vertexCount,
false));
161 std::getline(gridFile, line);
162 while (line.find(
"$EndElements") == std::string::npos)
165 std::istringstream stream(line);
167 std::vector<std::size_t> lineData;
168 while (stream >> buf) lineData.push_back(convertString<std::size_t>(buf));
169 assert(lineData.size() >= 4 &&
"Grid format erroneous or unsupported");
172 const auto gt = obtainGeometryType( lineData[1] );
173 const std::size_t physicalIndex = lineData[3];
174 const auto geoDim = gt.dim();
175 const bool isBoundarySeg = geoDim != bulkDim && physicalIndex < boundarySegThresh;
176 if (geoDim >= minGridDim-1)
179 if ((isBoundarySeg || geoDim == minGridDim-1))
181 const unsigned int nextLevelGridIdx = bulkDim-geoDim-1;
183 VertexIndexSet corners;
184 auto it = lineData.begin()+2+lineData[2]+1;
185 for (; it != lineData.end(); ++it)
190 if (!idxIsAssigned[nextLevelGridIdx][*it])
192 gridVertexMap[nextLevelGridIdx][*it] = gridVertexCount[nextLevelGridIdx]++;
193 idxIsAssigned[nextLevelGridIdx][*it] =
true;
194 vertexIndices_[nextLevelGridIdx].push_back(*it);
197 corners.push_back(gridVertexMap[nextLevelGridIdx][*it]);
201 boundaryMarkerMaps_[nextLevelGridIdx].push_back(physicalIndex);
202 boundarySegments_[nextLevelGridIdx].push_back(corners);
208 const unsigned int gridIdx = bulkDim-geoDim;
210 VertexIndexSet corners;
211 auto it = lineData.begin()+2+lineData[2]+1;
212 for (; it != lineData.end(); ++it)
217 if (!idxIsAssigned[gridIdx][*it])
219 gridVertexMap[gridIdx][*it] = gridVertexCount[gridIdx]++;
220 idxIsAssigned[gridIdx][*it] =
true;
221 vertexIndices_[gridIdx].push_back(*it);
224 corners.push_back(gridVertexMap[gridIdx][*it]);
228 if (geoDim > minGridDim)
230 const auto gridElemCount = elementData_[gridIdx].size();
231 const auto& embeddedVIndices = vertexIndices_[gridIdx+1];
232 const auto& embeddedIndicesAssigned = idxIsAssigned[gridIdx+1];
234 VertexIndexSet cornerIndicesGlobal(corners.size());
235 for (
unsigned int i = 0; i < corners.size(); ++i)
236 cornerIndicesGlobal[i] = vertexIndices_[gridIdx][corners[i]];
237 addEmbeddings(cornerIndicesGlobal, gridIdx, gridElemCount, embeddedVIndices, embeddedIndicesAssigned);
241 reorder(gt, corners);
244 elementMarkerMaps_[gridIdx].push_back(physicalIndex);
245 elementData_[gridIdx].emplace_back(ElementData({gt, corners}));
250 std::getline(gridFile, line);
255 if (elemCount != numElements)
256 DUNE_THROW(Dune::InvalidStateException,
"Didn't read as many elements as stated in the .msh file");
260 std::cout <<
"Finished reading gmsh file" << std::endl;
261 for (std::size_t
id = 0;
id < numGrids; ++id)
263 std::cout << elementData_[id].size() <<
" "
264 << bulkDim-
id <<
"-dimensional elements comprising of "
265 << gridVertexCount[id] <<
" vertices";
266 if (
id < numGrids-1) std::cout <<
"," << std::endl;
268 std::cout <<
" have been read in " << watch.elapsed() <<
" seconds." << std::endl;