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(); }