On 12/2/10 10:17 AM, Roy Stogner wrote:

On Thu, 2 Dec 2010, Boyce Griffith wrote:

If you agree, I'm happy to send a patch.

Thanks! That would be great.

OK --- attached is a patch. Most of it is just re-indenting. (I wasn't always careful about using tabs instead of spaces --- is there a convention that you all prefer to use?)

I believe that this patch replaces most calls to BoundaryInfo::boundary_id() in core libMesh with calls to BoundaryInfo::boundary_ids() followed by a loop over the IDs.

The implementation of MeshTools::Modification::change_boundary_id() is somewhat more complicated. I wasn't sure whether the boundary ID returned by BoundaryInfo::boundary_id() depended on the order in which the IDs are added to the side, so I took the somewhat paranoid approach of removing all of the IDs, running std::replace on the IDs, and then re-adding all of the IDs.

The only places where BoundaryInfo::boundary_id() is still used in the core library are in MeshGeneration, in which the use of boundary_id() appears correct, and the implementation of DivaIO, in which it seems that support for boundary IDs appears incomplete.

-- Boyce
Index: src/fe/fe_base.C
===================================================================
--- src/fe/fe_base.C    (revision 4126)
+++ src/fe/fe_base.C    (working copy)
@@ -2015,218 +2015,221 @@
       if (elem->neighbor(s))
         continue;
 
-      unsigned int boundary_id = mesh.boundary_info->boundary_id(elem, s);
-      PeriodicBoundary *periodic = boundaries.boundary(boundary_id);
-      if (periodic)
+      const std::vector<short int>& bc_ids = mesh.boundary_info->boundary_ids 
(elem, s);
+      for (std::vector<short int>::const_iterator id_it=bc_ids.begin(); 
id_it!=bc_ids.end(); ++id_it)
         {
-          // Get pointers to the element's neighbor.
-          const Elem* neigh = boundaries.neighbor(boundary_id, mesh, elem, s);
-
-          // h refinement constraints:
-          // constrain dofs shared between
-          // this element and ones as coarse
-          // as or coarser than this element.
-          if (neigh->level() <= elem->level()) 
+          const unsigned int boundary_id = *id_it;
+          PeriodicBoundary *periodic = boundaries.boundary(boundary_id);
+          if (periodic)
             {
-             unsigned int s_neigh = 
-                mesh.boundary_info->side_with_boundary_id (neigh, 
periodic->pairedboundary);
-              libmesh_assert(s_neigh != libMesh::invalid_uint);
+              // Get pointers to the element's neighbor.
+              const Elem* neigh = boundaries.neighbor(boundary_id, mesh, elem, 
s);
 
+              // h refinement constraints:
+              // constrain dofs shared between
+              // this element and ones as coarse
+              // as or coarser than this element.
+              if (neigh->level() <= elem->level()) 
+                {
+                 unsigned int s_neigh = 
+                    mesh.boundary_info->side_with_boundary_id (neigh, 
periodic->pairedboundary);
+                  libmesh_assert(s_neigh != libMesh::invalid_uint);
+
 #ifdef LIBMESH_ENABLE_AMR
-              // Find the minimum p level; we build the h constraint
-              // matrix with this and then constrain away all higher p
-              // DoFs.
-              libmesh_assert(neigh->active());
-              const unsigned int min_p_level =
-                std::min(elem->p_level(), neigh->p_level());
+                  // Find the minimum p level; we build the h constraint
+                  // matrix with this and then constrain away all higher p
+                  // DoFs.
+                  libmesh_assert(neigh->active());
+                  const unsigned int min_p_level =
+                    std::min(elem->p_level(), neigh->p_level());
 
-              // we may need to make the FE objects reinit with the
-              // minimum shared p_level
-              // FIXME - I hate using const_cast<> and avoiding
-              // accessor functions; there's got to be a
-              // better way to do this!
-              const unsigned int old_elem_level = elem->p_level();
-              if (old_elem_level != min_p_level)
-                (const_cast<Elem *>(elem))->hack_p_level(min_p_level);
-              const unsigned int old_neigh_level = neigh->p_level();
-              if (old_neigh_level != min_p_level)
-                (const_cast<Elem *>(neigh))->hack_p_level(min_p_level);
+                  // we may need to make the FE objects reinit with the
+                  // minimum shared p_level
+                  // FIXME - I hate using const_cast<> and avoiding
+                  // accessor functions; there's got to be a
+                  // better way to do this!
+                  const unsigned int old_elem_level = elem->p_level();
+                  if (old_elem_level != min_p_level)
+                    (const_cast<Elem *>(elem))->hack_p_level(min_p_level);
+                  const unsigned int old_neigh_level = neigh->p_level();
+                  if (old_neigh_level != min_p_level)
+                    (const_cast<Elem *>(neigh))->hack_p_level(min_p_level);
 #endif // #ifdef LIBMESH_ENABLE_AMR
 
-             my_fe->reinit(elem, s);
+                 my_fe->reinit(elem, s);
 
-             dof_map.dof_indices (elem, my_dof_indices,
-                                  variable_number);
-             dof_map.dof_indices (neigh, neigh_dof_indices,
-                                  variable_number);
+                 dof_map.dof_indices (elem, my_dof_indices,
+                                      variable_number);
+                 dof_map.dof_indices (neigh, neigh_dof_indices,
+                                      variable_number);
 
-             const unsigned int n_qp = my_qface.n_points();
+                 const unsigned int n_qp = my_qface.n_points();
 
-              // Translate the quadrature points over to the
-              // neighbor's boundary
-              std::vector<Point> neigh_point(q_point.size());
-              for (unsigned int i=0; i != neigh_point.size(); ++i)
-                neigh_point[i] = periodic->get_corresponding_pos(q_point[i]);
+                  // Translate the quadrature points over to the
+                  // neighbor's boundary
+                  std::vector<Point> neigh_point(q_point.size());
+                  for (unsigned int i=0; i != neigh_point.size(); ++i)
+                    neigh_point[i] = 
periodic->get_corresponding_pos(q_point[i]);
 
-             FEInterface::inverse_map (Dim, base_fe_type, neigh,
-                                        neigh_point, neigh_qface);
+                 FEInterface::inverse_map (Dim, base_fe_type, neigh,
+                                            neigh_point, neigh_qface);
 
-             neigh_fe->reinit(neigh, &neigh_qface);
+                 neigh_fe->reinit(neigh, &neigh_qface);
 
-             // We're only concerned with DOFs whose values (and/or first
-             // derivatives for C1 elements) are supported on side nodes
-             FEInterface::dofs_on_side(elem, Dim, base_fe_type, s, 
my_side_dofs);
-             FEInterface::dofs_on_side(neigh, Dim, base_fe_type, s_neigh, 
neigh_side_dofs);
+                 // We're only concerned with DOFs whose values (and/or first
+                 // derivatives for C1 elements) are supported on side nodes
+                 FEInterface::dofs_on_side(elem, Dim, base_fe_type, s, 
my_side_dofs);
+                 FEInterface::dofs_on_side(neigh, Dim, base_fe_type, s_neigh, 
neigh_side_dofs);
 
-              // We're done with functions that examine Elem::p_level(),
-              // so let's unhack those levels
+                  // We're done with functions that examine Elem::p_level(),
+                  // so let's unhack those levels
 #ifdef LIBMESH_ENABLE_AMR
-              if (elem->p_level() != old_elem_level)
-                (const_cast<Elem *>(elem))->hack_p_level(old_elem_level);
-              if (neigh->p_level() != old_neigh_level)
-                (const_cast<Elem *>(neigh))->hack_p_level(old_neigh_level);
+                  if (elem->p_level() != old_elem_level)
+                    (const_cast<Elem *>(elem))->hack_p_level(old_elem_level);
+                  if (neigh->p_level() != old_neigh_level)
+                    (const_cast<Elem *>(neigh))->hack_p_level(old_neigh_level);
 #endif // #ifdef LIBMESH_ENABLE_AMR
 
-             const unsigned int n_side_dofs = my_side_dofs.size();
-             libmesh_assert(n_side_dofs == neigh_side_dofs.size());
+                 const unsigned int n_side_dofs = my_side_dofs.size();
+                 libmesh_assert(n_side_dofs == neigh_side_dofs.size());
 
-             Ke.resize (n_side_dofs, n_side_dofs);
-             Ue.resize(n_side_dofs);
+                 Ke.resize (n_side_dofs, n_side_dofs);
+                 Ue.resize(n_side_dofs);
 
-             // Form the projection matrix, (inner product of fine basis
-             // functions against fine test functions)
-             for (unsigned int is = 0; is != n_side_dofs; ++is)
-               {
-                 const unsigned int i = my_side_dofs[is];
-                 for (unsigned int js = 0; js != n_side_dofs; ++js)
+                 // Form the projection matrix, (inner product of fine basis
+                 // functions against fine test functions)
+                 for (unsigned int is = 0; is != n_side_dofs; ++is)
                    {
-                     const unsigned int j = my_side_dofs[js];
-                     for (unsigned int qp = 0; qp != n_qp; ++qp)
-                        {
-                         Ke(is,js) += JxW[qp] * (phi[i][qp] * phi[j][qp]);
-                          if (cont != C_ZERO)
-                           Ke(is,js) += JxW[qp] * (((*dphi)[i][qp] *
-                                                  (*face_normals)[qp]) *
-                                                 ((*dphi)[j][qp] *
-                                                  (*face_normals)[qp]));
-                        }
-                   }
-               }
+                     const unsigned int i = my_side_dofs[is];
+                     for (unsigned int js = 0; js != n_side_dofs; ++js)
+                       {
+                         const unsigned int j = my_side_dofs[js];
+                         for (unsigned int qp = 0; qp != n_qp; ++qp)
+                            {
+                             Ke(is,js) += JxW[qp] * (phi[i][qp] * phi[j][qp]);
+                              if (cont != C_ZERO)
+                               Ke(is,js) += JxW[qp] * (((*dphi)[i][qp] *
+                                                      (*face_normals)[qp]) *
+                                                     ((*dphi)[j][qp] *
+                                                      (*face_normals)[qp]));
+                            }
+                       }
+                   }
 
-             // Form the right hand sides, (inner product of coarse basis
-             // functions against fine test functions)
-             for (unsigned int is = 0; is != n_side_dofs; ++is)
-               {
-                 const unsigned int i = neigh_side_dofs[is];
-                 Fe.resize (n_side_dofs);
-                 for (unsigned int js = 0; js != n_side_dofs; ++js)
-                   {
-                     const unsigned int j = my_side_dofs[js];
-                     for (unsigned int qp = 0; qp != n_qp; ++qp)
-                        {
-                         Fe(js) += JxW[qp] * (neigh_phi[i][qp] *
-                                              phi[j][qp]);
-                          if (cont != C_ZERO)
-                           Fe(js) += JxW[qp] * (((*neigh_dphi)[i][qp] *
-                                                 (*face_normals)[qp]) *
-                                                ((*dphi)[j][qp] *
-                                                 (*face_normals)[qp]));
-                        }
-                   }
-                 Ke.cholesky_solve(Fe, Ue[is]);
-               }
+                 // Form the right hand sides, (inner product of coarse basis
+                 // functions against fine test functions)
+                 for (unsigned int is = 0; is != n_side_dofs; ++is)
+                   {
+                     const unsigned int i = neigh_side_dofs[is];
+                     Fe.resize (n_side_dofs);
+                     for (unsigned int js = 0; js != n_side_dofs; ++js)
+                       {
+                         const unsigned int j = my_side_dofs[js];
+                         for (unsigned int qp = 0; qp != n_qp; ++qp)
+                            {
+                             Fe(js) += JxW[qp] * (neigh_phi[i][qp] *
+                                                  phi[j][qp]);
+                              if (cont != C_ZERO)
+                               Fe(js) += JxW[qp] * (((*neigh_dphi)[i][qp] *
+                                                     (*face_normals)[qp]) *
+                                                    ((*dphi)[j][qp] *
+                                                     (*face_normals)[qp]));
+                            }
+                       }
+                     Ke.cholesky_solve(Fe, Ue[is]);
+                   }
 
-              // Make sure we're not adding recursive constraints
-              // due to the redundancy in the way we add periodic
-              // boundary constraints
-              std::vector<bool> recursive_constraint(n_side_dofs, false);
+                  // Make sure we're not adding recursive constraints
+                  // due to the redundancy in the way we add periodic
+                  // boundary constraints
+                  std::vector<bool> recursive_constraint(n_side_dofs, false);
 
-             for (unsigned int is = 0; is != n_side_dofs; ++is)
-               {
-                 const unsigned int i = neigh_side_dofs[is];
-                 const unsigned int their_dof_g = neigh_dof_indices[i];
-                  libmesh_assert(their_dof_g != DofObject::invalid_id);
+                 for (unsigned int is = 0; is != n_side_dofs; ++is)
+                   {
+                     const unsigned int i = neigh_side_dofs[is];
+                     const unsigned int their_dof_g = neigh_dof_indices[i];
+                      libmesh_assert(their_dof_g != DofObject::invalid_id);
 
-                  if (!dof_map.is_constrained_dof(their_dof_g))
-                    continue;
+                      if (!dof_map.is_constrained_dof(their_dof_g))
+                        continue;
 
-                  DofConstraintRow& their_constraint_row =
-                    constraints[their_dof_g];
+                      DofConstraintRow& their_constraint_row =
+                        constraints[their_dof_g];
 
+                     for (unsigned int js = 0; js != n_side_dofs; ++js)
+                       {
+                         const unsigned int j = my_side_dofs[js];
+                         const unsigned int my_dof_g = my_dof_indices[j];
+                          libmesh_assert(my_dof_g != DofObject::invalid_id);
+
+                          if (their_constraint_row.count(my_dof_g))
+                            recursive_constraint[js] = true;
+                       }
+                    }
                  for (unsigned int js = 0; js != n_side_dofs; ++js)
                    {
+                      if (recursive_constraint[js])
+                        continue;
+
                      const unsigned int j = my_side_dofs[js];
                      const unsigned int my_dof_g = my_dof_indices[j];
                       libmesh_assert(my_dof_g != DofObject::invalid_id);
 
-                      if (their_constraint_row.count(my_dof_g))
-                        recursive_constraint[js] = true;
-                   }
-                }
-             for (unsigned int js = 0; js != n_side_dofs; ++js)
-               {
-                  if (recursive_constraint[js])
-                    continue;
+                      if (dof_map.is_constrained_dof(my_dof_g))
+                        continue;
 
-                 const unsigned int j = my_side_dofs[js];
-                 const unsigned int my_dof_g = my_dof_indices[j];
-                  libmesh_assert(my_dof_g != DofObject::invalid_id);
+                     for (unsigned int is = 0; is != n_side_dofs; ++is)
+                       {
+                         const unsigned int i = neigh_side_dofs[is];
+                         const unsigned int their_dof_g = neigh_dof_indices[i];
+                          libmesh_assert(their_dof_g != DofObject::invalid_id);
 
-                  if (dof_map.is_constrained_dof(my_dof_g))
-                    continue;
+                         const Real their_dof_value = Ue[is](js);
+                         if (their_dof_g == my_dof_g)
+                           {
+                             libmesh_assert(std::abs(their_dof_value-1.) < 
1.e-5);
+                             for (unsigned int k = 0; k != n_side_dofs; ++k)
+                               libmesh_assert(k == is || std::abs(Ue[k](js)) < 
1.e-5);
+                             continue;
+                           }
+                         if (std::abs(their_dof_value) < 1.e-5)
+                           continue;
 
-                 for (unsigned int is = 0; is != n_side_dofs; ++is)
-                   {
-                     const unsigned int i = neigh_side_dofs[is];
-                     const unsigned int their_dof_g = neigh_dof_indices[i];
-                      libmesh_assert(their_dof_g != DofObject::invalid_id);
+                         // since we may be running this method concurretly 
+                         // on multiple threads we need to acquire a lock 
+                         // before modifying the shared constraint_row object.
+                         {
+                           Threads::spin_mutex::scoped_lock 
lock(Threads::spin_mtx);
 
-                     const Real their_dof_value = Ue[is](js);
-                     if (their_dof_g == my_dof_g)
-                       {
-                         libmesh_assert(std::abs(their_dof_value-1.) < 1.e-5);
-                         for (unsigned int k = 0; k != n_side_dofs; ++k)
-                           libmesh_assert(k == is || std::abs(Ue[k](js)) < 
1.e-5);
-                         continue;
+                           DofConstraintRow& constraint_row =
+                             constraints[my_dof_g];
+
+                           constraint_row.insert(std::make_pair(their_dof_g,
+                                                                
their_dof_value));
+                         }
                        }
-                     if (std::abs(their_dof_value) < 1.e-5)
-                       continue;
-
-                     // since we may be running this method concurretly 
-                     // on multiple threads we need to acquire a lock 
-                     // before modifying the shared constraint_row object.
-                     {
-                       Threads::spin_mutex::scoped_lock 
lock(Threads::spin_mtx);
-
-                       DofConstraintRow& constraint_row =
-                         constraints[my_dof_g];
-
-                       constraint_row.insert(std::make_pair(their_dof_g,
-                                                            their_dof_value));
-                     }
-                   }
+                   }
                }
-           }
-          // p refinement constraints:
-          // constrain dofs shared between
-          // active elements and neighbors with
-          // lower polynomial degrees
+              // p refinement constraints:
+              // constrain dofs shared between
+              // active elements and neighbors with
+              // lower polynomial degrees
 #ifdef LIBMESH_ENABLE_AMR
-          const unsigned int min_p_level =
-            neigh->min_p_level_by_neighbor(elem, elem->p_level());
-          if (min_p_level < elem->p_level())
-            {
-              // Adaptive p refinement of non-hierarchic bases will
-              // require more coding
-              libmesh_assert(my_fe->is_hierarchic());
-              dof_map.constrain_p_dofs(variable_number, elem,
-                                       s, min_p_level);
+              const unsigned int min_p_level =
+                neigh->min_p_level_by_neighbor(elem, elem->p_level());
+              if (min_p_level < elem->p_level())
+                {
+                  // Adaptive p refinement of non-hierarchic bases will
+                  // require more coding
+                  libmesh_assert(my_fe->is_hierarchic());
+                  dof_map.constrain_p_dofs(variable_number, elem,
+                                           s, min_p_level);
+                }
+#endif // #ifdef LIBMESH_ENABLE_AMR
             }
-#endif // #ifdef LIBMESH_ENABLE_AMR
         }
     }
 }
-
 #endif // LIBMESH_ENABLE_PERIODIC
 
 
Index: src/mesh/mesh_communication.C
===================================================================
--- src/mesh/mesh_communication.C       (revision 4126)
+++ src/mesh/mesh_communication.C       (working copy)
@@ -361,13 +361,19 @@
                if ((*elem_it)->level() == 0)
                  for (unsigned int s=0; s<(*elem_it)->n_sides(); s++)
                    if ((*elem_it)->neighbor(s) == NULL)
-                     if (mesh.boundary_info->boundary_id (*elem_it, s) !=
-                         mesh.boundary_info->invalid_id)
-                       {
-                         element_bcs_sent[pid].push_back ((*elem_it)->id());
-                         element_bcs_sent[pid].push_back (s);
-                         element_bcs_sent[pid].push_back 
(mesh.boundary_info->boundary_id (*elem_it, s));
-                       }
+                      {
+                        const std::vector<short int>& bc_ids = 
mesh.boundary_info->boundary_ids(*elem_it, s);
+                        for (std::vector<short int>::const_iterator 
id_it=bc_ids.begin(); id_it!=bc_ids.end(); ++id_it)
+                          {
+                            const short int bc_id = *id_it;
+                           if (bc_id != mesh.boundary_info->invalid_id)
+                             {
+                               element_bcs_sent[pid].push_back 
((*elem_it)->id());
+                               element_bcs_sent[pid].push_back (s);
+                               element_bcs_sent[pid].push_back (bc_id);
+                             }
+                          }
+                      }
              }
            
            // the packed connectivity size to send to this processor
@@ -1077,13 +1083,19 @@
                if ((*elem_it)->level() == 0)
                  for (unsigned int s=0; s<(*elem_it)->n_sides(); s++)
                    if ((*elem_it)->neighbor(s) == NULL)
-                     if (mesh.boundary_info->boundary_id (*elem_it, s) !=
-                         mesh.boundary_info->invalid_id)
-                       {
-                         element_bcs_sent.push_back ((*elem_it)->id());
-                         element_bcs_sent.push_back (s);
-                         element_bcs_sent.push_back 
(mesh.boundary_info->boundary_id (*elem_it, s));
-                       }
+                      {
+                        const std::vector<short int>& bc_ids = 
mesh.boundary_info->boundary_ids(*elem_it, s);
+                        for (std::vector<short int>::const_iterator 
id_it=bc_ids.begin(); id_it!=bc_ids.end(); ++id_it)
+                          {
+                            const short int bc_id = *id_it;
+                           if (bc_id != mesh.boundary_info->invalid_id)
+                             {
+                               element_bcs_sent.push_back ((*elem_it)->id());
+                               element_bcs_sent.push_back (s);
+                               element_bcs_sent.push_back (bc_id);
+                             }
+                          }
+                      }
              }
            element_neighbors_sent[n_elem_replies_sent].push_back 
(dest_pid_idx);
            elements_to_send.clear();
Index: src/mesh/unstructured_mesh.C
===================================================================
--- src/mesh/unstructured_mesh.C        (revision 4126)
+++ src/mesh/unstructured_mesh.C        (working copy)
@@ -911,11 +911,17 @@
       // Maybe add boundary conditions for this element
       for (unsigned int s=0; s<old_elem->n_sides(); s++)
        if (old_elem->neighbor(s) == NULL)
-         if (this->boundary_info->boundary_id (old_elem, s) !=
-             this->boundary_info->invalid_id)
-           new_mesh.boundary_info->add_side (new_elem,
-                                            s,
-                                            this->boundary_info->boundary_id 
(old_elem, s));
+          {
+            const std::vector<short int>& bc_ids = 
this->boundary_info->boundary_ids(old_elem, s);
+            for (std::vector<short int>::const_iterator id_it=bc_ids.begin(); 
id_it!=bc_ids.end(); ++id_it)
+              {
+                const short int bc_id = *id_it;
+               if (bc_id != this->boundary_info->invalid_id)
+               new_mesh.boundary_info->add_side (new_elem,
+                                                 s,
+                                                 bc_id);
+              }
+          }
     } // end loop over elements
   
 
Index: src/mesh/mesh_modification.C
===================================================================
--- src/mesh/mesh_modification.C        (revision 4126)
+++ src/mesh/mesh_modification.C        (working copy)
@@ -837,97 +837,101 @@
              {
                for (unsigned int sn=0; sn<(*el)->n_sides(); ++sn)
                  {
-                   short int b_id = mesh.boundary_info->boundary_id(*el, sn);
+                    const std::vector<short int>& bc_ids = 
mesh.boundary_info->boundary_ids(*el, sn);
+                    for (std::vector<short int>::const_iterator 
id_it=bc_ids.begin(); id_it!=bc_ids.end(); ++id_it)
+                      {
+                        const short int b_id = *id_it;
 
-                   if (b_id != BoundaryInfo::invalid_id)
-                     {
-                       // Add the boundary ID to the list of new boundary ids
-                       new_bndry_ids.push_back(b_id);
+                       if (b_id != BoundaryInfo::invalid_id)
+                         {
+                           // Add the boundary ID to the list of new boundary 
ids
+                           new_bndry_ids.push_back(b_id);
                          
-                       // Convert the boundary side information of the old 
element to
-                       // boundary side information for the new element.
-                       if (!edge_swap)
-                         {
-                           switch (sn)
+                           // Convert the boundary side information of the old 
element to
+                           // boundary side information for the new element.
+                           if (!edge_swap)
                              {
-                             case 0:
-                               {
-                                 // New boundary side is Tri 0, side 0
-                                 new_bndry_elements.push_back(tri0);
-                                 new_bndry_sides.push_back(0);
-                                 break;
-                               }
-                             case 1:
-                               {
-                                 // New boundary side is Tri 0, side 1
-                                 new_bndry_elements.push_back(tri0);
-                                 new_bndry_sides.push_back(1);
-                                 break;
-                               }
-                             case 2:
-                               {
-                                 // New boundary side is Tri 1, side 1
-                                 new_bndry_elements.push_back(tri1);
-                                 new_bndry_sides.push_back(1);
-                                 break;
-                               }
-                             case 3:
-                               {
-                                 // New boundary side is Tri 1, side 2
-                                 new_bndry_elements.push_back(tri1);
-                                 new_bndry_sides.push_back(2);
-                                 break;
-                               }
+                               switch (sn)
+                                 {
+                                 case 0:
+                                   {
+                                     // New boundary side is Tri 0, side 0
+                                     new_bndry_elements.push_back(tri0);
+                                     new_bndry_sides.push_back(0);
+                                     break;
+                                   }
+                                 case 1:
+                                   {
+                                     // New boundary side is Tri 0, side 1
+                                     new_bndry_elements.push_back(tri0);
+                                     new_bndry_sides.push_back(1);
+                                     break;
+                                   }
+                                 case 2:
+                                   {
+                                     // New boundary side is Tri 1, side 1
+                                     new_bndry_elements.push_back(tri1);
+                                     new_bndry_sides.push_back(1);
+                                     break;
+                                   }
+                                 case 3:
+                                   {
+                                     // New boundary side is Tri 1, side 2
+                                     new_bndry_elements.push_back(tri1);
+                                     new_bndry_sides.push_back(2);
+                                     break;
+                                   }
 
-                             default:
-                               {
-                                 libMesh::err << "Quad4/8/9 cannot have more 
than 4 sides." << std::endl;
-                                 libmesh_error();
-                               }
+                                 default:
+                                   {
+                                     libMesh::err << "Quad4/8/9 cannot have 
more than 4 sides." << std::endl;
+                                     libmesh_error();
+                                   }
+                                 }
                              }
-                         }
 
-                       else // edge_swap==true
-                         {
-                           switch (sn)
+                           else // edge_swap==true
                              {
-                             case 0:
-                               {
-                                 // New boundary side is Tri 0, side 0
-                                 new_bndry_elements.push_back(tri0);
-                                 new_bndry_sides.push_back(0);
-                                 break;
-                               }
-                             case 1:
-                               {
-                                 // New boundary side is Tri 1, side 0
-                                 new_bndry_elements.push_back(tri1);
-                                 new_bndry_sides.push_back(0);
-                                 break;
-                               }
-                             case 2:
-                               {
-                                 // New boundary side is Tri 1, side 1
-                                 new_bndry_elements.push_back(tri1);
-                                 new_bndry_sides.push_back(1);
-                                 break;
-                               }
-                             case 3:
-                               {
-                                 // New boundary side is Tri 0, side 2
-                                 new_bndry_elements.push_back(tri0);
-                                 new_bndry_sides.push_back(2);
-                                 break;
-                               }
+                               switch (sn)
+                                 {
+                                 case 0:
+                                   {
+                                     // New boundary side is Tri 0, side 0
+                                     new_bndry_elements.push_back(tri0);
+                                     new_bndry_sides.push_back(0);
+                                     break;
+                                   }
+                                 case 1:
+                                   {
+                                     // New boundary side is Tri 1, side 0
+                                     new_bndry_elements.push_back(tri1);
+                                     new_bndry_sides.push_back(0);
+                                     break;
+                                   }
+                                 case 2:
+                                   {
+                                     // New boundary side is Tri 1, side 1
+                                     new_bndry_elements.push_back(tri1);
+                                     new_bndry_sides.push_back(1);
+                                     break;
+                                   }
+                                 case 3:
+                                   {
+                                     // New boundary side is Tri 0, side 2
+                                     new_bndry_elements.push_back(tri0);
+                                     new_bndry_sides.push_back(2);
+                                     break;
+                                   }
 
-                             default:
-                               {
-                                 libMesh::err << "Quad4/8/9 cannot have more 
than 4 sides." << std::endl;
-                                 libmesh_error();
-                               }
-                             }
-                         } // end edge_swap==true
-                     } // end if (b_id != BoundaryInfo::invalid_id)
+                                 default:
+                                   {
+                                     libMesh::err << "Quad4/8/9 cannot have 
more than 4 sides." << std::endl;
+                                     libmesh_error();
+                                   }
+                                 }
+                             } // end edge_swap==true
+                         } // end if (b_id != BoundaryInfo::invalid_id)
+                      } // end for loop over boundary IDs
                  } // end for loop over sides
 
                // Remove the original element from the BoundaryInfo structure.
@@ -1221,13 +1225,17 @@
        for (unsigned int s=0; s<elem->n_sides(); s++)
            if (elem->neighbor(s) == NULL)
              {
-               short int bc_id = mesh.boundary_info->boundary_id (elem,s);
+                const std::vector<short int>& bc_ids = 
mesh.boundary_info->boundary_ids(elem,s);
+                for (std::vector<short int>::const_iterator 
id_it=bc_ids.begin(); id_it!=bc_ids.end(); ++id_it)
+                  {
+                   const short int bc_id = *id_it;
 
-               if (bc_id != BoundaryInfo::invalid_id)
-                 {
-                   saved_boundary_elements.push_back(copy);
-                   saved_bc_ids.push_back(bc_id);
-                   saved_bc_sides.push_back(s);
+                   if (bc_id != BoundaryInfo::invalid_id)
+                     {
+                       saved_boundary_elements.push_back(copy);
+                       saved_bc_ids.push_back(bc_id);
+                       saved_bc_sides.push_back(s);
+                      }
                  }
              }
 
@@ -1289,11 +1297,16 @@
       Elem *elem = *el;
       unsigned int n_sides = elem->n_sides();
       for (unsigned int s=0; s != n_sides; ++s)
-        if (mesh.boundary_info->boundary_id(elem, s) == old_id)
-          {
-            mesh.boundary_info->remove_side(elem, s, old_id);
-            mesh.boundary_info->add_side(elem, s, new_id);
-          }
+        {
+          const std::vector<short int>& old_ids = 
mesh.boundary_info->boundary_ids(elem, s);
+          if (std::find(old_ids.begin(), old_ids.end(), old_id) != 
old_ids.end())
+            {
+              std::vector<short int> new_ids(old_ids);
+              std::replace(new_ids.begin(), new_ids.end(), old_id, new_id);
+              mesh.boundary_info->remove_side(elem, s);
+              mesh.boundary_info->add_side(elem, s, new_ids);
+            }
+        }
     }
 }
 
------------------------------------------------------------------------------
Increase Visibility of Your 3D Game App & Earn a Chance To Win $500!
Tap into the largest installed PC base & get more eyes on your game by
optimizing for Intel(R) Graphics Technology. Get started today with the
Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs.
http://p.sf.net/sfu/intelisp-dev2dev
_______________________________________________
Libmesh-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libmesh-devel

Reply via email to