$extrastylesheet
face_tri3_subdivision.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 // C++ includes
00019 
00020 // Local includes
00021 #include "libmesh/face_tri3_subdivision.h"
00022 #include "libmesh/mesh_subdivision_support.h"
00023 
00024 namespace libMesh
00025 {
00026 
00027 
00028 
00029 // ------------------------------------------------------------
00030 // Tri3 subdivision class member functions
00031 
00032 Tri3Subdivision::Tri3Subdivision(Elem *p) : Tri3(p), _subdivision_updated(true)
00033 {
00034   if (p)
00035     {
00036       libmesh_assert_equal_to(p->type(), TRI3SUBDIVISION);
00037       Tri3Subdivision* sd_elem = static_cast<Tri3Subdivision*>(p);
00038       _is_ghost = sd_elem->is_ghost();
00039 
00040       if (!_is_ghost)
00041         {
00042           _ordered_nodes[0] = sd_elem->get_ordered_node(0);
00043           _ordered_nodes[1] = sd_elem->get_ordered_node(1);
00044           _ordered_nodes[2] = sd_elem->get_ordered_node(2);
00045         }
00046     }
00047 }
00048 
00049 
00050 void Tri3Subdivision::prepare_subdivision_properties()
00051 {
00052   /*
00053    * Find the index of the irregular vertex, if any.
00054    * The current implementation can only handle triangles with
00055    * no more than one irregular vertex. That is, a vertex with
00056    * valence != 6.
00057    */
00058   unsigned int irregular_idx = 0;
00059   for (unsigned int i = 0; i < 3; ++i)
00060     {
00061       if (this->get_node(i)->valence() != 6)
00062         {
00063           irregular_idx = i;
00064           if (this->get_node(MeshTools::Subdivision::next[i])->valence() != 6 || this->get_node(MeshTools::Subdivision::prev[i])->valence() != 6)
00065             libmesh_error_msg("Error: The mesh contains elements with more than one irregular vertex!");
00066         }
00067     }
00068 
00069   /*
00070    * Rotate ordered vertices such that ordered_nodes[0] is the
00071    * irregular vertex. Doing this once in advance lets the evaluation
00072    * of subdivision interpolation be much more efficient afterwards.
00073    */
00074   switch (irregular_idx)
00075     {
00076     case 0:
00077       _ordered_nodes[0] = this->get_node(0);
00078       _ordered_nodes[1] = this->get_node(1);
00079       _ordered_nodes[2] = this->get_node(2);
00080       break;
00081     case 1:
00082       _ordered_nodes[0] = this->get_node(1);
00083       _ordered_nodes[1] = this->get_node(2);
00084       _ordered_nodes[2] = this->get_node(0);
00085       break;
00086     case 2:
00087       _ordered_nodes[0] = this->get_node(2);
00088       _ordered_nodes[1] = this->get_node(0);
00089       _ordered_nodes[2] = this->get_node(1);
00090       break;
00091     default:
00092       libmesh_error_msg("Unrecognized irregular_idx = " << irregular_idx);
00093     }
00094 
00095   _subdivision_updated = true;
00096 }
00097 
00098 
00099 unsigned int Tri3Subdivision::local_node_number(unsigned int node_id) const
00100 {
00101   return (_nodes[0]->id() == node_id) ? 0 : ( (_nodes[1]->id() == node_id) ? 1 : ( (_nodes[2]->id() == node_id) ? 2 : 3 ) );
00102 }
00103 
00104 
00105 unsigned int Tri3Subdivision::get_ordered_valence(unsigned int node_id) const
00106 {
00107   libmesh_assert_less(node_id, n_neighbors());
00108   libmesh_assert(_subdivision_updated);
00109   return get_ordered_node(node_id)->valence();
00110 }
00111 
00112 
00113 Node* Tri3Subdivision::get_ordered_node(unsigned int node_id) const
00114 {
00115   libmesh_assert_less(node_id, 3);
00116   libmesh_assert(_subdivision_updated);
00117   return _ordered_nodes[node_id];
00118 }
00119 
00120 } // namespace libMesh