$extrastylesheet
cell_inf_prism6.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 // Local includes
00019 #include "libmesh/libmesh_config.h"
00020 
00021 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
00022 
00023 // C++ includes
00024 
00025 // Local includes cont'd
00026 #include "libmesh/cell_inf_prism6.h"
00027 #include "libmesh/edge_edge2.h"
00028 #include "libmesh/edge_inf_edge2.h"
00029 #include "libmesh/fe_interface.h"
00030 #include "libmesh/fe_type.h"
00031 #include "libmesh/side.h"
00032 #include "libmesh/face_inf_quad4.h"
00033 #include "libmesh/face_tri3.h"
00034 
00035 namespace libMesh
00036 {
00037 
00038 
00039 // ------------------------------------------------------------
00040 // InfPrism6 class static member initializations
00041 const unsigned int InfPrism6::side_nodes_map[4][4] =
00042   {
00043     { 0, 1, 2, 99}, // Side 0
00044     { 0, 1, 3, 4},  // Side 1
00045     { 1, 2, 4, 5},  // Side 2
00046     { 2, 0, 5, 3}   // Side 3
00047   };
00048 
00049 const unsigned int InfPrism6::edge_nodes_map[6][2] =
00050   {
00051     { 0, 1}, // Side 0
00052     { 1, 2},  // Side 1
00053     { 0, 2},  // Side 2
00054     { 0, 3},  // Side 3
00055     { 1, 4},  // Side 4
00056     { 2, 5}   // Side 5
00057   };
00058 
00059 
00060 // ------------------------------------------------------------
00061 // InfPrism6 class member functions
00062 
00063 bool InfPrism6::is_vertex(const unsigned int i) const
00064 {
00065   if (i < 3)
00066     return true;
00067   return false;
00068 }
00069 
00070 bool InfPrism6::is_edge(const unsigned int i) const
00071 {
00072   if (i < 3)
00073     return false;
00074   return true;
00075 }
00076 
00077 bool InfPrism6::is_face(const unsigned int) const
00078 {
00079   return false;
00080 }
00081 
00082 bool InfPrism6::is_node_on_side(const unsigned int n,
00083                                 const unsigned int s) const
00084 {
00085   libmesh_assert_less (s, n_sides());
00086   for (unsigned int i = 0; i != 4; ++i)
00087     if (side_nodes_map[s][i] == n)
00088       return true;
00089   return false;
00090 }
00091 
00092 bool InfPrism6::is_node_on_edge(const unsigned int n,
00093                                 const unsigned int e) const
00094 {
00095   libmesh_assert_less (e, n_edges());
00096   for (unsigned int i = 0; i != 2; ++i)
00097     if (edge_nodes_map[e][i] == n)
00098       return true;
00099   return false;
00100 }
00101 
00102 
00103 UniquePtr<Elem> InfPrism6::build_side (const unsigned int i,
00104                                        bool proxy) const
00105 {
00106   libmesh_assert_less (i, this->n_sides());
00107 
00108   if (proxy)
00109     {
00110       switch (i)
00111         {
00112           // base
00113         case 0:
00114           return UniquePtr<Elem>(new Side<Tri3,InfPrism6>(this,i));
00115 
00116           // ifem sides
00117         case 1:
00118         case 2:
00119         case 3:
00120           return UniquePtr<Elem>(new Side<InfQuad4,InfPrism6>(this,i));
00121 
00122         default:
00123           libmesh_error_msg("Invalid side i = " << i);
00124         }
00125     }
00126 
00127   else
00128     {
00129       // Create NULL pointer to be initialized, returned later.
00130       Elem* face = NULL;
00131 
00132       switch (i)
00133         {
00134         case 0:  // the triangular face at z=-1, base face
00135           {
00136             face = new Tri3;
00137 
00138             // Note that for this face element, the normal points inward
00139             face->set_node(0) = this->get_node(0);
00140             face->set_node(1) = this->get_node(1);
00141             face->set_node(2) = this->get_node(2);
00142 
00143             break;
00144           }
00145 
00146         case 1:  // the quad face at y=0
00147           {
00148             face = new InfQuad4;
00149 
00150             face->set_node(0) = this->get_node(0);
00151             face->set_node(1) = this->get_node(1);
00152             face->set_node(2) = this->get_node(3);
00153             face->set_node(3) = this->get_node(4);
00154 
00155             break;
00156           }
00157 
00158         case 2:  // the other quad face
00159           {
00160             face = new InfQuad4;
00161 
00162             face->set_node(0) = this->get_node(1);
00163             face->set_node(1) = this->get_node(2);
00164             face->set_node(2) = this->get_node(4);
00165             face->set_node(3) = this->get_node(5);
00166 
00167             break;
00168           }
00169 
00170         case 3: // the quad face at x=0
00171           {
00172             face = new InfQuad4;
00173 
00174             face->set_node(0) = this->get_node(2);
00175             face->set_node(1) = this->get_node(0);
00176             face->set_node(2) = this->get_node(5);
00177             face->set_node(3) = this->get_node(3);
00178 
00179             break;
00180           }
00181 
00182         default:
00183           libmesh_error_msg("Invalid side i = " << i);
00184         }
00185 
00186       face->subdomain_id() = this->subdomain_id();
00187       return UniquePtr<Elem>(face);
00188     }
00189 
00190   libmesh_error_msg("We'll never get here!");
00191   return UniquePtr<Elem>();
00192 }
00193 
00194 
00195 UniquePtr<Elem> InfPrism6::build_edge (const unsigned int i) const
00196 {
00197   libmesh_assert_less (i, n_edges());
00198 
00199   if (i < 3)
00200     return UniquePtr<Elem>(new SideEdge<Edge2,InfPrism6>(this,i));
00201   return UniquePtr<Elem>(new SideEdge<InfEdge2,InfPrism6>(this,i));
00202 }
00203 
00204 
00205 bool InfPrism6::contains_point (const Point& p, Real tol) const
00206 {
00207   /*
00208    * For infinite elements with linear base interpolation:
00209    *
00210    * make use of the fact that infinite elements do not
00211    * live inside the envelope.  Use a fast scheme to
00212    * check whether point \p p is inside or outside
00213    * our relevant part of the envelope.  Note that
00214    * this is not exclusive: only when the distance is less,
00215    * we are safe.  Otherwise, we cannot say anything. The
00216    * envelope may be non-spherical, the physical point may lie
00217    * inside the envelope, outside the envelope, or even inside
00218    * this infinite element.  Therefore if this fails,
00219    * fall back to the FEInterface::inverse_map()
00220    */
00221   const Point my_origin (this->origin());
00222 
00223   /*
00224    * determine the minimal distance of the base from the origin
00225    * use size_sq(), it is faster than size() and produces
00226    * the same behavior
00227    */
00228   const Real min_distance_sq = std::min((Point(this->point(0)-my_origin)).size_sq(),
00229                                         std::min((Point(this->point(1)-my_origin)).size_sq(),
00230                                                  (Point(this->point(2)-my_origin)).size_sq()));
00231 
00232   /*
00233    * work with 1% allowable deviation.  We can still fall
00234    * back to the InfFE::inverse_map()
00235    */
00236   const Real conservative_p_dist_sq = 1.01 * (Point(p-my_origin).size_sq());
00237 
00238 
00239   if (conservative_p_dist_sq < min_distance_sq)
00240     {
00241       /*
00242        * the physical point is definitely not contained in the element
00243        */
00244       return false;
00245     }
00246   else
00247     {
00248       /*
00249        * Declare a basic FEType.  Will use default in the base,
00250        * and something else (not important) in radial direction.
00251        */
00252       FEType fe_type(default_order());
00253 
00254       const Point mapped_point = FEInterface::inverse_map(dim(),
00255                                                           fe_type,
00256                                                           this,
00257                                                           p,
00258                                                           tol,
00259                                                           false);
00260 
00261       return FEInterface::on_reference_element(mapped_point, this->type(), tol);
00262     }
00263 }
00264 
00265 
00266 
00267 
00268 void InfPrism6::connectivity(const unsigned int libmesh_dbg_var(sc),
00269                              const IOPackage iop,
00270                              std::vector<dof_id_type>& conn) const
00271 {
00272   libmesh_assert(_nodes);
00273   libmesh_assert_less (sc, this->n_sub_elem());
00274   libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
00275 
00276   switch (iop)
00277     {
00278     case TECPLOT:
00279       {
00280         conn.resize(8);
00281         conn[0] = this->node(0)+1;
00282         conn[1] = this->node(1)+1;
00283         conn[2] = this->node(2)+1;
00284         conn[3] = this->node(2)+1;
00285         conn[4] = this->node(3)+1;
00286         conn[5] = this->node(4)+1;
00287         conn[6] = this->node(5)+1;
00288         conn[7] = this->node(5)+1;
00289         return;
00290       }
00291 
00292     default:
00293       libmesh_error_msg("Unsupported IO package " << iop);
00294     }
00295 }
00296 
00297 
00298 
00299 
00300 
00301 #ifdef LIBMESH_ENABLE_AMR
00302 
00303 const float InfPrism6::_embedding_matrix[4][6][6] =
00304   {
00305     // embedding matrix for child 0
00306     {
00307       //          0           1           2           3           4           5 th parent Node
00308       {         1.0,        0.0,        0.0,        0.0,        0.0,        0.0}, // 0th child N.
00309       {         0.5,        0.5,        0.0,        0.0,        0.0,        0.0}, // 1
00310       {         0.5,        0.0,        0.5,        0.0,        0.0,        0.0}, // 2
00311       {         0.0,        0.0,        0.0,        1.0,        0.0,        0.0}, // 3
00312       {         0.0,        0.0,        0.0,        0.5,        0.5,        0.0}, // 4
00313       {         0.0,        0.0,        0.0,        0.5,        0.0,        0.5}  // 5
00314     },
00315 
00316     // embedding matrix for child 1
00317     {
00318       //          0           1           2           3           4           5 th parent Node
00319       {         0.5,        0.5,        0.0,        0.0,        0.0,        0.0}, // 0th child N.
00320       {         0.0,        1.0,        0.0,        0.0,        0.0,        0.0}, // 1
00321       {         0.0,        0.5,        0.5,        0.0,        0.0,        0.0}, // 2
00322       {         0.0,        0.0,        0.0,        0.5,        0.5,        0.0}, // 3
00323       {         0.0,        0.0,        0.0,        0.0,        1.0,        0.0}, // 4
00324       {         0.0,        0.0,        0.0,        0.0,        0.5,        0.5}  // 5
00325     },
00326 
00327     // embedding matrix for child 2
00328     {
00329       //          0           1           2           3           4           5 th parent Node
00330       {         0.5,        0.0,        0.5,        0.0,        0.0,        0.0}, // 0th child N.
00331       {         0.0,        0.5,        0.5,        0.0,        0.0,        0.0}, // 1
00332       {         0.0,        0.0,        1.0,        0.0,        0.0,        0.0}, // 2
00333       {         0.0,        0.0,        0.0,        0.5,        0.0,        0.5}, // 3
00334       {         0.0,        0.0,        0.0,        0.0,        0.5,        0.5}, // 4
00335       {         0.0,        0.0,        0.0,        0.0,        0.0,        1.0}  // 5
00336     },
00337 
00338     // embedding matrix for child 3
00339     {
00340       //          0           1           2           3           4           5 th parent Node
00341       {         0.5,        0.5,        0.0,        0.0,        0.0,        0.0}, // 0th child N.
00342       {         0.0,        0.5,        0.5,        0.0,        0.0,        0.0}, // 1
00343       {         0.5,        0.0,        0.5,        0.0,        0.0,        0.0}, // 2
00344       {         0.0,        0.0,        0.0,        0.5,        0.5,        0.0}, // 3
00345       {         0.0,        0.0,        0.0,        0.0,        0.5,        0.5}, // 4
00346       {         0.0,        0.0,        0.0,        0.5,        0.0,        0.5}  // 5
00347     }
00348   };
00349 
00350 
00351 
00352 #endif
00353 
00354 } // namespace libMesh
00355 
00356 #endif  // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS