$extrastylesheet
cell_prism15.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 
00019 // C++ includes
00020 
00021 // Local includes
00022 #include "libmesh/side.h"
00023 #include "libmesh/cell_prism15.h"
00024 #include "libmesh/edge_edge3.h"
00025 #include "libmesh/face_quad8.h"
00026 #include "libmesh/face_tri6.h"
00027 
00028 namespace libMesh
00029 {
00030 
00031 
00032 
00033 // ------------------------------------------------------------
00034 // Prism15 class static member initializations
00035 const unsigned int Prism15::side_nodes_map[5][8] =
00036   {
00037     {0, 2, 1,  8,  7,  6, 99, 99}, // Side 0
00038     {0, 1, 4,  3,  6, 10, 12,  9}, // Side 1
00039     {1, 2, 5,  4,  7, 11, 13, 10}, // Side 2
00040     {2, 0, 3,  5,  8,  9, 14, 11}, // Side 3
00041     {3, 4, 5, 12, 13, 14, 99, 99}  // Side 4
00042   };
00043 
00044 const unsigned int Prism15::edge_nodes_map[9][3] =
00045   {
00046     {0, 1, 6},  // Side 0
00047     {1, 2, 7},  // Side 1
00048     {0, 2, 8},  // Side 2
00049     {0, 3, 9},  // Side 3
00050     {1, 4, 10}, // Side 4
00051     {2, 5, 11}, // Side 5
00052     {3, 4, 12}, // Side 6
00053     {4, 5, 13}, // Side 7
00054     {3, 5, 14}  // Side 8
00055   };
00056 
00057 
00058 // ------------------------------------------------------------
00059 // Prism15 class member functions
00060 
00061 bool Prism15::is_vertex(const unsigned int i) const
00062 {
00063   if (i < 6)
00064     return true;
00065   return false;
00066 }
00067 
00068 bool Prism15::is_edge(const unsigned int i) const
00069 {
00070   if (i < 6)
00071     return false;
00072   return true;
00073 }
00074 
00075 bool Prism15::is_face(const unsigned int) const
00076 {
00077   return false;
00078 }
00079 
00080 bool Prism15::is_node_on_side(const unsigned int n,
00081                               const unsigned int s) const
00082 {
00083   libmesh_assert_less (s, n_sides());
00084   for (unsigned int i = 0; i != 8; ++i)
00085     if (side_nodes_map[s][i] == n)
00086       return true;
00087   return false;
00088 }
00089 
00090 bool Prism15::is_node_on_edge(const unsigned int n,
00091                               const unsigned int e) const
00092 {
00093   libmesh_assert_less (e, n_edges());
00094   for (unsigned int i = 0; i != 3; ++i)
00095     if (edge_nodes_map[e][i] == n)
00096       return true;
00097   return false;
00098 }
00099 
00100 
00101 
00102 bool Prism15::has_affine_map() const
00103 {
00104   // Make sure z edges are affine
00105   Point v = this->point(3) - this->point(0);
00106   if (!v.relative_fuzzy_equals(this->point(4) - this->point(1)) ||
00107       !v.relative_fuzzy_equals(this->point(5) - this->point(2)))
00108     return false;
00109   // Make sure edges are straight
00110   v /= 2;
00111   if (!v.relative_fuzzy_equals(this->point(9) - this->point(0)) ||
00112       !v.relative_fuzzy_equals(this->point(10) - this->point(1)) ||
00113       !v.relative_fuzzy_equals(this->point(11) - this->point(2)))
00114     return false;
00115   v = (this->point(1) - this->point(0))/2;
00116   if (!v.relative_fuzzy_equals(this->point(6) - this->point(0)) ||
00117       !v.relative_fuzzy_equals(this->point(12) - this->point(3)))
00118     return false;
00119   v = (this->point(2) - this->point(0))/2;
00120   if (!v.relative_fuzzy_equals(this->point(8) - this->point(0)) ||
00121       !v.relative_fuzzy_equals(this->point(14) - this->point(3)))
00122     return false;
00123   v = (this->point(2) - this->point(1))/2;
00124   if (!v.relative_fuzzy_equals(this->point(7) - this->point(1)) ||
00125       !v.relative_fuzzy_equals(this->point(13) - this->point(4)))
00126     return false;
00127   return true;
00128 }
00129 
00130 
00131 
00132 UniquePtr<Elem> Prism15::build_side (const unsigned int i,
00133                                      bool proxy) const
00134 {
00135   libmesh_assert_less (i, this->n_sides());
00136 
00137   if (proxy)
00138     {
00139       switch (i)
00140         {
00141         case 0:  // the triangular face at z=-1
00142         case 4:
00143           return UniquePtr<Elem>(new Side<Tri6,Prism15>(this,i));
00144 
00145         case 1:
00146         case 2:
00147         case 3:
00148           return UniquePtr<Elem>(new Side<Quad8,Prism15>(this,i));
00149 
00150         default:
00151           libmesh_error_msg("Invalid side i = " << i);
00152         }
00153     }
00154 
00155   else
00156     {
00157       // Create NULL pointer to be initialized, returned later.
00158       Elem* face = NULL;
00159 
00160       switch (i)
00161         {
00162         case 0:  // the triangular face at z=-1
00163           {
00164             face = new Tri6;
00165 
00166             face->set_node(0) = this->get_node(0);
00167             face->set_node(1) = this->get_node(2);
00168             face->set_node(2) = this->get_node(1);
00169             face->set_node(3) = this->get_node(8);
00170             face->set_node(4) = this->get_node(7);
00171             face->set_node(5) = this->get_node(6);
00172 
00173             break;
00174           }
00175         case 1:  // the quad face at y=0
00176           {
00177             face = new Quad8;
00178 
00179             face->set_node(0) = this->get_node(0);
00180             face->set_node(1) = this->get_node(1);
00181             face->set_node(2) = this->get_node(4);
00182             face->set_node(3) = this->get_node(3);
00183             face->set_node(4) = this->get_node(6);
00184             face->set_node(5) = this->get_node(10);
00185             face->set_node(6) = this->get_node(12);
00186             face->set_node(7) = this->get_node(9);
00187 
00188             break;
00189           }
00190         case 2:  // the other quad face
00191           {
00192             face = new Quad8;
00193 
00194             face->set_node(0) = this->get_node(1);
00195             face->set_node(1) = this->get_node(2);
00196             face->set_node(2) = this->get_node(5);
00197             face->set_node(3) = this->get_node(4);
00198             face->set_node(4) = this->get_node(7);
00199             face->set_node(5) = this->get_node(11);
00200             face->set_node(6) = this->get_node(13);
00201             face->set_node(7) = this->get_node(10);
00202 
00203             break;
00204           }
00205         case 3: // the quad face at x=0
00206           {
00207             face = new Quad8;
00208 
00209             face->set_node(0) = this->get_node(2);
00210             face->set_node(1) = this->get_node(0);
00211             face->set_node(2) = this->get_node(3);
00212             face->set_node(3) = this->get_node(5);
00213             face->set_node(4) = this->get_node(8);
00214             face->set_node(5) = this->get_node(9);
00215             face->set_node(6) = this->get_node(14);
00216             face->set_node(7) = this->get_node(11);
00217 
00218             break;
00219           }
00220         case 4: // the triangular face at z=1
00221           {
00222             face = new Tri6;
00223 
00224             face->set_node(0) = this->get_node(3);
00225             face->set_node(1) = this->get_node(4);
00226             face->set_node(2) = this->get_node(5);
00227             face->set_node(3) = this->get_node(12);
00228             face->set_node(4) = this->get_node(13);
00229             face->set_node(5) = this->get_node(14);
00230 
00231             break;
00232           }
00233         default:
00234           libmesh_error_msg("Invalid side i = " << i);
00235         }
00236 
00237       face->subdomain_id() = this->subdomain_id();
00238       return UniquePtr<Elem>(face);
00239     }
00240 
00241   libmesh_error_msg("We'll never get here!");
00242   return UniquePtr<Elem>();
00243 }
00244 
00245 
00246 UniquePtr<Elem> Prism15::build_edge (const unsigned int i) const
00247 {
00248   libmesh_assert_less (i, this->n_edges());
00249 
00250   return UniquePtr<Elem>(new SideEdge<Edge3,Prism15>(this,i));
00251 }
00252 
00253 
00254 void Prism15::connectivity(const unsigned int libmesh_dbg_var(sc),
00255                            const IOPackage iop,
00256                            std::vector<dof_id_type>& conn) const
00257 {
00258   libmesh_assert(_nodes);
00259   libmesh_assert_less (sc, this->n_sub_elem());
00260   libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
00261 
00262   switch (iop)
00263     {
00264     case TECPLOT:
00265       {
00266         conn.resize(8);
00267         conn[0] = this->node(0)+1;
00268         conn[1] = this->node(1)+1;
00269         conn[2] = this->node(2)+1;
00270         conn[3] = this->node(2)+1;
00271         conn[4] = this->node(3)+1;
00272         conn[5] = this->node(4)+1;
00273         conn[6] = this->node(5)+1;
00274         conn[7] = this->node(5)+1;
00275         return;
00276       }
00277 
00278     case VTK:
00279       {
00280         /*
00281           conn.resize(6);
00282           conn[0] = this->node(0);
00283           conn[1] = this->node(2);
00284           conn[2] = this->node(1);
00285           conn[3] = this->node(3);
00286           conn[4] = this->node(5);
00287           conn[5] = this->node(4);
00288         */
00289 
00290         // VTK's VTK_QUADRATIC_WEDGE first 9 nodes match, then their
00291         // middle and top layers of mid-edge nodes are reversed from
00292         // LibMesh's.
00293         conn.resize(15);
00294         for (unsigned i=0; i<9; ++i)
00295           conn[i] = this->node(i);
00296 
00297         // top "ring" of mid-edge nodes
00298         conn[9]  = this->node(12);
00299         conn[10] = this->node(13);
00300         conn[11] = this->node(14);
00301 
00302         // middle "ring" of mid-edge nodes
00303         conn[12] = this->node(9);
00304         conn[13] = this->node(10);
00305         conn[14] = this->node(11);
00306 
00307 
00308         return;
00309       }
00310 
00311     default:
00312       libmesh_error_msg("Unsupported IO package " << iop);
00313     }
00314 }
00315 
00316 
00317 
00318 
00319 unsigned short int Prism15::second_order_adjacent_vertex (const unsigned int n,
00320                                                           const unsigned int v) const
00321 {
00322   libmesh_assert_greater_equal (n, this->n_vertices());
00323   libmesh_assert_less (n, this->n_nodes());
00324   libmesh_assert_less (v, 2);
00325   return _second_order_adjacent_vertices[n-this->n_vertices()][v];
00326 }
00327 
00328 
00329 
00330 std::pair<unsigned short int, unsigned short int>
00331 Prism15::second_order_child_vertex (const unsigned int n) const
00332 {
00333   libmesh_assert_greater_equal (n, this->n_vertices());
00334   libmesh_assert_less (n, this->n_nodes());
00335 
00336   return std::pair<unsigned short int, unsigned short int>
00337     (_second_order_vertex_child_number[n],
00338      _second_order_vertex_child_index[n]);
00339 }
00340 
00341 } // namespace libMesh