$extrastylesheet
face_quad.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_quad.h"
00022 #include "libmesh/edge_edge2.h"
00023 
00024 namespace libMesh
00025 {
00026 
00027 
00028 // ------------------------------------------------------------
00029 // Quad class member functions
00030 dof_id_type Quad::key (const unsigned int s) const
00031 {
00032   libmesh_assert_less (s, this->n_sides());
00033 
00034   switch (s)
00035     {
00036     case 0:
00037       return
00038         this->compute_key (this->node(0),
00039                            this->node(1));
00040 
00041     case 1:
00042       return
00043         this->compute_key (this->node(1),
00044                            this->node(2));
00045 
00046     case 2:
00047       return
00048         this->compute_key (this->node(2),
00049                            this->node(3));
00050 
00051     case 3:
00052       return
00053         this->compute_key (this->node(3),
00054                            this->node(0));
00055 
00056     default:
00057       libmesh_error_msg("Invalid side s = " << s);
00058     }
00059 
00060   libmesh_error_msg("We'll never get here!");
00061   return 0;
00062 }
00063 
00064 
00065 
00066 UniquePtr<Elem> Quad::side (const unsigned int i) const
00067 {
00068   libmesh_assert_less (i, this->n_sides());
00069 
00070   Elem* edge = new Edge2;
00071 
00072   switch (i)
00073     {
00074     case 0:
00075       {
00076         edge->set_node(0) = this->get_node(0);
00077         edge->set_node(1) = this->get_node(1);
00078         break;
00079       }
00080     case 1:
00081       {
00082         edge->set_node(0) = this->get_node(1);
00083         edge->set_node(1) = this->get_node(2);
00084         break;
00085       }
00086     case 2:
00087       {
00088         edge->set_node(0) = this->get_node(2);
00089         edge->set_node(1) = this->get_node(3);
00090         break;
00091       }
00092     case 3:
00093       {
00094         edge->set_node(0) = this->get_node(3);
00095         edge->set_node(1) = this->get_node(0);
00096         break;
00097       }
00098     default:
00099       libmesh_error_msg("Invalid side i = " << i);
00100     }
00101 
00102   return UniquePtr<Elem>(edge);
00103 }
00104 
00105 
00106 
00107 bool Quad::is_child_on_side(const unsigned int c,
00108                             const unsigned int s) const
00109 {
00110   libmesh_assert_less (c, this->n_children());
00111   libmesh_assert_less (s, this->n_sides());
00112 
00113   // A quad's children and nodes don't share the same ordering:
00114   // child 2 and 3 are swapped;
00115   unsigned int n = (c < 2) ? c : 5-c;
00116   return (n == s || n == (s+1)%4);
00117 }
00118 
00119 
00120 
00121 unsigned int Quad::opposite_side(const unsigned int side_in) const
00122 {
00123   libmesh_assert_less (side_in, 4);
00124 
00125   return (side_in + 2) % 4;
00126 }
00127 
00128 
00129 
00130 unsigned int Quad::opposite_node(const unsigned int node_in,
00131                                  const unsigned int side_in) const
00132 {
00133   libmesh_assert_less (node_in, 8);
00134   libmesh_assert_less (node_in, this->n_nodes());
00135   libmesh_assert_less (side_in, this->n_sides());
00136   libmesh_assert(this->is_node_on_side(node_in, side_in));
00137 
00138   static const unsigned char side02_nodes_map[] =
00139     {3, 2, 1, 0, 6, 255, 4, 255};
00140   static const unsigned char side13_nodes_map[] =
00141     {1, 0, 3, 2, 255, 7, 255, 5};
00142 
00143   switch (side_in)
00144     {
00145     case 0:
00146     case 2:
00147       return side02_nodes_map[node_in];
00148     case 1:
00149     case 3:
00150       return side13_nodes_map[node_in];
00151     default:
00152       libmesh_error_msg("Unsupported side_in = " << side_in);
00153     }
00154 
00155   libmesh_error_msg("We'll never get here!");
00156   return 255;
00157 }
00158 
00159 
00160 Real Quad::quality (const ElemQuality q) const
00161 {
00162   switch (q)
00163     {
00164 
00169     case DISTORTION:
00170     case DIAGONAL:
00171     case STRETCH:
00172       {
00173         // Diagonal between node 0 and node 2
00174         const Real d02 = this->length(0,2);
00175 
00176         // Diagonal between node 1 and node 3
00177         const Real d13 = this->length(1,3);
00178 
00179         // Find the biggest and smallest diagonals
00180         if ( (d02 > 0.) && (d13 >0.) )
00181           if (d02 < d13) return d02 / d13;
00182           else return d13 / d02;
00183         else
00184           return 0.;
00185         break;
00186       }
00187 
00188     default:
00189       return Elem::quality(q);
00190     }
00191 
00197   return Elem::quality(q);
00198 }
00199 
00200 
00201 
00202 
00203 
00204 
00205 std::pair<Real, Real> Quad::qual_bounds (const ElemQuality q) const
00206 {
00207   std::pair<Real, Real> bounds;
00208 
00209   switch (q)
00210     {
00211 
00212     case ASPECT_RATIO:
00213       bounds.first  = 1.;
00214       bounds.second = 4.;
00215       break;
00216 
00217     case SKEW:
00218       bounds.first  = 0.;
00219       bounds.second = 0.5;
00220       break;
00221 
00222     case TAPER:
00223       bounds.first  = 0.;
00224       bounds.second = 0.7;
00225       break;
00226 
00227     case WARP:
00228       bounds.first  = 0.9;
00229       bounds.second = 1.;
00230       break;
00231 
00232     case STRETCH:
00233       bounds.first  = 0.25;
00234       bounds.second = 1.;
00235       break;
00236 
00237     case MIN_ANGLE:
00238       bounds.first  = 45.;
00239       bounds.second = 90.;
00240       break;
00241 
00242     case MAX_ANGLE:
00243       bounds.first  = 90.;
00244       bounds.second = 135.;
00245       break;
00246 
00247     case CONDITION:
00248       bounds.first  = 1.;
00249       bounds.second = 4.;
00250       break;
00251 
00252     case JACOBIAN:
00253       bounds.first  = 0.5;
00254       bounds.second = 1.;
00255       break;
00256 
00257     case SHEAR:
00258     case SHAPE:
00259     case SIZE:
00260       bounds.first  = 0.3;
00261       bounds.second = 1.;
00262       break;
00263 
00264     case DISTORTION:
00265       bounds.first  = 0.6;
00266       bounds.second = 1.;
00267       break;
00268 
00269     default:
00270       libMesh::out << "Warning: Invalid quality measure chosen." << std::endl;
00271       bounds.first  = -1;
00272       bounds.second = -1;
00273     }
00274 
00275   return bounds;
00276 }
00277 
00278 
00279 
00280 
00281 const unsigned short int Quad::_second_order_adjacent_vertices[4][2] =
00282   {
00283     {0, 1}, // vertices adjacent to node 4
00284     {1, 2}, // vertices adjacent to node 5
00285     {2, 3}, // vertices adjacent to node 6
00286     {0, 3}  // vertices adjacent to node 7
00287   };
00288 
00289 
00290 
00291 const unsigned short int Quad::_second_order_vertex_child_number[9] =
00292   {
00293     99,99,99,99, // Vertices
00294     0,1,2,0,     // Edges
00295     0            // Interior
00296   };
00297 
00298 
00299 
00300 const unsigned short int Quad::_second_order_vertex_child_index[9] =
00301   {
00302     99,99,99,99, // Vertices
00303     1,2,3,3,     // Edges
00304     2            // Interior
00305   };
00306 
00307 } // namespace libMesh