79 void read(
const std::string& fileName, std::size_t boundarySegThresh,
bool verbose =
false)
82 if (verbose) std::cout <<
"Opening " << fileName << std::endl;
83 std::ifstream gridFile(fileName);
85 DUNE_THROW(Dune::InvalidStateException,
"Could not open the given .msh file. Make sure it exists");
89 std::getline(gridFile, line);
90 if (line.find(
"$MeshFormat") == std::string::npos)
91 DUNE_THROW(Dune::InvalidStateException,
"Expected $MeshFormat in the first line of the grid file!");
92 std::getline(gridFile, line);
93 if (line.find_first_of(
"2") != 0)
94 DUNE_THROW(Dune::InvalidStateException,
"Currently only Gmsh mesh file format version 2 is supported!");
97 while (line.find(
"$Nodes") == std::string::npos)
98 std::getline(gridFile, line);
101 std::getline(gridFile, line);
102 const auto numVertices = convertString<std::size_t>(line);
103 gridVertices_.resize(numVertices);
105 std::getline(gridFile, line);
106 std::size_t vertexCount = 0;
107 while (line.find(
"$EndNodes") == std::string::npos)
110 std::istringstream stream(line);
111 std::string buf; stream >> buf;
113 for (
auto& coord : v)
116 if (stream.fail()) DUNE_THROW(Dune::IOError,
"Could not read vertex coordinate");
120 gridVertices_[vertexCount++] = v;
121 std::getline(gridFile, line);
125 if (vertexCount != numVertices)
126 DUNE_THROW(Dune::InvalidStateException,
"Couldn't find as many vertices as stated in the .msh file");
129 while(line.find(
"$Elements") == std::string::npos)
130 std::getline(gridFile, line);
133 std::getline(gridFile, line);
134 const auto numElements = convertString<std::size_t>(line);
137 std::array<std::size_t, numGrids> elementCount;
138 std::fill(elementCount.begin(), elementCount.end(), 0);
142 std::size_t elemCount = 0;
143 std::array<std::size_t, numGrids> gridVertexCount;
144 std::array<std::vector<GridIndexType>, numGrids> gridVertexMap;
145 std::array<std::vector<bool>, numGrids> idxIsAssigned;
146 std::fill(gridVertexCount.begin(), gridVertexCount.end(), 0);
147 std::fill(gridVertexMap.begin(), gridVertexMap.end(), std::vector<GridIndexType>(vertexCount));
148 std::fill(idxIsAssigned.begin(), idxIsAssigned.end(), std::vector<bool>(vertexCount,
false));
149 std::getline(gridFile, line);
150 while (line.find(
"$EndElements") == std::string::npos)
153 std::istringstream stream(line);
155 std::vector<std::size_t> lineData;
156 while (stream >> buf) lineData.push_back(convertString<std::size_t>(buf));
157 assert(lineData.size() >= 4 &&
"Grid format erroneous or unsupported");
160 const auto gt = obtainGeometryType( lineData[1] );
161 const std::size_t physicalIndex = lineData[3];
162 const auto geoDim = gt.dim();
163 const bool isBoundarySeg = geoDim != bulkDim && physicalIndex < boundarySegThresh;
164 if (geoDim >= minGridDim-1)
167 if ((isBoundarySeg || geoDim == minGridDim-1))
169 const unsigned int nextLevelGridIdx = bulkDim-geoDim-1;
171 VertexIndexSet corners;
172 auto it = lineData.begin()+2+lineData[2]+1;
173 for (; it != lineData.end(); ++it)
178 if (!idxIsAssigned[nextLevelGridIdx][*it])
180 gridVertexMap[nextLevelGridIdx][*it] = gridVertexCount[nextLevelGridIdx]++;
181 idxIsAssigned[nextLevelGridIdx][*it] =
true;
182 vertexIndices_[nextLevelGridIdx].push_back(*it);
185 corners.push_back(gridVertexMap[nextLevelGridIdx][*it]);
189 boundaryMarkerMaps_[nextLevelGridIdx].push_back(physicalIndex);
190 boundarySegments_[nextLevelGridIdx].push_back(corners);
196 const unsigned int gridIdx = bulkDim-geoDim;
198 VertexIndexSet corners;
199 auto it = lineData.begin()+2+lineData[2]+1;
200 for (; it != lineData.end(); ++it)
205 if (!idxIsAssigned[gridIdx][*it])
207 gridVertexMap[gridIdx][*it] = gridVertexCount[gridIdx]++;
208 idxIsAssigned[gridIdx][*it] =
true;
209 vertexIndices_[gridIdx].push_back(*it);
212 corners.push_back(gridVertexMap[gridIdx][*it]);
216 if (geoDim > minGridDim)
218 const auto gridElemCount = elementData_[gridIdx].size();
219 const auto& embeddedVIndices = vertexIndices_[gridIdx+1];
220 const auto& embeddedIndicesAssigned = idxIsAssigned[gridIdx+1];
222 VertexIndexSet cornerIndicesGlobal(corners.size());
223 for (
unsigned int i = 0; i < corners.size(); ++i)
224 cornerIndicesGlobal[i] = vertexIndices_[gridIdx][corners[i]];
225 addEmbeddings(cornerIndicesGlobal, gridIdx, gridElemCount, embeddedVIndices, embeddedIndicesAssigned);
229 reorder(gt, corners);
232 elementMarkerMaps_[gridIdx].push_back(physicalIndex);
233 elementData_[gridIdx].emplace_back(ElementData({gt, corners}));
238 std::getline(gridFile, line);
243 if (elemCount != numElements)
244 DUNE_THROW(Dune::InvalidStateException,
"Didn't read as many elements as stated in the .msh file");
248 std::cout <<
"Finished reading gmsh file" << std::endl;
249 for (std::size_t
id = 0;
id < numGrids; ++id)
251 std::cout << elementData_[id].size() <<
" "
252 << bulkDim-
id <<
"-dimensional elements comprising of "
253 << gridVertexCount[id] <<
" vertices";
254 if (
id < numGrids-1) std::cout <<
"," << std::endl;
256 std::cout <<
" have been read in " << watch.elapsed() <<
" seconds." << std::endl;