void ProcessDetectSurf::Process() { if (m_mesh->m_expDim > 2) { cerr << "Surface detection only implemented for 2D meshes" << endl; return; } int i, j; string surf = m_config["vol"].as<string>(); // Obtain vector of surface IDs from string. vector<unsigned int> surfs; if (surf != "-1") { ParseUtils::GenerateSeqVector(surf.c_str(), surfs); sort(surfs.begin(), surfs.end()); } // If we're running in verbose mode print out a list of surfaces. if (m_mesh->m_verbose) { cout << "ProcessDetectSurf: detecting surfaces"; if (surfs.size() > 0) { cout << " for surface" << (surfs.size() == 1 ? "" : "s") << " " << surf << endl; } } vector<ElementSharedPtr> &el = m_mesh->m_element[m_mesh->m_expDim]; map<int, EdgeInfo> edgeCount; set<int> doneIds; map<int, int> idMap; // Iterate over list of surface elements. for (i = 0; i < el.size(); ++i) { // Work out whether this lies on our surface of interest. if (surfs.size() > 0) { vector<int> inter, tags = el[i]->GetTagList(); sort(tags.begin(), tags.end()); set_intersection(surfs.begin(), surfs.end(), tags .begin(), tags .end(), back_inserter(inter)); // It doesn't continue to next element. if (inter.size() != 1) { continue; } } // List all edges. ElementSharedPtr elmt = el[i]; for (j = 0; j < elmt->GetEdgeCount(); ++j) { EdgeSharedPtr e = elmt->GetEdge(j); int eId = e->m_id; edgeCount[eId].count++; edgeCount[eId].edge = e; } doneIds.insert(elmt->GetId()); ASSERTL0(idMap.count(elmt->GetId()) == 0, "Shouldn't happen"); idMap[elmt->GetId()] = i; } CompositeMap::iterator cIt; unsigned int maxId = 0; for (cIt = m_mesh->m_composite.begin(); cIt != m_mesh->m_composite.end(); ++cIt) { maxId = std::max(cIt->first, maxId); } ++maxId; map<int, EdgeInfo>::iterator eIt; while (doneIds.size() > 0) { ElementSharedPtr start = m_mesh->m_element[m_mesh->m_expDim][idMap[*(doneIds.begin())]]; vector<ElementSharedPtr> block; FindContiguousSurface(start, doneIds, block); ASSERTL0(block.size() > 0, "Contiguous block not found"); // Loop over all edges in block. for (i = 0; i < block.size(); ++i) { // Find edge info. ElementSharedPtr elmt = block[i]; for (j = 0; j < elmt->GetEdgeCount(); ++j) { eIt = edgeCount.find(elmt->GetEdge(j)->m_id); ASSERTL0(eIt != edgeCount.end(), "Couldn't find edge"); eIt->second.group = maxId; } } ++maxId; } for (eIt = edgeCount.begin(); eIt != edgeCount.end(); ++eIt) { if (eIt->second.count > 1) { continue; } unsigned int compId = eIt->second.group; CompositeMap::iterator cIt = m_mesh->m_composite.find(compId); if (cIt == m_mesh->m_composite.end()) { CompositeSharedPtr comp(new Composite()); comp->m_id = compId; comp->m_tag = "E"; cIt = m_mesh->m_composite.insert(std::make_pair(compId, comp)).first; } vector<int> tags(1); tags[0] = compId; vector<NodeSharedPtr> nodeList(2); nodeList[0] = eIt->second.edge->m_n1; nodeList[1] = eIt->second.edge->m_n2; ElmtConfig conf(LibUtilities::eSegment, 1, false, false); ElementSharedPtr elmt = GetElementFactory(). CreateInstance(LibUtilities::eSegment,conf,nodeList,tags); elmt->SetEdgeLink(eIt->second.edge); cIt->second->m_items.push_back(elmt); } }
/** * Gmsh file contains a list of nodes and their coordinates, along with * a list of elements and those nodes which define them. We read in and * store the list of nodes in #m_node and store the list of elements in * #m_element. Each new element is supplied with a list of entries from * #m_node which defines the element. Finally some mesh statistics are * printed. * * @param pFilename Filename of Gmsh file to read. */ void InputVtk::Process() { if (m_mesh->m_verbose) { cout << "InputVtk: Start reading file..." << endl; } vtkPolyDataReader *vtkMeshReader = vtkPolyDataReader::New(); vtkMeshReader->SetFileName(m_config["infile"].as<string>().c_str()); vtkMeshReader->Update(); vtkPolyData *vtkMesh = vtkMeshReader->GetOutput(); vtkPoints *vtkPoints = vtkMesh->GetPoints(); const int numCellTypes = 3; vtkCellArray* vtkCells[numCellTypes]; LibUtilities::ShapeType vtkCellTypes[numCellTypes]; int vtkNumPoints[numCellTypes]; vtkCells[0] = vtkMesh->GetPolys(); vtkCells[1] = vtkMesh->GetStrips(); vtkCells[2] = vtkMesh->GetLines(); vtkCellTypes[0] = LibUtilities::eTriangle; vtkCellTypes[1] = LibUtilities::eTriangle; vtkCellTypes[2] = LibUtilities::eSegment; vtkNumPoints[0] = 3; vtkNumPoints[1] = 3; vtkNumPoints[2] = 2; vtkIdType npts; vtkIdType *pts = 0; double p[3]; for (int i = 0; i < vtkPoints->GetNumberOfPoints(); ++i) { vtkPoints->GetPoint(i, p); if ((p[0] * p[0]) > 0.000001 && m_mesh->m_spaceDim < 1) { m_mesh->m_spaceDim = 1; } if ((p[1] * p[1]) > 0.000001 && m_mesh->m_spaceDim < 2) { m_mesh->m_spaceDim = 2; } if ((p[2] * p[2]) > 0.000001 && m_mesh->m_spaceDim < 3) { m_mesh->m_spaceDim = 3; } m_mesh->m_node.push_back(boost::shared_ptr<Node>(new Node(i, p[0], p[1], p[2]))); } for (int c = 0; c < numCellTypes; ++c) { vtkCells[c]->InitTraversal(); for (int i = 0; vtkCells[c]->GetNextCell(npts, pts); ++i) { for (int j = 0; j < npts - vtkNumPoints[c] + 1; ++j) { // Create element tags vector<int> tags; tags.push_back(0); // composite tags.push_back(vtkCellTypes[c]); // element type // Read element node list vector<NodeSharedPtr> nodeList; for (int k = j; k < j + vtkNumPoints[c]; ++k) { nodeList.push_back(m_mesh->m_node[pts[k]]); } // Create element ElmtConfig conf(vtkCellTypes[c],1,false,false); ElementSharedPtr E = GetElementFactory(). CreateInstance(vtkCellTypes[c], conf,nodeList,tags); // Determine mesh expansion dimension if (E->GetDim() > m_mesh->m_expDim) { m_mesh->m_expDim = E->GetDim(); } m_mesh->m_element[E->GetDim()].push_back(E); } } } ProcessVertices(); ProcessEdges(); ProcessFaces(); ProcessElements(); ProcessComposites(); }