$extrastylesheet
fe_lagrange_shape_2D.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 
00029 
00030 
00031 template <>
00032 Real FE<2,LAGRANGE>::shape(const ElemType type,
00033                            const Order order,
00034                            const unsigned int i,
00035                            const Point& p)
00036 {
00037 #if LIBMESH_DIM > 1
00038 
00039   switch (order)
00040     {
00041       // linear Lagrange shape functions
00042     case FIRST:
00043       {
00044         switch (type)
00045           {
00046           case QUAD4:
00047           case QUAD8:
00048           case QUAD9:
00049             {
00050               // Compute quad shape functions as a tensor-product
00051               const Real xi  = p(0);
00052               const Real eta = p(1);
00053 
00054               libmesh_assert_less (i, 4);
00055 
00056               //                                0  1  2  3
00057               static const unsigned int i0[] = {0, 1, 1, 0};
00058               static const unsigned int i1[] = {0, 0, 1, 1};
00059 
00060               return (FE<1,LAGRANGE>::shape(EDGE2, FIRST, i0[i], xi)*
00061                       FE<1,LAGRANGE>::shape(EDGE2, FIRST, i1[i], eta));
00062             }
00063 
00064           case TRI3:
00065           case TRI6:
00066             {
00067               const Real zeta1 = p(0);
00068               const Real zeta2 = p(1);
00069               const Real zeta0 = 1. - zeta1 - zeta2;
00070 
00071               libmesh_assert_less (i, 3);
00072 
00073               switch(i)
00074                 {
00075                 case 0:
00076                   return zeta0;
00077 
00078                 case 1:
00079                   return zeta1;
00080 
00081                 case 2:
00082                   return zeta2;
00083 
00084                 default:
00085                   libmesh_error_msg("Invalid shape function index i = " << i);
00086                 }
00087             }
00088 
00089           default:
00090             libmesh_error_msg("ERROR: Unsupported 2D element type: " << type);
00091           }
00092       }
00093 
00094 
00095       // quadratic Lagrange shape functions
00096     case SECOND:
00097       {
00098         switch (type)
00099           {
00100           case QUAD8:
00101             {
00102               const Real xi  = p(0);
00103               const Real eta = p(1);
00104 
00105               libmesh_assert_less (i, 8);
00106 
00107               switch (i)
00108                 {
00109                 case 0:
00110                   return .25*(1. - xi)*(1. - eta)*(-1. - xi - eta);
00111 
00112                 case 1:
00113                   return .25*(1. + xi)*(1. - eta)*(-1. + xi - eta);
00114 
00115                 case 2:
00116                   return .25*(1. + xi)*(1. + eta)*(-1. + xi + eta);
00117 
00118                 case 3:
00119                   return .25*(1. - xi)*(1. + eta)*(-1. - xi + eta);
00120 
00121                 case 4:
00122                   return .5*(1. - xi*xi)*(1. - eta);
00123 
00124                 case 5:
00125                   return .5*(1. + xi)*(1. - eta*eta);
00126 
00127                 case 6:
00128                   return .5*(1. - xi*xi)*(1. + eta);
00129 
00130                 case 7:
00131                   return .5*(1. - xi)*(1. - eta*eta);
00132 
00133                 default:
00134                   libmesh_error_msg("Invalid shape function index i = " << i);
00135                 }
00136             }
00137 
00138           case QUAD9:
00139             {
00140               // Compute quad shape functions as a tensor-product
00141               const Real xi  = p(0);
00142               const Real eta = p(1);
00143 
00144               libmesh_assert_less (i, 9);
00145 
00146               //                                0  1  2  3  4  5  6  7  8
00147               static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
00148               static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
00149 
00150               return (FE<1,LAGRANGE>::shape(EDGE3, SECOND, i0[i], xi)*
00151                       FE<1,LAGRANGE>::shape(EDGE3, SECOND, i1[i], eta));
00152             }
00153 
00154           case TRI6:
00155             {
00156               const Real zeta1 = p(0);
00157               const Real zeta2 = p(1);
00158               const Real zeta0 = 1. - zeta1 - zeta2;
00159 
00160               libmesh_assert_less (i, 6);
00161 
00162               switch(i)
00163                 {
00164                 case 0:
00165                   return 2.*zeta0*(zeta0-0.5);
00166 
00167                 case 1:
00168                   return 2.*zeta1*(zeta1-0.5);
00169 
00170                 case 2:
00171                   return 2.*zeta2*(zeta2-0.5);
00172 
00173                 case 3:
00174                   return 4.*zeta0*zeta1;
00175 
00176                 case 4:
00177                   return 4.*zeta1*zeta2;
00178 
00179                 case 5:
00180                   return 4.*zeta2*zeta0;
00181 
00182                 default:
00183                   libmesh_error_msg("Invalid shape function index i = " << i);
00184                 }
00185             }
00186 
00187           default:
00188             libmesh_error_msg("ERROR: Unsupported 2D element type: " << type);
00189           }
00190       }
00191 
00192 
00193 
00194       // unsupported order
00195     default:
00196       libmesh_error_msg("ERROR: Unsupported 2D FE order: " << order);
00197     }
00198 
00199   libmesh_error_msg("We'll never get here!");
00200 #endif // LIBMESH_DIM > 1
00201   return 0.;
00202 }
00203 
00204 
00205 
00206 template <>
00207 Real FE<2,LAGRANGE>::shape(const Elem* elem,
00208                            const Order order,
00209                            const unsigned int i,
00210                            const Point& p)
00211 {
00212   libmesh_assert(elem);
00213 
00214   // call the orientation-independent shape functions
00215   return FE<2,LAGRANGE>::shape(elem->type(), static_cast<Order>(order + elem->p_level()), i, p);
00216 }
00217 
00218 
00219 
00220 template <>
00221 Real FE<2,LAGRANGE>::shape_deriv(const ElemType type,
00222                                  const Order order,
00223                                  const unsigned int i,
00224                                  const unsigned int j,
00225                                  const Point& p)
00226 {
00227 #if LIBMESH_DIM > 1
00228 
00229 
00230   libmesh_assert_less (j, 2);
00231 
00232   switch (order)
00233     {
00234       // linear Lagrange shape functions
00235     case FIRST:
00236       {
00237         switch (type)
00238           {
00239           case QUAD4:
00240           case QUAD8:
00241           case QUAD9:
00242             {
00243               // Compute quad shape functions as a tensor-product
00244               const Real xi  = p(0);
00245               const Real eta = p(1);
00246 
00247               libmesh_assert_less (i, 4);
00248 
00249               //                                0  1  2  3
00250               static const unsigned int i0[] = {0, 1, 1, 0};
00251               static const unsigned int i1[] = {0, 0, 1, 1};
00252 
00253               switch (j)
00254                 {
00255                   // d()/dxi
00256                 case 0:
00257                   return (FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i0[i], 0, xi)*
00258                           FE<1,LAGRANGE>::shape      (EDGE2, FIRST, i1[i], eta));
00259 
00260                   // d()/deta
00261                 case 1:
00262                   return (FE<1,LAGRANGE>::shape      (EDGE2, FIRST, i0[i], xi)*
00263                           FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i1[i], 0, eta));
00264 
00265                 default:
00266                   libmesh_error_msg("ERROR: Invalid derivative index j = " << j);
00267                 }
00268             }
00269 
00270           case TRI3:
00271           case TRI6:
00272             {
00273               libmesh_assert_less (i, 3);
00274 
00275               const Real dzeta0dxi  = -1.;
00276               const Real dzeta1dxi  = 1.;
00277               const Real dzeta2dxi  = 0.;
00278 
00279               const Real dzeta0deta = -1.;
00280               const Real dzeta1deta = 0.;
00281               const Real dzeta2deta = 1.;
00282 
00283               switch (j)
00284                 {
00285                   // d()/dxi
00286                 case 0:
00287                   {
00288                     switch(i)
00289                       {
00290                       case 0:
00291                         return dzeta0dxi;
00292 
00293                       case 1:
00294                         return dzeta1dxi;
00295 
00296                       case 2:
00297                         return dzeta2dxi;
00298 
00299                       default:
00300                         libmesh_error_msg("Invalid shape function index i = " << i);
00301                       }
00302                   }
00303                   // d()/deta
00304                 case 1:
00305                   {
00306                     switch(i)
00307                       {
00308                       case 0:
00309                         return dzeta0deta;
00310 
00311                       case 1:
00312                         return dzeta1deta;
00313 
00314                       case 2:
00315                         return dzeta2deta;
00316 
00317                       default:
00318                         libmesh_error_msg("Invalid shape function index i = " << i);
00319                       }
00320                   }
00321                 default:
00322                   libmesh_error_msg("ERROR: Invalid derivative index j = " << j);
00323                 }
00324             }
00325 
00326           default:
00327             libmesh_error_msg("ERROR: Unsupported 2D element type: " << type);
00328           }
00329       }
00330 
00331 
00332       // quadratic Lagrange shape functions
00333     case SECOND:
00334       {
00335         switch (type)
00336           {
00337           case QUAD8:
00338             {
00339               const Real xi  = p(0);
00340               const Real eta = p(1);
00341 
00342               libmesh_assert_less (i, 8);
00343 
00344               switch (j)
00345                 {
00346                   // d/dxi
00347                 case 0:
00348                   switch (i)
00349                     {
00350                     case 0:
00351                       return .25*(1. - eta)*((1. - xi)*(-1.) +
00352                                              (-1.)*(-1. - xi - eta));
00353 
00354                     case 1:
00355                       return .25*(1. - eta)*((1. + xi)*(1.) +
00356                                              (1.)*(-1. + xi - eta));
00357 
00358                     case 2:
00359                       return .25*(1. + eta)*((1. + xi)*(1.) +
00360                                              (1.)*(-1. + xi + eta));
00361 
00362                     case 3:
00363                       return .25*(1. + eta)*((1. - xi)*(-1.) +
00364                                              (-1.)*(-1. - xi + eta));
00365 
00366                     case 4:
00367                       return .5*(-2.*xi)*(1. - eta);
00368 
00369                     case 5:
00370                       return .5*(1.)*(1. - eta*eta);
00371 
00372                     case 6:
00373                       return .5*(-2.*xi)*(1. + eta);
00374 
00375                     case 7:
00376                       return .5*(-1.)*(1. - eta*eta);
00377 
00378                     default:
00379                       libmesh_error_msg("Invalid shape function index i = " << i);
00380                     }
00381 
00382                   // d/deta
00383                 case 1:
00384                   switch (i)
00385                     {
00386                     case 0:
00387                       return .25*(1. - xi)*((1. - eta)*(-1.) +
00388                                             (-1.)*(-1. - xi - eta));
00389 
00390                     case 1:
00391                       return .25*(1. + xi)*((1. - eta)*(-1.) +
00392                                             (-1.)*(-1. + xi - eta));
00393 
00394                     case 2:
00395                       return .25*(1. + xi)*((1. + eta)*(1.) +
00396                                             (1.)*(-1. + xi + eta));
00397 
00398                     case 3:
00399                       return .25*(1. - xi)*((1. + eta)*(1.) +
00400                                             (1.)*(-1. - xi + eta));
00401 
00402                     case 4:
00403                       return .5*(1. - xi*xi)*(-1.);
00404 
00405                     case 5:
00406                       return .5*(1. + xi)*(-2.*eta);
00407 
00408                     case 6:
00409                       return .5*(1. - xi*xi)*(1.);
00410 
00411                     case 7:
00412                       return .5*(1. - xi)*(-2.*eta);
00413 
00414                     default:
00415                       libmesh_error_msg("Invalid shape function index i = " << i);
00416                     }
00417 
00418                 default:
00419                   libmesh_error_msg("ERROR: Invalid derivative index j = " << j);
00420                 }
00421             }
00422 
00423           case QUAD9:
00424             {
00425               // Compute quad shape functions as a tensor-product
00426               const Real xi  = p(0);
00427               const Real eta = p(1);
00428 
00429               libmesh_assert_less (i, 9);
00430 
00431               //                                0  1  2  3  4  5  6  7  8
00432               static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
00433               static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
00434 
00435               switch (j)
00436                 {
00437                   // d()/dxi
00438                 case 0:
00439                   return (FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i0[i], 0, xi)*
00440                           FE<1,LAGRANGE>::shape      (EDGE3, SECOND, i1[i], eta));
00441 
00442                   // d()/deta
00443                 case 1:
00444                   return (FE<1,LAGRANGE>::shape      (EDGE3, SECOND, i0[i], xi)*
00445                           FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i1[i], 0, eta));
00446 
00447                 default:
00448                   libmesh_error_msg("ERROR: Invalid derivative index j = " << j);
00449                 }
00450             }
00451 
00452           case TRI6:
00453             {
00454               libmesh_assert_less (i, 6);
00455 
00456               const Real zeta1 = p(0);
00457               const Real zeta2 = p(1);
00458               const Real zeta0 = 1. - zeta1 - zeta2;
00459 
00460               const Real dzeta0dxi  = -1.;
00461               const Real dzeta1dxi  = 1.;
00462               const Real dzeta2dxi  = 0.;
00463 
00464               const Real dzeta0deta = -1.;
00465               const Real dzeta1deta = 0.;
00466               const Real dzeta2deta = 1.;
00467 
00468               switch(j)
00469                 {
00470                 case 0:
00471                   {
00472                     switch(i)
00473                       {
00474                       case 0:
00475                         return (4.*zeta0-1.)*dzeta0dxi;
00476 
00477                       case 1:
00478                         return (4.*zeta1-1.)*dzeta1dxi;
00479 
00480                       case 2:
00481                         return (4.*zeta2-1.)*dzeta2dxi;
00482 
00483                       case 3:
00484                         return 4.*zeta1*dzeta0dxi + 4.*zeta0*dzeta1dxi;
00485 
00486                       case 4:
00487                         return 4.*zeta2*dzeta1dxi + 4.*zeta1*dzeta2dxi;
00488 
00489                       case 5:
00490                         return 4.*zeta2*dzeta0dxi + 4*zeta0*dzeta2dxi;
00491 
00492                       default:
00493                         libmesh_error_msg("Invalid shape function index i = " << i);
00494                       }
00495                   }
00496 
00497                 case 1:
00498                   {
00499                     switch(i)
00500                       {
00501                       case 0:
00502                         return (4.*zeta0-1.)*dzeta0deta;
00503 
00504                       case 1:
00505                         return (4.*zeta1-1.)*dzeta1deta;
00506 
00507                       case 2:
00508                         return (4.*zeta2-1.)*dzeta2deta;
00509 
00510                       case 3:
00511                         return 4.*zeta1*dzeta0deta + 4.*zeta0*dzeta1deta;
00512 
00513                       case 4:
00514                         return 4.*zeta2*dzeta1deta + 4.*zeta1*dzeta2deta;
00515 
00516                       case 5:
00517                         return 4.*zeta2*dzeta0deta + 4*zeta0*dzeta2deta;
00518 
00519                       default:
00520                         libmesh_error_msg("Invalid shape function index i = " << i);
00521                       }
00522                   }
00523                 default:
00524                   libmesh_error_msg("ERROR: Invalid derivative index j = " << j);
00525                 }
00526             }
00527 
00528           default:
00529             libmesh_error_msg("ERROR: Unsupported 2D element type: " << type);
00530           }
00531       }
00532 
00533       // unsupported order
00534     default:
00535       libmesh_error_msg("ERROR: Unsupported 2D FE order: " << order);
00536     }
00537 
00538 
00539   libmesh_error_msg("We'll never get here!");
00540 #endif // LIBMESH_DIM > 1
00541   return 0.;
00542 }
00543 
00544 
00545 
00546 template <>
00547 Real FE<2,LAGRANGE>::shape_deriv(const Elem* elem,
00548                                  const Order order,
00549                                  const unsigned int i,
00550                                  const unsigned int j,
00551                                  const Point& p)
00552 {
00553   libmesh_assert(elem);
00554 
00555 
00556   // call the orientation-independent shape functions
00557   return FE<2,LAGRANGE>::shape_deriv(elem->type(), static_cast<Order>(order + elem->p_level()), i, j, p);
00558 }
00559 
00560 
00561 
00562 
00563 template <>
00564 Real FE<2,LAGRANGE>::shape_second_deriv(const ElemType type,
00565                                         const Order order,
00566                                         const unsigned int i,
00567                                         const unsigned int j,
00568                                         const Point& p)
00569 {
00570 #if LIBMESH_DIM > 1
00571 
00572   // j = 0 ==> d^2 phi / dxi^2
00573   // j = 1 ==> d^2 phi / dxi deta
00574   // j = 2 ==> d^2 phi / deta^2
00575   libmesh_assert_less (j, 3);
00576 
00577   switch (order)
00578     {
00579       // linear Lagrange shape functions
00580     case FIRST:
00581       {
00582         switch (type)
00583           {
00584           case QUAD4:
00585           case QUAD8:
00586           case QUAD9:
00587             {
00588               // Compute quad shape functions as a tensor-product
00589               const Real xi  = p(0);
00590               const Real eta = p(1);
00591 
00592               libmesh_assert_less (i, 4);
00593 
00594               //                                0  1  2  3
00595               static const unsigned int i0[] = {0, 1, 1, 0};
00596               static const unsigned int i1[] = {0, 0, 1, 1};
00597 
00598               switch (j)
00599                 {
00600                   // d^2() / dxi^2
00601                 case 0:
00602                   return 0.;
00603 
00604                   // d^2() / dxi deta
00605                 case 1:
00606                   return (FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i0[i], 0, xi)*
00607                           FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i1[i], 0, eta));
00608 
00609                   // d^2() / deta^2
00610                 case 2:
00611                   return 0.;
00612 
00613                 default:
00614                   libmesh_error_msg("ERROR: Invalid derivative index j = " << j);
00615                 }
00616             }
00617 
00618           case TRI3:
00619           case TRI6:
00620             {
00621               // All second derivatives for linear triangles are zero.
00622               return 0.;
00623             }
00624 
00625           default:
00626             libmesh_error_msg("ERROR: Unsupported 2D element type: " << type);
00627 
00628           } // end switch (type)
00629       } // end case FIRST
00630 
00631 
00632       // quadratic Lagrange shape functions
00633     case SECOND:
00634       {
00635         switch (type)
00636           {
00637           case QUAD8:
00638             {
00639               const Real xi  = p(0);
00640               const Real eta = p(1);
00641 
00642               libmesh_assert_less (j, 3);
00643 
00644               switch (j)
00645                 {
00646                   // d^2() / dxi^2
00647                 case 0:
00648                   {
00649                     switch (i)
00650                       {
00651                       case 0:
00652                       case 1:
00653                         return 0.5*(1.-eta);
00654 
00655                       case 2:
00656                       case 3:
00657                         return 0.5*(1.+eta);
00658 
00659                       case 4:
00660                         return eta - 1.;
00661 
00662                       case 5:
00663                       case 7:
00664                         return 0.0;
00665 
00666                       case 6:
00667                         return -1. - eta;
00668 
00669                       default:
00670                         libmesh_error_msg("Invalid shape function index i = " << i);
00671                       }
00672                   }
00673 
00674                   // d^2() / dxi deta
00675                 case 1:
00676                   {
00677                     switch (i)
00678                       {
00679                       case 0:
00680                         return 0.25*( 1. - 2.*xi - 2.*eta);
00681 
00682                       case 1:
00683                         return 0.25*(-1. - 2.*xi + 2.*eta);
00684 
00685                       case 2:
00686                         return 0.25*( 1. + 2.*xi + 2.*eta);
00687 
00688                       case 3:
00689                         return 0.25*(-1. + 2.*xi - 2.*eta);
00690 
00691                       case 4:
00692                         return xi;
00693 
00694                       case 5:
00695                         return -eta;
00696 
00697                       case 6:
00698                         return -xi;
00699 
00700                       case 7:
00701                         return eta;
00702 
00703                       default:
00704                         libmesh_error_msg("Invalid shape function index i = " << i);
00705                       }
00706                   }
00707 
00708                   // d^2() / deta^2
00709                 case 2:
00710                   {
00711                     switch (i)
00712                       {
00713                       case 0:
00714                       case 3:
00715                         return 0.5*(1.-xi);
00716 
00717                       case 1:
00718                       case 2:
00719                         return 0.5*(1.+xi);
00720 
00721                       case 4:
00722                       case 6:
00723                         return 0.0;
00724 
00725                       case 5:
00726                         return -1.0 - xi;
00727 
00728                       case 7:
00729                         return xi - 1.0;
00730 
00731                       default:
00732                         libmesh_error_msg("Invalid shape function index i = " << i);
00733                       }
00734                   }
00735 
00736                 default:
00737                   libmesh_error_msg("ERROR: Invalid derivative index j = " << j);
00738                 } // end switch (j)
00739             } // end case QUAD8
00740 
00741           case QUAD9:
00742             {
00743               // Compute QUAD9 second derivatives as tensor product
00744               const Real xi  = p(0);
00745               const Real eta = p(1);
00746 
00747               libmesh_assert_less (i, 9);
00748 
00749               //                                0  1  2  3  4  5  6  7  8
00750               static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
00751               static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
00752 
00753               switch (j)
00754                 {
00755                   // d^2() / dxi^2
00756                 case 0:
00757                   return (FE<1,LAGRANGE>::shape_second_deriv(EDGE3, SECOND, i0[i], 0, xi)*
00758                           FE<1,LAGRANGE>::shape             (EDGE3, SECOND, i1[i], eta));
00759 
00760                   // d^2() / dxi deta
00761                 case 1:
00762                   return (FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i0[i], 0, xi)*
00763                           FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i1[i], 0, eta));
00764 
00765                   // d^2() / deta^2
00766                 case 2:
00767                   return (FE<1,LAGRANGE>::shape             (EDGE3, SECOND, i0[i], xi)*
00768                           FE<1,LAGRANGE>::shape_second_deriv(EDGE3, SECOND, i1[i], 0, eta));
00769 
00770                 default:
00771                   libmesh_error_msg("ERROR: Invalid derivative index j = " << j);
00772                 }  // end switch (j)
00773             } // end case QUAD9
00774 
00775           case TRI6:
00776             {
00777               const Real dzeta0dxi  = -1.;
00778               const Real dzeta1dxi  = 1.;
00779               const Real dzeta2dxi  = 0.;
00780 
00781               const Real dzeta0deta = -1.;
00782               const Real dzeta1deta = 0.;
00783               const Real dzeta2deta = 1.;
00784 
00785               libmesh_assert_less (j, 3);
00786 
00787               switch (j)
00788                 {
00789                   // d^2() / dxi^2
00790                 case 0:
00791                   {
00792                     switch (i)
00793                       {
00794                       case 0:
00795                         return 4.*dzeta0dxi*dzeta0dxi;
00796 
00797                       case 1:
00798                         return 4.*dzeta1dxi*dzeta1dxi;
00799 
00800                       case 2:
00801                         return 4.*dzeta2dxi*dzeta2dxi;
00802 
00803                       case 3:
00804                         return 8.*dzeta0dxi*dzeta1dxi;
00805 
00806                       case 4:
00807                         return 8.*dzeta1dxi*dzeta2dxi;
00808 
00809                       case 5:
00810                         return 8.*dzeta0dxi*dzeta2dxi;
00811 
00812                       default:
00813                         libmesh_error_msg("Invalid shape function index i = " << i);
00814                       }
00815                   }
00816 
00817                   // d^2() / dxi deta
00818                 case 1:
00819                   {
00820                     switch (i)
00821                       {
00822                       case 0:
00823                         return 4.*dzeta0dxi*dzeta0deta;
00824 
00825                       case 1:
00826                         return 4.*dzeta1dxi*dzeta1deta;
00827 
00828                       case 2:
00829                         return 4.*dzeta2dxi*dzeta2deta;
00830 
00831                       case 3:
00832                         return 4.*dzeta1deta*dzeta0dxi + 4.*dzeta0deta*dzeta1dxi;
00833 
00834                       case 4:
00835                         return 4.*dzeta2deta*dzeta1dxi + 4.*dzeta1deta*dzeta2dxi;
00836 
00837                       case 5:
00838                         return 4.*dzeta2deta*dzeta0dxi + 4.*dzeta0deta*dzeta2dxi;
00839 
00840                       default:
00841                         libmesh_error_msg("Invalid shape function index i = " << i);
00842                       }
00843                   }
00844 
00845                   // d^2() / deta^2
00846                 case 2:
00847                   {
00848                     switch (i)
00849                       {
00850                       case 0:
00851                         return 4.*dzeta0deta*dzeta0deta;
00852 
00853                       case 1:
00854                         return 4.*dzeta1deta*dzeta1deta;
00855 
00856                       case 2:
00857                         return 4.*dzeta2deta*dzeta2deta;
00858 
00859                       case 3:
00860                         return 8.*dzeta0deta*dzeta1deta;
00861 
00862                       case 4:
00863                         return 8.*dzeta1deta*dzeta2deta;
00864 
00865                       case 5:
00866                         return 8.*dzeta0deta*dzeta2deta;
00867 
00868                       default:
00869                         libmesh_error_msg("Invalid shape function index i = " << i);
00870                       }
00871                   }
00872 
00873                 default:
00874                   libmesh_error_msg("ERROR: Invalid derivative index j = " << j);
00875                 } // end switch (j)
00876             }  // end case TRI6
00877 
00878           default:
00879             libmesh_error_msg("ERROR: Unsupported 2D element type: " << type);
00880           }
00881       } // end case SECOND
00882 
00883 
00884 
00885       // unsupported order
00886     default:
00887       libmesh_error_msg("ERROR: Unsupported 2D FE order: " << order);
00888 
00889     } // end switch (order)
00890 
00891   libmesh_error_msg("We'll never get here!");
00892 #endif // LIBMESH_DIM > 1
00893   return 0.;
00894 }
00895 
00896 
00897 
00898 template <>
00899 Real FE<2,LAGRANGE>::shape_second_deriv(const Elem* elem,
00900                                         const Order order,
00901                                         const unsigned int i,
00902                                         const unsigned int j,
00903                                         const Point& p)
00904 {
00905   libmesh_assert(elem);
00906 
00907   // call the orientation-independent shape functions
00908   return FE<2,LAGRANGE>::shape_second_deriv(elem->type(), static_cast<Order>(order + elem->p_level()), i, j, p);
00909 }
00910 
00911 } // namespace libMesh