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;