$extrastylesheet
fe_nedelec_one_shape_3D.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++ inlcludes
00020 
00021 // Local includes
00022 #include "libmesh/fe.h"
00023 #include "libmesh/elem.h"
00024 
00025 namespace libMesh
00026 {
00027 
00028 template <>
00029 RealGradient FE<3,NEDELEC_ONE>::shape(const ElemType,
00030                                       const Order,
00031                                       const unsigned int,
00032                                       const Point&)
00033 {
00034   libmesh_error_msg("Nedelec elements require the element type \nbecause edge orientation is needed.");
00035   return RealGradient();
00036 }
00037 
00038 
00039 
00040 template <>
00041 RealGradient FE<3,NEDELEC_ONE>::shape(const Elem* elem,
00042                                       const Order order,
00043                                       const unsigned int i,
00044                                       const Point& p)
00045 {
00046 #if LIBMESH_DIM == 3
00047   libmesh_assert(elem);
00048 
00049   const Order totalorder = static_cast<Order>(order + elem->p_level());
00050 
00051   switch (totalorder)
00052     {
00053       // linear Lagrange shape functions
00054     case FIRST:
00055       {
00056         switch (elem->type())
00057           {
00058           case HEX20:
00059           case HEX27:
00060             {
00061               libmesh_assert_less (i, 12);
00062 
00063               const Real xi   = p(0);
00064               const Real eta  = p(1);
00065               const Real zeta = p(2);
00066 
00067               // Even with a loose inverse_map tolerance we ought to
00068               // be nearly on the element interior in master
00069               // coordinates
00070               libmesh_assert_less_equal ( std::fabs(xi),   1.0+10*TOLERANCE );
00071               libmesh_assert_less_equal ( std::fabs(eta),  1.0+10*TOLERANCE );
00072               libmesh_assert_less_equal ( std::fabs(zeta), 1.0+10*TOLERANCE );
00073 
00074               switch(i)
00075                 {
00076                 case 0:
00077                   {
00078                     if( elem->point(0) > elem->point(1) )
00079                       return RealGradient( -0.125*(1.0-eta-zeta+eta*zeta), 0.0, 0.0 );
00080                     else
00081                       return RealGradient(  0.125*(1.0-eta-zeta+eta*zeta), 0.0, 0.0 );
00082                   }
00083                 case 1:
00084                   {
00085                     if( elem->point(1) > elem->point(2) )
00086                       return RealGradient( 0.0, -0.125*(1.0+xi-zeta-xi*zeta), 0.0 );
00087                     else
00088                       return RealGradient( 0.0,  0.125*(1.0+xi-zeta-xi*zeta), 0.0 );
00089                   }
00090                 case 2:
00091                   {
00092                     if( elem->point(2) > elem->point(3) )
00093                       return RealGradient(  0.125*(1.0+eta-zeta-eta*zeta), 0.0, 0.0 );
00094                     else
00095                       return RealGradient( -0.125*(1.0+eta-zeta-eta*zeta), 0.0, 0.0 );
00096                   }
00097                 case 3:
00098                   {
00099                     if( elem->point(3) > elem->point(0) )
00100                       return RealGradient( 0.0,  0.125*(1.0-xi-zeta+xi*zeta), 0.0 );
00101                     else
00102                       return RealGradient( 0.0, -0.125*(1.0-xi-zeta+xi*zeta), 0.0 );
00103                   }
00104                 case 4:
00105                   {
00106                     if( elem->point(0) > elem->point(4) )
00107                       return RealGradient( 0.0, 0.0, -0.125*(1.0-xi-eta+xi*eta) );
00108                     else
00109                       return RealGradient( 0.0, 0.0,  0.125*(1.0-xi-eta+xi*eta) );
00110                   }
00111                 case 5:
00112                   {
00113                     if( elem->point(1) > elem->point(5) )
00114                       return RealGradient( 0.0, 0.0, -0.125*(1.0+xi-eta-xi*eta) );
00115                     else
00116                       return RealGradient( 0.0, 0.0,  0.125*(1.0+xi-eta-xi*eta) );
00117                   }
00118                 case 6:
00119                   {
00120                     if( elem->point(2) > elem->point(6) )
00121                       return RealGradient( 0.0, 0.0, -0.125*(1.0+xi+eta+xi*eta) );
00122                     else
00123                       return RealGradient( 0.0, 0.0,  0.125*(1.0+xi+eta+xi*eta) );
00124                   }
00125                 case 7:
00126                   {
00127                     if( elem->point(3) > elem->point(7) )
00128                       return RealGradient( 0.0, 0.0, -0.125*(1.0-xi+eta-xi*eta) );
00129                     else
00130                       return RealGradient( 0.0, 0.0,  0.125*(1.0-xi+eta-xi*eta) );
00131                   }
00132                 case 8:
00133                   {
00134                     if( elem->point(4) > elem->point(5) )
00135                       return RealGradient( -0.125*(1.0-eta+zeta-eta*zeta), 0.0, 0.0 );
00136                     else
00137                       return RealGradient(  0.125*(1.0-eta+zeta-eta*zeta), 0.0, 0.0 );
00138                   }
00139                 case 9:
00140                   {
00141                     if( elem->point(5) > elem->point(6) )
00142                       return RealGradient( 0.0, -0.125*(1.0+xi+zeta+xi*zeta), 0.0 );
00143                     else
00144                       return RealGradient( 0.0,  0.125*(1.0+xi+zeta+xi*zeta), 0.0 );
00145                   }
00146                 case 10:
00147                   {
00148                     if( elem->point(7) > elem->point(6) )
00149                       return RealGradient( -0.125*(1.0+eta+zeta+eta*zeta), 0.0, 0.0 );
00150                     else
00151                       return RealGradient(  0.125*(1.0+eta+zeta+eta*zeta), 0.0, 0.0 );
00152                   }
00153                 case 11:
00154                   {
00155                     if( elem->point(4) > elem->point(7) )
00156                       return RealGradient( 0.0, -0.125*(1.0-xi+zeta-xi*zeta), 0.0 );
00157                     else
00158                       return RealGradient( 0.0,  0.125*(1.0-xi+zeta-xi*zeta), 0.0 );
00159                   }
00160 
00161                 default:
00162                   libmesh_error_msg("Invalid i = " << i);
00163                 }
00164 
00165               return RealGradient();
00166             }
00167 
00168           case TET10:
00169             {
00170               libmesh_assert_less (i, 6);
00171 
00172               libmesh_not_implemented();
00173               return RealGradient();
00174             }
00175 
00176           default:
00177             libmesh_error_msg("ERROR: Unsupported 3D element type!: " << elem->type());
00178           }
00179       }
00180 
00181       // unsupported order
00182     default:
00183       libmesh_error_msg("ERROR: Unsupported 3D FE order!: " << totalorder);
00184     }
00185 #endif
00186 
00187   libmesh_error_msg("We'll never get here!");
00188   return RealGradient();
00189 }
00190 
00191 
00192 
00193 
00194 template <>
00195 RealGradient FE<3,NEDELEC_ONE>::shape_deriv(const ElemType,
00196                                             const Order,
00197                                             const unsigned int,
00198                                             const unsigned int,
00199                                             const Point&)
00200 {
00201   libmesh_error_msg("Nedelec elements require the element type \nbecause edge orientation is needed.");
00202   return RealGradient();
00203 }
00204 
00205 template <>
00206 RealGradient FE<3,NEDELEC_ONE>::shape_deriv(const Elem* elem,
00207                                             const Order order,
00208                                             const unsigned int i,
00209                                             const unsigned int j,
00210                                             const Point& p)
00211 {
00212 #if LIBMESH_DIM == 3
00213   libmesh_assert(elem);
00214   libmesh_assert_less (j, 3);
00215 
00216   const Order totalorder = static_cast<Order>(order + elem->p_level());
00217 
00218   switch (totalorder)
00219     {
00220     case FIRST:
00221       {
00222         switch (elem->type())
00223           {
00224           case HEX20:
00225           case HEX27:
00226             {
00227               libmesh_assert_less (i, 12);
00228 
00229               const Real xi   = p(0);
00230               const Real eta  = p(1);
00231               const Real zeta = p(2);
00232 
00233               // Even with a loose inverse_map tolerance we ought to
00234               // be nearly on the element interior in master
00235               // coordinates
00236               libmesh_assert_less_equal ( std::fabs(xi),   1.0+TOLERANCE );
00237               libmesh_assert_less_equal ( std::fabs(eta),  1.0+TOLERANCE );
00238               libmesh_assert_less_equal ( std::fabs(zeta), 1.0+TOLERANCE );
00239 
00240               switch (j)
00241                 {
00242                   // d()/dxi
00243                 case 0:
00244                   {
00245                     switch(i)
00246                       {
00247                       case 0:
00248                       case 2:
00249                       case 8:
00250                       case 10:
00251                         return RealGradient();
00252                       case 1:
00253                         {
00254                           if( elem->point(1) > elem->point(2) )
00255                             return RealGradient( 0.0, -0.125*(1.0-zeta) );
00256                           else
00257                             return RealGradient( 0.0, 0.125*(1.0-zeta) );
00258                         }
00259                       case 3:
00260                         {
00261                           if( elem->point(3) > elem->point(0) )
00262                             return RealGradient( 0.0, 0.125*(-1.0+zeta) );
00263                           else
00264                             return RealGradient( 0.0, -0.125*(-1.0+zeta) );
00265                         }
00266                       case 4:
00267                         {
00268                           if( elem->point(0) > elem->point(4) )
00269                             return RealGradient( 0.0, 0.0, -0.125*(-1.0+eta) );
00270                           else
00271                             return RealGradient( 0.0, 0.0,  0.125*(-1.0+eta) );
00272                         }
00273                       case 5:
00274                         {
00275                           if( elem->point(1) > elem->point(5) )
00276                             return RealGradient( 0.0, 0.0, -0.125*(1.0-eta) );
00277                           else
00278                             return RealGradient( 0.0, 0.0,  0.125*(1.0-eta) );
00279                         }
00280                       case 6:
00281                         {
00282                           if( elem->point(2) > elem->point(6) )
00283                             return RealGradient( 0.0, 0.0, -0.125*(1.0+eta) );
00284                           else
00285                             return RealGradient( 0.0, 0.0,  0.125*(1.0+eta) );
00286                         }
00287                       case 7:
00288                         {
00289                           if( elem->point(3) > elem->point(7) )
00290                             return RealGradient( 0.0, 0.0, -0.125*(-1.0-eta) );
00291                           else
00292                             return RealGradient( 0.0, 0.0,  0.125*(-1.0-eta) );
00293                         }
00294                       case 9:
00295                         {
00296                           if( elem->point(5) > elem->point(6) )
00297                             return RealGradient( 0.0, -0.125*(1.0+zeta), 0.0 );
00298                           else
00299                             return RealGradient( 0.0,  0.125*(1.0+zeta), 0.0 );
00300                         }
00301                       case 11:
00302                         {
00303                           if( elem->point(4) > elem->point(7) )
00304                             return RealGradient( 0.0, -0.125*(-1.0-zeta), 0.0 );
00305                           else
00306                             return RealGradient( 0.0,  0.125*(-1.0-zeta), 0.0 );
00307                         }
00308                       default:
00309                         libmesh_error_msg("Invalid i = " << i);
00310                       } // switch(i)
00311 
00312                   } // j=0
00313 
00314                   // d()/deta
00315                 case 1:
00316                   {
00317                     switch(i)
00318                       {
00319                       case 1:
00320                       case 3:
00321                       case 9:
00322                       case 11:
00323                         return RealGradient();
00324                       case 0:
00325                         {
00326                           if( elem->point(0) > elem->point(1) )
00327                             return RealGradient( -0.125*(-1.0+zeta), 0.0, 0.0 );
00328                           else
00329                             return RealGradient(  0.125*(-1.0+zeta), 0.0, 0.0 );
00330                         }
00331                       case 2:
00332                         {
00333                           if( elem->point(2) > elem->point(3) )
00334                             return RealGradient( 0.125*(1.0-zeta), 0.0, 0.0 );
00335                           else
00336                             return RealGradient( -0.125*(1.0-zeta), 0.0, 0.0 );
00337                         }
00338                       case 4:
00339                         {
00340                           if( elem->point(0) > elem->point(4) )
00341                             return RealGradient( 0.0, 0.0, -0.125*(-1.0+xi) );
00342                           else
00343                             return RealGradient( 0.0, 0.0,  0.125*(-1.0+xi) );
00344                         }
00345                       case 5:
00346                         {
00347                           if( elem->point(1) > elem->point(5) )
00348                             return RealGradient( 0.0, 0.0, -0.125*(-1.0-xi) );
00349                           else
00350                             return RealGradient( 0.0, 0.0,  0.125*(-1.0-xi) );
00351                         }
00352                       case 6:
00353                         {
00354                           if( elem->point(2) > elem->point(6) )
00355                             return RealGradient( 0.0, 0.0, -0.125*(1.0+xi) );
00356                           else
00357                             return RealGradient( 0.0, 0.0,  0.125*(1.0+xi) );
00358                         }
00359                       case 7:
00360                         {
00361                           if( elem->point(3) > elem->point(7) )
00362                             return RealGradient( 0.0, 0.0, -0.125*(1.0-xi) );
00363                           else
00364                             return RealGradient( 0.0, 0.0,  0.125*(1.0-xi) );
00365                         }
00366                       case 8:
00367                         {
00368                           if( elem->point(4) > elem->point(5) )
00369                             return RealGradient( -0.125*(-1.0-zeta), 0.0, 0.0 );
00370                           else
00371                             return RealGradient(  0.125*(-1.0-zeta), 0.0, 0.0 );
00372                         }
00373                       case 10:
00374                         {
00375                           if( elem->point(7) > elem->point(6) )
00376                             return RealGradient( -0.125*(1.0+zeta), 0.0, 0.0 );
00377                           else
00378                             return RealGradient(  0.125*(1.0+zeta), 0.0, 0.0 );
00379                         }
00380                       default:
00381                         libmesh_error_msg("Invalid i = " << i);
00382                       } // switch(i)
00383 
00384                   } // j=1
00385 
00386                   // d()/dzeta
00387                 case 2:
00388                   {
00389                     switch(i)
00390                       {
00391                       case 4:
00392                       case 5:
00393                       case 6:
00394                       case 7:
00395                         return RealGradient();
00396 
00397                       case 0:
00398                         {
00399                           if( elem->point(0) > elem->point(1) )
00400                             return RealGradient( -0.125*(-1.0+eta), 0.0, 0.0 );
00401                           else
00402                             return RealGradient(  0.125*(-1.0+eta), 0.0, 0.0 );
00403                         }
00404                       case 1:
00405                         {
00406                           if( elem->point(1) > elem->point(2) )
00407                             return RealGradient( 0.0, -0.125*(-1.0-xi), 0.0 );
00408                           else
00409                             return RealGradient( 0.0,  0.125*(-1.0-xi), 0.0 );
00410                         }
00411                       case 2:
00412                         {
00413                           if( elem->point(2) > elem->point(3) )
00414                             return RealGradient( 0.125*(-1.0-eta), 0.0, 0.0 );
00415                           else
00416                             return RealGradient( -0.125*(-1.0-eta), 0.0, 0.0 );
00417                         }
00418                       case 3:
00419                         {
00420                           if( elem->point(3) > elem->point(0) )
00421                             return RealGradient( 0.0, 0.125*(-1.0+xi), 0.0 );
00422                           else
00423                             return RealGradient( 0.0,  -0.125*(-1.0+xi), 0.0 );
00424                         }
00425                       case 8:
00426                         {
00427                           if( elem->point(4) > elem->point(5) )
00428                             return RealGradient( -0.125*(1.0-eta), 0.0, 0.0 );
00429                           else
00430                             return RealGradient(  0.125*(1.0-eta), 0.0, 0.0 );
00431                         }
00432                       case 9:
00433                         {
00434                           if( elem->point(5) > elem->point(6) )
00435                             return RealGradient( 0.0, -0.125*(1.0+xi), 0.0 );
00436                           else
00437                             return RealGradient( 0.0,  0.125*(1.0+xi), 0.0 );
00438                         }
00439                       case 10:
00440                         {
00441                           if( elem->point(7) > elem->point(6) )
00442                             return RealGradient( -0.125*(1.0+eta), 0.0, 0.0 );
00443                           else
00444                             return RealGradient(  0.125*(1.0+eta), 0.0, 0.0 );
00445                         }
00446                       case 11:
00447                         {
00448                           if( elem->point(4) > elem->point(7) )
00449                             return RealGradient( 0.0, -0.125*(1.0-xi), 0.0 );
00450                           else
00451                             return RealGradient( 0.0,  0.125*(1.0-xi), 0.0 );
00452                         }
00453                       default:
00454                         libmesh_error_msg("Invalid i = " << i);
00455                       } // switch(i)
00456 
00457                   } // j = 2
00458 
00459                 default:
00460                   libmesh_error_msg("Invalid j = " << j);
00461                 }
00462 
00463               return RealGradient();
00464             }
00465 
00466           case TET10:
00467             {
00468               libmesh_assert_less (i, 6);
00469 
00470               libmesh_not_implemented();
00471               return RealGradient();
00472             }
00473 
00474           default:
00475             libmesh_error_msg("ERROR: Unsupported 3D element type!: " << elem->type());
00476           }
00477       }
00478 
00479       // unsupported order
00480     default:
00481       libmesh_error_msg("ERROR: Unsupported 3D FE order!: " << totalorder);
00482     }
00483 
00484 #endif
00485 
00486   libmesh_error_msg("We'll never get here!");
00487   return RealGradient();
00488 }
00489 
00490 
00491 
00492 template <>
00493 RealGradient FE<3,NEDELEC_ONE>::shape_second_deriv(const ElemType,
00494                                                    const Order,
00495                                                    const unsigned int,
00496                                                    const unsigned int,
00497                                                    const Point&)
00498 {
00499   libmesh_error_msg("Nedelec elements require the element type \nbecause edge orientation is needed.");
00500   return RealGradient();
00501 }
00502 
00503 
00504 
00505 template <>
00506 RealGradient FE<3,NEDELEC_ONE>::shape_second_deriv(const Elem* elem,
00507                                                    const Order order,
00508                                                    const unsigned int i,
00509                                                    const unsigned int j,
00510                                                    const Point& libmesh_dbg_var(p))
00511 {
00512 #if LIBMESH_DIM == 3
00513 
00514   libmesh_assert(elem);
00515 
00516   // j = 0 ==> d^2 phi / dxi^2
00517   // j = 1 ==> d^2 phi / dxi deta
00518   // j = 2 ==> d^2 phi / deta^2
00519   // j = 3 ==> d^2 phi / dxi dzeta
00520   // j = 4 ==> d^2 phi / deta dzeta
00521   // j = 5 ==> d^2 phi / dzeta^2
00522   libmesh_assert_less (j, 6);
00523 
00524   const Order totalorder = static_cast<Order>(order + elem->p_level());
00525 
00526   switch (totalorder)
00527     {
00528       // linear Lagrange shape functions
00529     case FIRST:
00530       {
00531         switch (elem->type())
00532           {
00533           case HEX20:
00534           case HEX27:
00535             {
00536               libmesh_assert_less (i, 12);
00537 
00538 #ifndef NDEBUG
00539               const Real xi   = p(0);
00540               const Real eta  = p(1);
00541               const Real zeta = p(2);
00542 #endif
00543 
00544               libmesh_assert_less_equal ( std::fabs(xi),   1.0+TOLERANCE );
00545               libmesh_assert_less_equal ( std::fabs(eta),  1.0+TOLERANCE );
00546               libmesh_assert_less_equal ( std::fabs(zeta), 1.0+TOLERANCE );
00547 
00548               switch (j)
00549                 {
00550                   // d^2()/dxi^2
00551                 case 0:
00552                   {
00553                     // All d^2()/dxi^2 derivatives for linear hexes are zero.
00554                     return RealGradient();
00555                   } // j=0
00556 
00557                   // d^2()/dxideta
00558                 case 1:
00559                   {
00560                     switch(i)
00561                       {
00562                       case 0:
00563                       case 1:
00564                       case 2:
00565                       case 3:
00566                       case 8:
00567                       case 9:
00568                       case 10:
00569                       case 11:
00570                         return RealGradient();
00571                       case 4:
00572                         {
00573                           if( elem->point(0) > elem->point(4) )
00574                             return RealGradient( 0.0, 0.0, -0.125 );
00575                           else
00576                             return RealGradient( 0.0, 0.0,  0.125 );
00577                         }
00578                       case 5:
00579                         {
00580                           if( elem->point(1) > elem->point(5) )
00581                             return RealGradient( 0.0, 0.0,  0.125 );
00582                           else
00583                             return RealGradient( 0.0, 0.0, -0.125 );
00584                         }
00585                       case 6:
00586                         {
00587                           if( elem->point(2) > elem->point(6) )
00588                             return RealGradient( 0.0, 0.0, -0.125 );
00589                           else
00590                             return RealGradient( 0.0, 0.0,  0.125 );
00591                         }
00592                       case 7:
00593                         {
00594                           if( elem->point(3) > elem->point(7) )
00595                             return RealGradient( 0.0, 0.0,  0.125 );
00596                           else
00597                             return RealGradient( 0.0, 0.0, -0.125 );
00598                         }
00599                       default:
00600                         libmesh_error_msg("Invalid i = " << i);
00601                       } // switch(i)
00602 
00603                   } // j=1
00604 
00605                   // d^2()/deta^2
00606                 case 2:
00607                   {
00608                     // All d^2()/deta^2 derivatives for linear hexes are zero.
00609                     return RealGradient();
00610                   } // j = 2
00611 
00612                   // d^2()/dxidzeta
00613                 case 3:
00614                   {
00615                     switch(i)
00616                       {
00617                       case 0:
00618                       case 2:
00619                       case 4:
00620                       case 5:
00621                       case 6:
00622                       case 7:
00623                       case 8:
00624                       case 10:
00625                         return RealGradient();
00626 
00627                       case 1:
00628                         {
00629                           if( elem->point(1) > elem->point(2) )
00630                             return RealGradient( 0.0,  0.125 );
00631                           else
00632                             return RealGradient( 0.0, -0.125 );
00633                         }
00634                       case 3:
00635                         {
00636                           if( elem->point(3) > elem->point(0) )
00637                             return RealGradient( 0.0, -0.125 );
00638                           else
00639                             return RealGradient( 0.0,  0.125 );
00640                         }
00641                       case 9:
00642                         {
00643                           if( elem->point(5) > elem->point(6) )
00644                             return RealGradient( 0.0, -0.125, 0.0 );
00645                           else
00646                             return RealGradient( 0.0,  0.125, 0.0 );
00647                         }
00648                       case 11:
00649                         {
00650                           if( elem->point(4) > elem->point(7) )
00651                             return RealGradient( 0.0,  0.125, 0.0 );
00652                           else
00653                             return RealGradient( 0.0, -0.125, 0.0 );
00654                         }
00655                       default:
00656                         libmesh_error_msg("Invalid i = " << i);
00657                       } // switch(i)
00658 
00659                   } // j = 3
00660 
00661                   // d^2()/detadzeta
00662                 case 4:
00663                   {
00664                     switch(i)
00665                       {
00666                       case 1:
00667                       case 3:
00668                       case 4:
00669                       case 5:
00670                       case 6:
00671                       case 7:
00672                       case 9:
00673                       case 11:
00674                         return RealGradient();
00675 
00676                       case 0:
00677                         {
00678                           if( elem->point(0) > elem->point(1) )
00679                             return RealGradient( -0.125, 0.0, 0.0 );
00680                           else
00681                             return RealGradient(  0.125, 0.0, 0.0 );
00682                         }
00683                       case 2:
00684                         {
00685                           if( elem->point(2) > elem->point(3) )
00686                             return RealGradient(  0.125, 0.0, 0.0 );
00687                           else
00688                             return RealGradient( -0.125, 0.0, 0.0 );
00689                         }
00690                       case 8:
00691                         {
00692                           if( elem->point(4) > elem->point(5) )
00693                             return RealGradient(  0.125, 0.0, 0.0 );
00694                           else
00695                             return RealGradient( -0.125, 0.0, 0.0 );
00696                         }
00697                       case 10:
00698                         {
00699                           if( elem->point(7) > elem->point(6) )
00700                             return RealGradient( -0.125, 0.0, 0.0 );
00701                           else
00702                             return RealGradient(  0.125, 0.0, 0.0 );
00703                         }
00704                       default:
00705                         libmesh_error_msg("Invalid i = " << i);
00706                       } // switch(i)
00707 
00708                   } // j = 4
00709 
00710                   // d^2()/dzeta^2
00711                 case 5:
00712                   {
00713                     // All d^2()/dzeta^2 derivatives for linear hexes are zero.
00714                     return RealGradient();
00715                   } // j = 5
00716 
00717                 default:
00718                   libmesh_error_msg("Invalid j = " << j);
00719                 }
00720 
00721               return RealGradient();
00722             }
00723 
00724           case TET10:
00725             {
00726               libmesh_assert_less (i, 6);
00727 
00728               libmesh_not_implemented();
00729               return RealGradient();
00730             }
00731 
00732           default:
00733             libmesh_error_msg("ERROR: Unsupported 3D element type!: " << elem->type());
00734 
00735           } //switch(type)
00736 
00737       } // case FIRST:
00738       // unsupported order
00739     default:
00740       libmesh_error_msg("ERROR: Unsupported 3D FE order!: " << totalorder);
00741     }
00742 
00743 #endif
00744 
00745   libmesh_error_msg("We'll never get here!");
00746   return RealGradient();
00747 }
00748 
00749 } // namespace libMesh