90 void read(
const std::string& fileName, std::size_t boundarySegThresh,
bool verbose =
false)
93 if (verbose) std::cout <<
"Opening " << fileName << std::endl;
94 std::ifstream gridFile(fileName);
96 DUNE_THROW(Dune::InvalidStateException,
"Could not open the given .msh file. Make sure it exists");
100 std::getline(gridFile,
line);
101 if (
line.find(
"$MeshFormat") == std::string::npos)
102 DUNE_THROW(Dune::InvalidStateException,
"Expected $MeshFormat in the first line of the grid file!");
103 std::getline(gridFile,
line);
104 if (
line.find_first_of(
"2") != 0)
105 DUNE_THROW(Dune::InvalidStateException,
"Currently only Gmsh mesh file format version 2 is supported!");
108 while (
line.find(
"$Nodes") == std::string::npos)
109 std::getline(gridFile,
line);
112 std::getline(gridFile,
line);
113 const auto numVertices = convertString<std::size_t>(
line);
114 gridVertices_.resize(numVertices);
116 std::getline(gridFile,
line);
117 std::size_t vertexCount = 0;
118 while (
line.find(
"$EndNodes") == std::string::npos)
121 std::istringstream stream(
line);
122 std::string buf; stream >> buf;
124 for (
auto& coord : v)
127 if (stream.fail()) DUNE_THROW(Dune::IOError,
"Could not read vertex coordinate");
131 gridVertices_[vertexCount++] = v;
132 std::getline(gridFile,
line);
136 if (vertexCount != numVertices)
137 DUNE_THROW(Dune::InvalidStateException,
"Couldn't find as many vertices as stated in the .msh file");
140 while(
line.find(
"$Elements") == std::string::npos)
141 std::getline(gridFile,
line);
144 std::getline(gridFile,
line);
145 const auto numElements = convertString<std::size_t>(
line);
148 std::array<std::size_t, numGrids> elementCount;
149 std::fill(elementCount.begin(), elementCount.end(), 0);
153 std::size_t elemCount = 0;
154 std::array<std::size_t, numGrids> gridVertexCount;
155 std::array<std::vector<GridIndexType>, numGrids> gridVertexMap;
156 std::array<std::vector<bool>, numGrids> idxIsAssigned;
157 std::fill(gridVertexCount.begin(), gridVertexCount.end(), 0);
158 std::fill(gridVertexMap.begin(), gridVertexMap.end(), std::vector<GridIndexType>(vertexCount));
159 std::fill(idxIsAssigned.begin(), idxIsAssigned.end(), std::vector<bool>(vertexCount,
false));
160 std::getline(gridFile,
line);
161 while (
line.find(
"$EndElements") == std::string::npos)
164 std::istringstream stream(
line);
166 std::vector<std::size_t> lineData;
167 while (stream >> buf) lineData.push_back(convertString<std::size_t>(buf));
168 assert(lineData.size() >= 4 &&
"Grid format erroneous or unsupported");
171 const auto gt = obtainGeometryType( lineData[1] );
172 const std::size_t physicalIndex = lineData[3];
173 const auto geoDim = gt.dim();
174 const bool isBoundarySeg = geoDim != bulkDim && physicalIndex < boundarySegThresh;
175 if (geoDim >= minGridDim-1)
178 if ((isBoundarySeg || geoDim == minGridDim-1))
180 const unsigned int nextLevelGridIdx = bulkDim-geoDim-1;
182 VertexIndexSet corners;
183 auto it = lineData.begin()+2+lineData[2]+1;
184 for (; it != lineData.end(); ++it)
189 if (!idxIsAssigned[nextLevelGridIdx][*it])
191 gridVertexMap[nextLevelGridIdx][*it] = gridVertexCount[nextLevelGridIdx]++;
192 idxIsAssigned[nextLevelGridIdx][*it] =
true;
193 vertexIndices_[nextLevelGridIdx].push_back(*it);
196 corners.push_back(gridVertexMap[nextLevelGridIdx][*it]);
200 boundaryMarkerMaps_[nextLevelGridIdx].push_back(physicalIndex);
201 boundarySegments_[nextLevelGridIdx].push_back(corners);
207 const unsigned int gridIdx = bulkDim-geoDim;
209 VertexIndexSet corners;
210 auto it = lineData.begin()+2+lineData[2]+1;
211 for (; it != lineData.end(); ++it)
216 if (!idxIsAssigned[gridIdx][*it])
218 gridVertexMap[gridIdx][*it] = gridVertexCount[gridIdx]++;
219 idxIsAssigned[gridIdx][*it] =
true;
220 vertexIndices_[gridIdx].push_back(*it);
223 corners.push_back(gridVertexMap[gridIdx][*it]);
227 if (geoDim > minGridDim)
229 const auto gridElemCount = elementData_[gridIdx].size();
230 const auto& embeddedVIndices = vertexIndices_[gridIdx+1];
231 const auto& embeddedIndicesAssigned = idxIsAssigned[gridIdx+1];
233 VertexIndexSet cornerIndicesGlobal(corners.size());
234 for (
unsigned int i = 0; i < corners.size(); ++i)
235 cornerIndicesGlobal[i] = vertexIndices_[gridIdx][corners[i]];
236 addEmbeddings(cornerIndicesGlobal, gridIdx, gridElemCount, embeddedVIndices, embeddedIndicesAssigned);
240 reorder(gt, corners);
243 elementMarkerMaps_[gridIdx].push_back(physicalIndex);
244 elementData_[gridIdx].emplace_back(ElementData({gt, corners}));
249 std::getline(gridFile,
line);
254 if (elemCount != numElements)
255 DUNE_THROW(Dune::InvalidStateException,
"Didn't read as many elements as stated in the .msh file");
259 std::cout <<
"Finished reading gmsh file" << std::endl;
260 for (std::size_t
id = 0;
id < numGrids; ++id)
262 std::cout << elementData_[id].size() <<
" "
263 << bulkDim-
id <<
"-dimensional elements comprising of "
264 << gridVertexCount[id] <<
" vertices";
265 if (
id < numGrids-1) std::cout <<
"," << std::endl;
267 std::cout <<
" have been read in " << watch.elapsed() <<
" seconds." << std::endl;