void TriangleWrapper::copy_tri_to_mesh(const triangulateio& triangle_data_input, UnstructuredMesh& mesh_output, const ElemType type) { // Transfer the information into the LibMesh mesh. mesh_output.clear(); // Make sure the new Mesh will be 2D mesh_output.set_mesh_dimension(2); // Node information for (int i=0, c=0; c<triangle_data_input.numberofpoints; i+=2, ++c) { // Specify ID when adding point, otherwise, if this is ParallelMesh, // it might add points with a non-sequential numbering... mesh_output.add_point( Point(triangle_data_input.pointlist[i], triangle_data_input.pointlist[i+1]), /*id=*/c); } // Element information for (int i=0; i<triangle_data_input.numberoftriangles; ++i) { switch (type) { case TRI3: { Elem* elem = mesh_output.add_elem (new Tri3); for (unsigned int n=0; n<3; ++n) elem->set_node(n) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*3 + n]); break; } case TRI6: { Elem* elem = mesh_output.add_elem (new Tri6); // Triangle number TRI6 nodes in a different way to libMesh elem->set_node(0) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 0]); elem->set_node(1) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 1]); elem->set_node(2) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 2]); elem->set_node(3) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 5]); elem->set_node(4) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 3]); elem->set_node(5) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 4]); break; } default: { libMesh::err << "ERROR: Unrecognized triangular element type." << std::endl; libmesh_error(); } } } // Note: If the input mesh was a parallel one, calling // prepare_for_use() now will re-parallelize it by a call to // delete_remote_elements()... We do not actually want to // reparallelize it here though: the triangulate() function may // still do some Mesh smoothing. The main thing needed (for // smoothing) is the neighbor information, so let's just find // neighbors... //mesh_output.prepare_for_use(/*skip_renumber =*/false); mesh_output.find_neighbors(); }
void UnstructuredMesh::create_submesh (UnstructuredMesh & new_mesh, const_element_iterator & it, const const_element_iterator & it_end) const { // Just in case the subdomain_mesh already has some information // in it, get rid of it. new_mesh.clear(); // If we're not serial, our submesh isn't either. // There are no remote elements to delete on an empty mesh, but // calling the method to do so marks the mesh as parallel. if (!this->is_serial()) new_mesh.delete_remote_elements(); // Fail if (*this == new_mesh), we cannot create a submesh inside ourself! // This may happen if the user accidently passes the original mesh into // this function! We will check this by making sure we did not just // clear ourself. libmesh_assert_not_equal_to (this->n_nodes(), 0); libmesh_assert_not_equal_to (this->n_elem(), 0); // Container to catch boundary IDs handed back by BoundaryInfo std::vector<boundary_id_type> bc_ids; for (; it != it_end; ++it) { const Elem * old_elem = *it; // Add an equivalent element type to the new_mesh. // Copy ids for this element. Elem * new_elem = Elem::build(old_elem->type()).release(); new_elem->set_id() = old_elem->id(); #ifdef LIBMESH_ENABLE_UNIQUE_ID new_elem->set_unique_id() = old_elem->unique_id(); #endif new_elem->subdomain_id() = old_elem->subdomain_id(); new_elem->processor_id() = old_elem->processor_id(); new_mesh.add_elem (new_elem); libmesh_assert(new_elem); // Loop over the nodes on this element. for (unsigned int n=0; n<old_elem->n_nodes(); n++) { const dof_id_type this_node_id = old_elem->node_id(n); // Add this node to the new mesh if it's not there already if (!new_mesh.query_node_ptr(this_node_id)) { #ifdef LIBMESH_ENABLE_UNIQUE_ID Node *newn = #endif new_mesh.add_point (old_elem->point(n), this_node_id, old_elem->node_ptr(n)->processor_id()); #ifdef LIBMESH_ENABLE_UNIQUE_ID newn->set_unique_id() = old_elem->node_ptr(n)->unique_id(); #endif } // Define this element's connectivity on the new mesh new_elem->set_node(n) = new_mesh.node_ptr(this_node_id); } // Maybe add boundary conditions for this element for (unsigned short s=0; s<old_elem->n_sides(); s++) { this->get_boundary_info().boundary_ids(old_elem, s, bc_ids); new_mesh.get_boundary_info().add_side (new_elem, s, bc_ids); } } // end loop over elements // Prepare the new_mesh for use new_mesh.prepare_for_use(/*skip_renumber =*/false); }