예제 #1
0
void MeshTools::Subdivision::tag_boundary_ghosts(MeshBase & mesh)
{
  MeshBase::element_iterator       el     = mesh.elements_begin();
  const MeshBase::element_iterator end_el = mesh.elements_end();
  for (; el != end_el; ++el)
    {
      Elem * elem = *el;
      libmesh_assert_equal_to(elem->type(), TRI3SUBDIVISION);

      Tri3Subdivision * sd_elem = static_cast<Tri3Subdivision *>(elem);
      for (unsigned int i = 0; i < elem->n_sides(); ++i)
        {
          if (elem->neighbor(i) == libmesh_nullptr)
            {
              sd_elem->set_ghost(true);
              // set all other neighbors to ghosts as well
              if (elem->neighbor(next[i]))
                {
                  Tri3Subdivision * nb = static_cast<Tri3Subdivision *>(elem->neighbor(next[i]));
                  nb->set_ghost(true);
                }
              if (elem->neighbor(prev[i]))
                {
                  Tri3Subdivision * nb = static_cast<Tri3Subdivision *>(elem->neighbor(prev[i]));
                  nb->set_ghost(true);
                }
            }
        }
    }
}
예제 #2
0
void findElementsIntersectedByPlane(const Plane & plane, const MeshBase & mesh, std::vector<const Elem *> & intersected_elems)
{
  // Loop over all elements to find elements intersected by the plane
  MeshBase::const_element_iterator el = mesh.elements_begin();
  const MeshBase::const_element_iterator end_el = mesh.elements_end();
  for (; el != end_el; ++el)
  {
    const Elem * elem = *el;
    bool intersected = false;

    // Check whether the first node of this element is below or above the plane
    const Node node0 = *elem->get_node(0);
    bool node0_above_plane = plane.above_surface(node0);

    // Loop over the rest of the nodes and check if any node is on the other side of the plane
    for (unsigned int i = 1; i < elem->n_nodes(); ++i)
    {
      const Node node = *elem->get_node(i);

      bool node_above_plane = plane.above_surface(node);
      if (node0_above_plane != node_above_plane)
        intersected = true;
    }

    if (intersected)
      intersected_elems.push_back(elem);
  }
}
예제 #3
0
void TopologyMap::fill(const MeshBase& mesh)
{
  // Populate the nodes map
  MeshBase::const_element_iterator
    it = mesh.elements_begin(),
    end = mesh.elements_end();
  for (; it != end; ++it)
    {
      const Elem* elem = *it;

      // We only need to add nodes which might be added during mesh
      // refinement; this means they need to be child nodes.
      if (!elem->has_children())
        continue;

      for (unsigned int c = 0; c != elem->n_children(); ++c)
        {
          if (elem->child(c)->is_remote())
            continue;

          for (unsigned int n = 0; n != elem->n_nodes_in_child(c); ++n)
            {
              const std::vector<std::pair<dof_id_type, dof_id_type> >
                bracketing_nodes = elem->bracketing_nodes(c,n);

              this->add_node(*elem->child(c)->get_node(n),
                             bracketing_nodes);
            }
        }
    }
}
예제 #4
0
void UCDIO::write_interior_elems(std::ostream& out_stream, const MeshBase& mesh)
{
  std::string type[] =
    { "edge",  "edge",  "edge",
      "tri",   "tri",
      "quad",  "quad",  "quad",
      "tet",   "tet",
      "hex",   "hex",   "hex",
      "prism", "prism", "prism",
      "pyramid" };

  MeshBase::const_element_iterator it  = mesh.elements_begin();
  const MeshBase::const_element_iterator end = mesh.elements_end();

  unsigned int e=1; // 1-based element number for UCD

  // Write element information
  for (; it != end; ++it)
    {
      libmesh_assert (out_stream.good());

      // PB: I believe these are the only supported ElemTypes.
      const ElemType etype = (*it)->type();
      if( (etype != TRI3) && (etype != QUAD4) &&
          (etype != TET4) && (etype != HEX8) &&
          (etype != PRISM6) && (etype != PYRAMID5) )
        libmesh_error_msg("Error: Unsupported ElemType for UCDIO.");

      out_stream << e++ << " 0 " << type[etype] << "\t";
      // (*it)->write_ucd_connectivity(out_stream);
      (*it)->write_connectivity(out_stream, UCD);
    }

  return;
}
예제 #5
0
void CentroidPartitioner::_do_partition (MeshBase & mesh,
                                         const unsigned int n)
{
  this->partition_range(mesh,
                        mesh.elements_begin(),
                        mesh.elements_end(),
                        n);
}
예제 #6
0
void MeshTools::Subdivision::prepare_subdivision_mesh(MeshBase & mesh, bool ghosted)
{
  mesh.prepare_for_use();

  // convert all mesh elements to subdivision elements
  all_subdivision(mesh);

  if (!ghosted)
    {
      // add the ghost elements for the boundaries
      add_boundary_ghosts(mesh);
    }
  else
    {
      // This assumes that the mesh already has the ghosts. Only tagging them is required here.
      tag_boundary_ghosts(mesh);
    }

  mesh.prepare_for_use();

  std::vector<std::vector<const Elem *> > nodes_to_elem_map;
  MeshTools::build_nodes_to_elem_map(mesh, nodes_to_elem_map);

  // compute the node valences
  MeshBase::const_node_iterator       nd     = mesh.nodes_begin();
  const MeshBase::const_node_iterator end_nd = mesh.nodes_end();
  for (; nd != end_nd; ++nd)
    {
      Node * node = *nd;
      std::vector<const Node *> neighbors;
      MeshTools::find_nodal_neighbors(mesh, *node, nodes_to_elem_map, neighbors);
      const unsigned int valence =
        cast_int<unsigned int>(neighbors.size());
      libmesh_assert_greater(valence, 1);
      node->set_valence(valence);
    }

  MeshBase::const_element_iterator       el     = mesh.elements_begin();
  const MeshBase::const_element_iterator end_el = mesh.elements_end();
  for (; el != end_el; ++el)
    {
      Tri3Subdivision * elem = dynamic_cast<Tri3Subdivision *>(*el);
      libmesh_assert(elem);
      if (!elem->is_ghost())
        elem->prepare_subdivision_properties();
    }
}
예제 #7
0
void Partitioner::single_partition (MeshBase & mesh)
{
  LOG_SCOPE("single_partition()","Partitioner");

  // Loop over all the elements and assign them to processor 0.
  MeshBase::element_iterator       elem_it  = mesh.elements_begin();
  const MeshBase::element_iterator elem_end = mesh.elements_end();

  for ( ; elem_it != elem_end; ++elem_it)
    (*elem_it)->processor_id() = 0;

  // For a single partition, all the nodes are on processor 0
  MeshBase::node_iterator       node_it  = mesh.nodes_begin();
  const MeshBase::node_iterator node_end = mesh.nodes_end();

  for ( ; node_it != node_end; ++node_it)
    (*node_it)->processor_id() = 0;
}
예제 #8
0
void CentroidPartitioner::compute_centroids (MeshBase& mesh)
{
  _elem_centroids.clear();
  _elem_centroids.reserve(mesh.n_elem());

  //   elem_iterator it(mesh.elements_begin());
  //   const elem_iterator it_end(mesh.elements_end());

  MeshBase::element_iterator       it     = mesh.elements_begin();
  const MeshBase::element_iterator it_end = mesh.elements_end();

  for (; it != it_end; ++it)
    {
      Elem* elem = *it;

      _elem_centroids.push_back(std::make_pair(elem->centroid(), elem));
    }
}
예제 #9
0
void Partitioner::single_partition (MeshBase & mesh)
{
  this->single_partition_range(mesh.elements_begin(),
                               mesh.elements_end());
}
예제 #10
0
void MeshTools::Subdivision::all_subdivision(MeshBase & mesh)
{
  std::vector<Elem *> new_elements;
  new_elements.reserve(mesh.n_elem());
  const bool mesh_has_boundary_data =
    (mesh.get_boundary_info().n_boundary_ids() > 0);

  std::vector<Elem *> new_boundary_elements;
  std::vector<short int> new_boundary_sides;
  std::vector<boundary_id_type> new_boundary_ids;

  MeshBase::const_element_iterator       el     = mesh.elements_begin();
  const MeshBase::const_element_iterator end_el = mesh.elements_end();
  for (; el != end_el; ++el)
    {
      const Elem * elem = *el;
      libmesh_assert_equal_to(elem->type(), TRI3);

      Elem * tri = new Tri3Subdivision;
      tri->set_id(elem->id());
      tri->subdomain_id() = elem->subdomain_id();
      tri->set_node(0) = (*el)->get_node(0);
      tri->set_node(1) = (*el)->get_node(1);
      tri->set_node(2) = (*el)->get_node(2);

      if (mesh_has_boundary_data)
        {
          for (unsigned short side = 0; side < elem->n_sides(); ++side)
            {
              const boundary_id_type boundary_id =
                mesh.get_boundary_info().boundary_id(elem, side);
              if (boundary_id != BoundaryInfo::invalid_id)
                {
                  // add the boundary id to the list of new boundary ids
                  new_boundary_ids.push_back(boundary_id);
                  new_boundary_elements.push_back(tri);
                  new_boundary_sides.push_back(side);
                }
            }

          // remove the original element from the BoundaryInfo structure
          mesh.get_boundary_info().remove(elem);
        }

      new_elements.push_back(tri);
      mesh.insert_elem(tri);
    }
  mesh.prepare_for_use();

  if (mesh_has_boundary_data)
    {
      // If the old mesh had boundary data, the new mesh better have some too.
      libmesh_assert_greater(new_boundary_elements.size(), 0);

      // We should also be sure that the lengths of the new boundary data vectors
      // are all the same.
      libmesh_assert_equal_to(new_boundary_sides.size(), new_boundary_elements.size());
      libmesh_assert_equal_to(new_boundary_sides.size(), new_boundary_ids.size());

      // Add the new boundary info to the mesh.
      for (unsigned int s = 0; s < new_boundary_elements.size(); ++s)
        mesh.get_boundary_info().add_side(new_boundary_elements[s],
                                          new_boundary_sides[s],
                                          new_boundary_ids[s]);
    }

  mesh.prepare_for_use();
}