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();
  }
示例#2
0
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);
}