$extrastylesheet
fe_bernstein_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++ includes
00020 
00021 
00022 // Local includes
00023 #include "libmesh/libmesh_config.h"
00024 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
00025 
00026 #include "libmesh/fe.h"
00027 #include "libmesh/elem.h"
00028 
00029 
00030 namespace libMesh
00031 {
00032 
00033 
00034 
00035 template <>
00036 Real FE<3,BERNSTEIN>::shape(const ElemType,
00037                             const Order,
00038                             const unsigned int,
00039                             const Point&)
00040 {
00041   libmesh_error_msg("Bernstein polynomials require the element type \nbecause edge and face orientation is needed.");
00042   return 0.;
00043 }
00044 
00045 
00046 
00047 template <>
00048 Real FE<3,BERNSTEIN>::shape(const Elem* elem,
00049                             const Order order,
00050                             const unsigned int i,
00051                             const Point& p)
00052 {
00053 
00054 #if LIBMESH_DIM == 3
00055 
00056   libmesh_assert(elem);
00057   const ElemType type = elem->type();
00058 
00059   const Order totalorder = static_cast<Order>(order + elem->p_level());
00060 
00061   switch (totalorder)
00062     {
00063       // 1st order Bernstein.
00064     case FIRST:
00065       {
00066         switch (type)
00067           {
00068 
00069             // Bernstein shape functions on the tetrahedron.
00070           case TET4:
00071           case TET10:
00072             {
00073               libmesh_assert_less (i, 4);
00074 
00075               // Area coordinates
00076               const Real zeta1 = p(0);
00077               const Real zeta2 = p(1);
00078               const Real zeta3 = p(2);
00079               const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
00080 
00081               switch(i)
00082                 {
00083                 case  0:  return zeta0;
00084                 case  1:  return zeta1;
00085                 case  2:  return zeta2;
00086                 case  3:  return zeta3;
00087 
00088                 default:
00089                   libmesh_error_msg("Invalid shape function index i = " << i);
00090                 }
00091             }
00092 
00093             // Bernstein shape functions on the hexahedral.
00094           case HEX20:
00095           case HEX27:
00096             {
00097               libmesh_assert_less (i, 8);
00098 
00099               // Compute hex shape functions as a tensor-product
00100               const Real xi   = p(0);
00101               const Real eta  = p(1);
00102               const Real zeta = p(2);
00103 
00104               // The only way to make any sense of this
00105               // is to look at the mgflo/mg2/mgf documentation
00106               // and make the cut-out cube!
00107               //                                0  1  2  3  4  5  6  7
00108               static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0};
00109               static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1};
00110               static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1};
00111 
00112               return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
00113                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta)*
00114                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[i], zeta));
00115             }
00116 
00117 
00118           default:
00119             libmesh_error_msg("Invalid element type = " << type);
00120           }
00121       }
00122 
00123 
00124 
00125 
00126     case SECOND:
00127       {
00128         switch (type)
00129           {
00130 
00131             // Bernstein shape functions on the tetrahedron.
00132           case TET10:
00133             {
00134               libmesh_assert_less (i, 10);
00135 
00136               // Area coordinates
00137               const Real zeta1 = p(0);
00138               const Real zeta2 = p(1);
00139               const Real zeta3 = p(2);
00140               const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
00141 
00142               switch(i)
00143                 {
00144                 case  0:  return zeta0*zeta0;
00145                 case  1:  return zeta1*zeta1;
00146                 case  2:  return zeta2*zeta2;
00147                 case  3:  return zeta3*zeta3;
00148                 case  4:  return 2.*zeta0*zeta1;
00149                 case  5:  return 2.*zeta1*zeta2;
00150                 case  6:  return 2.*zeta0*zeta2;
00151                 case  7:  return 2.*zeta3*zeta0;
00152                 case  8:  return 2.*zeta1*zeta3;
00153                 case  9:  return 2.*zeta2*zeta3;
00154 
00155                 default:
00156                   libmesh_error_msg("Invalid shape function index i = " << i);
00157                 }
00158             }
00159 
00160             // Bernstein shape functions on the 20-noded hexahedral.
00161           case HEX20:
00162             {
00163               libmesh_assert_less (i, 20);
00164 
00165               // Compute hex shape functions as a tensor-product
00166               const Real xi   = p(0);
00167               const Real eta  = p(1);
00168               const Real zeta = p(2);
00169 
00170               // The only way to make any sense of this
00171               // is to look at the mgflo/mg2/mgf documentation
00172               // and make the cut-out cube!
00173               //                                0      1      2      3      4      5      6      7      8      9      10     11     12     13     14     15     16     17     18     19  20 21 22 23 24 25 26
00174               static const unsigned int i0[] = {0,     1,     1,     0,     0,     1,     1,     0,     2,     1,     2,     0,     0,     1,     1,     0,     2,     1,     2,     0,  2, 2, 1, 2, 0, 2, 2};
00175               static const unsigned int i1[] = {0,     0,     1,     1,     0,     0,     1,     1,     0,     2,     1,     2,     0,     0,     1,     1,     0,     2,     1,     2,  2, 0, 2, 1, 2, 2, 2};
00176               static const unsigned int i2[] = {0,     0,     0,     0,     1,     1,     1,     1,     0,     0,     0,     0,     2,     2,     2,     2,     1,     1,     1,     1,  0, 2, 2, 2, 2, 1, 2};
00177               //To compute the hex20 shape functions the original shape functions for hex27 are used.
00178               //scalx[i] tells how often the original x-th shape function has to be added to the original i-th shape function
00179               //to compute the new i-th shape function for hex20
00180               //example: B_0^HEX20 = B_0^HEX27 - 0.25*B_20^HEX27 - 0.25*B_21^HEX27 + 0*B_22^HEX27 + 0*B_23^HEX27 - 0.25*B_24^HEX27 + 0*B_25^HEX27 - 0.25*B_26^HEX27
00181               //         B_0^HEX20 = B_0^HEX27 + scal20[0]*B_20^HEX27 + scal21[0]*B_21^HEX27 + ...
00182               static const Real scal20[] =     {-0.25, -0.25, -0.25, -0.25, 0,     0,     0,     0,     0.5,   0.5,   0.5,   0.5,   0,     0,     0,     0,     0,     0,     0,     0};
00183               static const Real scal21[] =     {-0.25, -0.25, 0,     0,     -0.25, -0.25, 0,     0,     0.5,   0,     0,     0,     0.5,   0.5,   0,     0,     0.5,   0,     0,     0};
00184               static const Real scal22[] =     {0,     -0.25, -0.25, 0,     0,     -0.25, -0.25, 0,     0,     0.5,   0,     0,     0,     0.5,   0.5,   0,     0,     0.5,   0,     0};
00185               static const Real scal23[] =     {0,     0,     -0.25, -0.25, 0,     0,     -0.25, -0.25, 0,     0,     0.5,   0,     0,     0,     0.5,   0.5,   0,     0,     0.5,   0};
00186               static const Real scal24[] =     {-0.25, 0,     0,     -0.25, -0.25, 0,     0,     -0.25, 0,     0,     0,     0.5,   0.5,   0,     0,     0.5,   0,     0,     0,     0.5};
00187               static const Real scal25[] =     {0,     0,     0,     0,     -0.25, -0.25, -0.25, -0.25, 0,     0,     0,     0,     0,     0,     0,     0,     0.5,   0.5,   0.5,   0.5};
00188               static const Real scal26[] =     {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25};
00189 
00190               return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
00191                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta)*
00192                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[i], zeta)
00193                       +scal20[i]*
00194                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[20], xi)*
00195                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[20], eta)*
00196                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[20], zeta)
00197                       +scal21[i]*
00198                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[21], xi)*
00199                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[21], eta)*
00200                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[21], zeta)
00201                       +scal22[i]*
00202                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[22], xi)*
00203                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[22], eta)*
00204                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[22], zeta)
00205                       +scal23[i]*
00206                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[23], xi)*
00207                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[23], eta)*
00208                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[23], zeta)
00209                       +scal24[i]*
00210                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[24], xi)*
00211                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[24], eta)*
00212                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[24], zeta)
00213                       +scal25[i]*
00214                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[25], xi)*
00215                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[25], eta)*
00216                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[25], zeta)
00217                       +scal26[i]*
00218                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[26], xi)*
00219                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[26], eta)*
00220                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[26], zeta));
00221             }
00222 
00223             // Bernstein shape functions on the hexahedral.
00224           case HEX27:
00225             {
00226               libmesh_assert_less (i, 27);
00227 
00228               // Compute hex shape functions as a tensor-product
00229               const Real xi   = p(0);
00230               const Real eta  = p(1);
00231               const Real zeta = p(2);
00232 
00233               // The only way to make any sense of this
00234               // is to look at the mgflo/mg2/mgf documentation
00235               // and make the cut-out cube!
00236               //                                0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
00237               static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
00238               static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
00239               static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
00240 
00241               return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
00242                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta)*
00243                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[i], zeta));
00244             }
00245 
00246 
00247           default:
00248             libmesh_error_msg("Invalid element type = " << type);
00249           }
00250 
00251       }
00252 
00253 
00254 
00255       // 3rd-order Bernstein.
00256     case THIRD:
00257       {
00258         switch (type)
00259           {
00260 
00261             //     // Bernstein shape functions on the tetrahedron.
00262             //   case TET10:
00263             //     {
00264             //       libmesh_assert_less (i, 20);
00265 
00266             //       // Area coordinates
00267             //       const Real zeta1 = p(0);
00268             //       const Real zeta2 = p(1);
00269             //       const Real zeta3 = p(2);
00270             //       const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
00271 
00272 
00273             //       unsigned int shape=i;
00274 
00275             //       // handle the edge orientation
00276 
00277             //       if ((i== 4||i== 5) && elem->node(0) > elem->node(1))shape= 9-i;   //Edge 0
00278             //       if ((i== 6||i== 7) && elem->node(1) > elem->node(2))shape=13-i;   //Edge 1
00279             //       if ((i== 8||i== 9) && elem->node(0) > elem->node(2))shape=17-i;   //Edge 2
00280             //       if ((i==10||i==11) && elem->node(0) > elem->node(3))shape=21-i;   //Edge 3
00281             //       if ((i==12||i==13) && elem->node(1) > elem->node(3))shape=25-i;   //Edge 4
00282             //       if ((i==14||i==15) && elem->node(2) > elem->node(3))shape=29-i;   //Edge 5
00283 
00284             //       // No need to handle face orientation in 3rd order.
00285 
00286 
00287             //       switch(shape)
00288             // {
00289             //   //point function
00290             // case  0:  return zeta0*zeta0*zeta0;
00291             // case  1:  return zeta1*zeta1*zeta1;
00292             // case  2:  return zeta2*zeta2*zeta2;
00293             // case  3:  return zeta3*zeta3*zeta3;
00294 
00295             //   //edge functions
00296             // case  4:  return 3.*zeta0*zeta0*zeta1;
00297             // case  5:  return 3.*zeta1*zeta1*zeta0;
00298 
00299             // case  6:  return 3.*zeta1*zeta1*zeta2;
00300             // case  7:  return 3.*zeta2*zeta2*zeta1;
00301 
00302             // case  8:  return 3.*zeta0*zeta0*zeta2;
00303             // case  9:  return 3.*zeta2*zeta2*zeta0;
00304 
00305             // case 10:  return 3.*zeta0*zeta0*zeta3;
00306             // case 11:  return 3.*zeta3*zeta3*zeta0;
00307 
00308             // case 12:  return 3.*zeta1*zeta1*zeta3;
00309             // case 13:  return 3.*zeta3*zeta3*zeta1;
00310 
00311             // case 14:  return 3.*zeta2*zeta2*zeta3;
00312             // case 15:  return 3.*zeta3*zeta3*zeta2;
00313 
00314             //   //face functions
00315             // case 16:  return 6.*zeta0*zeta1*zeta2;
00316             // case 17:  return 6.*zeta0*zeta1*zeta3;
00317             // case 18:  return 6.*zeta1*zeta2*zeta3;
00318             // case 19:  return 6.*zeta2*zeta0*zeta3;
00319 
00320             // default:
00321             // libmesh_error_msg("Invalid shape function index i = " << i);
00322             // }
00323             //     }
00324 
00325 
00326             // Bernstein shape functions on the hexahedral.
00327           case HEX27:
00328             {
00329               libmesh_assert_less (i, 64);
00330 
00331               // Compute hex shape functions as a tensor-product
00332               const Real xi    = p(0);
00333               const Real eta   = p(1);
00334               const Real zeta  = p(2);
00335               Real xi_mapped   = p(0);
00336               Real eta_mapped  = p(1);
00337               Real zeta_mapped = p(2);
00338 
00339               // The only way to make any sense of this
00340               // is to look at the mgflo/mg2/mgf documentation
00341               // and make the cut-out cube!
00342               //  Nodes                         0  1  2  3  4  5  6  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24 25 25 25 25 26 26 26 26 26 26 26 26
00343               //  DOFS                          0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 18 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 60 62 63
00344               static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 3, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 2, 3, 2, 3, 0, 0, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3};
00345               static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 2, 2, 3, 3, 0, 0, 0, 0, 2, 3, 2, 3, 1, 1, 1, 1, 2, 3, 2, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3};
00346               static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3};
00347 
00348 
00349 
00350               // handle the edge orientation
00351               {
00352                 // Edge 0
00353                 if ( (i0[i] >= 2) && (i1[i] == 0) && (i2[i] == 0))
00354                   {
00355                     if (elem->point(0) != std::min(elem->point(0), elem->point(1)))
00356                       xi_mapped = -xi;
00357                   }
00358                 // Edge 1
00359                 else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] == 0))
00360                   {
00361                     if (elem->point(1) != std::min(elem->point(1), elem->point(2)))
00362                       eta_mapped = -eta;
00363                   }
00364                 // Edge 2
00365                 else if ((i0[i] >= 2) && (i1[i] == 1) && (i2[i] == 0))
00366                   {
00367                     if (elem->point(3) != std::min(elem->point(3), elem->point(2)))
00368                       xi_mapped = -xi;
00369                   }
00370                 // Edge 3
00371                 else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] == 0))
00372                   {
00373                     if (elem->point(0) != std::min(elem->point(0), elem->point(3)))
00374                       eta_mapped = -eta;
00375                   }
00376                 // Edge 4
00377                 else if ((i0[i] == 0) && (i1[i] == 0) && (i2[i] >=2 ))
00378                   {
00379                     if (elem->point(0) != std::min(elem->point(0), elem->point(4)))
00380                       zeta_mapped = -zeta;
00381                   }
00382                 // Edge 5
00383                 else if ((i0[i] == 1) && (i1[i] == 0) && (i2[i] >=2 ))
00384                   {
00385                     if (elem->point(1) != std::min(elem->point(1), elem->point(5)))
00386                       zeta_mapped = -zeta;
00387                   }
00388                 // Edge 6
00389                 else if ((i0[i] == 1) && (i1[i] == 1) && (i2[i] >=2 ))
00390                   {
00391                     if (elem->point(2) != std::min(elem->point(2), elem->point(6)))
00392                       zeta_mapped = -zeta;
00393                   }
00394                 // Edge 7
00395                 else if ((i0[i] == 0) && (i1[i] == 1) && (i2[i] >=2 ))
00396                   {
00397                     if (elem->point(3) != std::min(elem->point(3), elem->point(7)))
00398                       zeta_mapped = -zeta;
00399                   }
00400                 // Edge 8
00401                 else if ((i0[i] >=2 ) && (i1[i] == 0) && (i2[i] == 1))
00402                   {
00403                     if (elem->point(4) != std::min(elem->point(4), elem->point(5)))
00404                       xi_mapped = -xi;
00405                   }
00406                 // Edge 9
00407                 else if ((i0[i] == 1) && (i1[i] >=2 ) && (i2[i] == 1))
00408                   {
00409                     if (elem->point(5) != std::min(elem->point(5), elem->point(6)))
00410                       eta_mapped = -eta;
00411                   }
00412                 // Edge 10
00413                 else if ((i0[i] >=2 ) && (i1[i] == 1) && (i2[i] == 1))
00414                   {
00415                     if (elem->point(7) != std::min(elem->point(7), elem->point(6)))
00416                       xi_mapped = -xi;
00417                   }
00418                 // Edge 11
00419                 else if ((i0[i] == 0) && (i1[i] >=2 ) && (i2[i] == 1))
00420                   {
00421                     if (elem->point(4) != std::min(elem->point(4), elem->point(7)))
00422                       eta_mapped = -eta;
00423                   }
00424               }
00425 
00426 
00427               // handle the face orientation
00428               {
00429                 // Face 0
00430                 if (     (i2[i] == 0) && (i0[i] >= 2) && (i1[i] >= 2))
00431                   {
00432                     const Point min_point = std::min(elem->point(1),
00433                                                      std::min(elem->point(2),
00434                                                               std::min(elem->point(0),
00435                                                                        elem->point(3))));
00436                     if (elem->point(0) == min_point)
00437                       if (elem->point(1) == std::min(elem->point(1), elem->point(3)))
00438                         {
00439                           // Case 1
00440                           xi_mapped  = xi;
00441                           eta_mapped = eta;
00442                         }
00443                       else
00444                         {
00445                           // Case 2
00446                           xi_mapped  = eta;
00447                           eta_mapped = xi;
00448                         }
00449 
00450                     else if (elem->point(3) == min_point)
00451                       if (elem->point(0) == std::min(elem->point(0), elem->point(2)))
00452                         {
00453                           // Case 3
00454                           xi_mapped  = -eta;
00455                           eta_mapped = xi;
00456                         }
00457                       else
00458                         {
00459                           // Case 4
00460                           xi_mapped  = xi;
00461                           eta_mapped = -eta;
00462                         }
00463 
00464                     else if (elem->point(2) == min_point)
00465                       if (elem->point(3) == std::min(elem->point(3), elem->point(1)))
00466                         {
00467                           // Case 5
00468                           xi_mapped  = -xi;
00469                           eta_mapped = -eta;
00470                         }
00471                       else
00472                         {
00473                           // Case 6
00474                           xi_mapped  = -eta;
00475                           eta_mapped = -xi;
00476                         }
00477 
00478                     else if (elem->point(1) == min_point)
00479                       {
00480                         if (elem->point(2) == std::min(elem->point(2), elem->point(0)))
00481                           {
00482                             // Case 7
00483                             xi_mapped  = eta;
00484                             eta_mapped = -xi;
00485                           }
00486                         else
00487                           {
00488                             // Case 8
00489                             xi_mapped  = -xi;
00490                             eta_mapped = eta;
00491                           }
00492                       }
00493                   }
00494 
00495 
00496                 // Face 1
00497                 else if ((i1[i] == 0) && (i0[i] >= 2) && (i2[i] >= 2))
00498                   {
00499                     const Point min_point = std::min(elem->point(0),
00500                                                      std::min(elem->point(1),
00501                                                               std::min(elem->point(5),
00502                                                                        elem->point(4))));
00503                     if (elem->point(0) == min_point)
00504                       if (elem->point(1) == std::min(elem->point(1), elem->point(4)))
00505                         {
00506                           // Case 1
00507                           xi_mapped   = xi;
00508                           zeta_mapped = zeta;
00509                         }
00510                       else
00511                         {
00512                           // Case 2
00513                           xi_mapped   = zeta;
00514                           zeta_mapped = xi;
00515                         }
00516 
00517                     else if (elem->point(1) == min_point)
00518                       if (elem->point(5) == std::min(elem->point(5), elem->point(0)))
00519                         {
00520                           // Case 3
00521                           xi_mapped   = zeta;
00522                           zeta_mapped = -xi;
00523                         }
00524                       else
00525                         {
00526                           // Case 4
00527                           xi_mapped   = -xi;
00528                           zeta_mapped = zeta;
00529                         }
00530 
00531                     else if (elem->point(5) == min_point)
00532                       if (elem->point(4) == std::min(elem->point(4), elem->point(1)))
00533                         {
00534                           // Case 5
00535                           xi_mapped   = -xi;
00536                           zeta_mapped = -zeta;
00537                         }
00538                       else
00539                         {
00540                           // Case 6
00541                           xi_mapped   = -zeta;
00542                           zeta_mapped = -xi;
00543                         }
00544 
00545                     else if (elem->point(4) == min_point)
00546                       {
00547                         if (elem->point(0) == std::min(elem->point(0), elem->point(5)))
00548                           {
00549                             // Case 7
00550                             xi_mapped   = -xi;
00551                             zeta_mapped = zeta;
00552                           }
00553                         else
00554                           {
00555                             // Case 8
00556                             xi_mapped   = xi;
00557                             zeta_mapped = -zeta;
00558                           }
00559                       }
00560                   }
00561 
00562 
00563                 // Face 2
00564                 else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] >= 2))
00565                   {
00566                     const Point min_point = std::min(elem->point(1),
00567                                                      std::min(elem->point(2),
00568                                                               std::min(elem->point(6),
00569                                                                        elem->point(5))));
00570                     if (elem->point(1) == min_point)
00571                       if (elem->point(2) == std::min(elem->point(2), elem->point(5)))
00572                         {
00573                           // Case 1
00574                           eta_mapped  = eta;
00575                           zeta_mapped = zeta;
00576                         }
00577                       else
00578                         {
00579                           // Case 2
00580                           eta_mapped  = zeta;
00581                           zeta_mapped = eta;
00582                         }
00583 
00584                     else if (elem->point(2) == min_point)
00585                       if (elem->point(6) == std::min(elem->point(6), elem->point(1)))
00586                         {
00587                           // Case 3
00588                           eta_mapped  = zeta;
00589                           zeta_mapped = -eta;
00590                         }
00591                       else
00592                         {
00593                           // Case 4
00594                           eta_mapped  = -eta;
00595                           zeta_mapped = zeta;
00596                         }
00597 
00598                     else if (elem->point(6) == min_point)
00599                       if (elem->point(5) == std::min(elem->point(5), elem->point(2)))
00600                         {
00601                           // Case 5
00602                           eta_mapped  = -eta;
00603                           zeta_mapped = -zeta;
00604                         }
00605                       else
00606                         {
00607                           // Case 6
00608                           eta_mapped  = -zeta;
00609                           zeta_mapped = -eta;
00610                         }
00611 
00612                     else if (elem->point(5) == min_point)
00613                       {
00614                         if (elem->point(1) == std::min(elem->point(1), elem->point(6)))
00615                           {
00616                             // Case 7
00617                             eta_mapped  = -zeta;
00618                             zeta_mapped = eta;
00619                           }
00620                         else
00621                           {
00622                             // Case 8
00623                             eta_mapped   = eta;
00624                             zeta_mapped = -zeta;
00625                           }
00626                       }
00627                   }
00628 
00629 
00630                 // Face 3
00631                 else if ((i1[i] == 1) && (i0[i] >= 2) && (i2[i] >= 2))
00632                   {
00633                     const Point min_point = std::min(elem->point(2),
00634                                                      std::min(elem->point(3),
00635                                                               std::min(elem->point(7),
00636                                                                        elem->point(6))));
00637                     if (elem->point(3) == min_point)
00638                       if (elem->point(2) == std::min(elem->point(2), elem->point(7)))
00639                         {
00640                           // Case 1
00641                           xi_mapped   = xi;
00642                           zeta_mapped = zeta;
00643                         }
00644                       else
00645                         {
00646                           // Case 2
00647                           xi_mapped   = zeta;
00648                           zeta_mapped = xi;
00649                         }
00650 
00651                     else if (elem->point(7) == min_point)
00652                       if (elem->point(3) == std::min(elem->point(3), elem->point(6)))
00653                         {
00654                           // Case 3
00655                           xi_mapped   = -zeta;
00656                           zeta_mapped = xi;
00657                         }
00658                       else
00659                         {
00660                           // Case 4
00661                           xi_mapped   = xi;
00662                           zeta_mapped = -zeta;
00663                         }
00664 
00665                     else if (elem->point(6) == min_point)
00666                       if (elem->point(7) == std::min(elem->point(7), elem->point(2)))
00667                         {
00668                           // Case 5
00669                           xi_mapped   = -xi;
00670                           zeta_mapped = -zeta;
00671                         }
00672                       else
00673                         {
00674                           // Case 6
00675                           xi_mapped   = -zeta;
00676                           zeta_mapped = -xi;
00677                         }
00678 
00679                     else if (elem->point(2) == min_point)
00680                       {
00681                         if (elem->point(6) == std::min(elem->point(3), elem->point(6)))
00682                           {
00683                             // Case 7
00684                             xi_mapped   = zeta;
00685                             zeta_mapped = -xi;
00686                           }
00687                         else
00688                           {
00689                             // Case 8
00690                             xi_mapped   = -xi;
00691                             zeta_mapped = zeta;
00692                           }
00693                       }
00694                   }
00695 
00696 
00697                 // Face 4
00698                 else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] >= 2))
00699                   {
00700                     const Point min_point = std::min(elem->point(3),
00701                                                      std::min(elem->point(0),
00702                                                               std::min(elem->point(4),
00703                                                                        elem->point(7))));
00704                     if (elem->point(0) == min_point)
00705                       if (elem->point(3) == std::min(elem->point(3), elem->point(4)))
00706                         {
00707                           // Case 1
00708                           eta_mapped  = eta;
00709                           zeta_mapped = zeta;
00710                         }
00711                       else
00712                         {
00713                           // Case 2
00714                           eta_mapped  = zeta;
00715                           zeta_mapped = eta;
00716                         }
00717 
00718                     else if (elem->point(4) == min_point)
00719                       if (elem->point(0) == std::min(elem->point(0), elem->point(7)))
00720                         {
00721                           // Case 3
00722                           eta_mapped  = -zeta;
00723                           zeta_mapped = eta;
00724                         }
00725                       else
00726                         {
00727                           // Case 4
00728                           eta_mapped  = eta;
00729                           zeta_mapped = -zeta;
00730                         }
00731 
00732                     else if (elem->point(7) == min_point)
00733                       if (elem->point(4) == std::min(elem->point(4), elem->point(3)))
00734                         {
00735                           // Case 5
00736                           eta_mapped  = -eta;
00737                           zeta_mapped = -zeta;
00738                         }
00739                       else
00740                         {
00741                           // Case 6
00742                           eta_mapped  = -zeta;
00743                           zeta_mapped = -eta;
00744                         }
00745 
00746                     else if (elem->point(3) == min_point)
00747                       {
00748                         if (elem->point(7) == std::min(elem->point(7), elem->point(0)))
00749                           {
00750                             // Case 7
00751                             eta_mapped   = zeta;
00752                             zeta_mapped = -eta;
00753                           }
00754                         else
00755                           {
00756                             // Case 8
00757                             eta_mapped  = -eta;
00758                             zeta_mapped = zeta;
00759                           }
00760                       }
00761                   }
00762 
00763 
00764                 // Face 5
00765                 else if ((i2[i] == 1) && (i0[i] >= 2) && (i1[i] >= 2))
00766                   {
00767                     const Point min_point = std::min(elem->point(4),
00768                                                      std::min(elem->point(5),
00769                                                               std::min(elem->point(6),
00770                                                                        elem->point(7))));
00771                     if (elem->point(4) == min_point)
00772                       if (elem->point(5) == std::min(elem->point(5), elem->point(7)))
00773                         {
00774                           // Case 1
00775                           xi_mapped  = xi;
00776                           eta_mapped = eta;
00777                         }
00778                       else
00779                         {
00780                           // Case 2
00781                           xi_mapped  = eta;
00782                           eta_mapped = xi;
00783                         }
00784 
00785                     else if (elem->point(5) == min_point)
00786                       if (elem->point(6) == std::min(elem->point(6), elem->point(4)))
00787                         {
00788                           // Case 3
00789                           xi_mapped  = eta;
00790                           eta_mapped = -xi;
00791                         }
00792                       else
00793                         {
00794                           // Case 4
00795                           xi_mapped  = -xi;
00796                           eta_mapped = eta;
00797                         }
00798 
00799                     else if (elem->point(6) == min_point)
00800                       if (elem->point(7) == std::min(elem->point(7), elem->point(5)))
00801                         {
00802                           // Case 5
00803                           xi_mapped  = -xi;
00804                           eta_mapped = -eta;
00805                         }
00806                       else
00807                         {
00808                           // Case 6
00809                           xi_mapped  = -eta;
00810                           eta_mapped = -xi;
00811                         }
00812 
00813                     else if (elem->point(7) == min_point)
00814                       {
00815                         if (elem->point(4) == std::min(elem->point(4), elem->point(6)))
00816                           {
00817                             // Case 7
00818                             xi_mapped  = -eta;
00819                             eta_mapped = xi;
00820                           }
00821                         else
00822                           {
00823                             // Case 8
00824                             xi_mapped  = xi;
00825                             eta_mapped = eta;
00826                           }
00827                       }
00828                   }
00829               }
00830 
00831               return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi_mapped)*
00832                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta_mapped)*
00833                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[i], zeta_mapped));
00834             }
00835 
00836 
00837           default:
00838             libmesh_error_msg("Invalid element type = " << type);
00839           } //case HEX27
00840 
00841       }//case THIRD
00842 
00843 
00844       // 4th-order Bernstein.
00845     case FOURTH:
00846       {
00847         switch (type)
00848           {
00849 
00850             // Bernstein shape functions on the hexahedral.
00851           case HEX27:
00852             {
00853               libmesh_assert_less (i, 125);
00854 
00855               // Compute hex shape functions as a tensor-product
00856               const Real xi    = p(0);
00857               const Real eta   = p(1);
00858               const Real zeta  = p(2);
00859               Real xi_mapped   = p(0);
00860               Real eta_mapped  = p(1);
00861               Real zeta_mapped = p(2);
00862 
00863               // The only way to make any sense of this
00864               // is to look at the mgflo/mg2/mgf documentation
00865               // and make the cut-out cube!
00866               //  Nodes                         0  1  2  3  4  5  6  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24 25 25 25 25 26 26 26 26 26 26 26 26
00867               //  DOFS                          0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 18 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 60 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
00868               static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4};
00869               static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4};
00870               static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4};
00871 
00872 
00873 
00874               // handle the edge orientation
00875               {
00876                 // Edge 0
00877                 if ( (i0[i] >= 2) && (i1[i] == 0) && (i2[i] == 0))
00878                   {
00879                     if (elem->point(0) != std::min(elem->point(0), elem->point(1)))
00880                       xi_mapped = -xi;
00881                   }
00882                 // Edge 1
00883                 else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] == 0))
00884                   {
00885                     if (elem->point(1) != std::min(elem->point(1), elem->point(2)))
00886                       eta_mapped = -eta;
00887                   }
00888                 // Edge 2
00889                 else if ((i0[i] >= 2) && (i1[i] == 1) && (i2[i] == 0))
00890                   {
00891                     if (elem->point(3) != std::min(elem->point(3), elem->point(2)))
00892                       xi_mapped = -xi;
00893                   }
00894                 // Edge 3
00895                 else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] == 0))
00896                   {
00897                     if (elem->point(0) != std::min(elem->point(0), elem->point(3)))
00898                       eta_mapped = -eta;
00899                   }
00900                 // Edge 4
00901                 else if ((i0[i] == 0) && (i1[i] == 0) && (i2[i] >=2 ))
00902                   {
00903                     if (elem->point(0) != std::min(elem->point(0), elem->point(4)))
00904                       zeta_mapped = -zeta;
00905                   }
00906                 // Edge 5
00907                 else if ((i0[i] == 1) && (i1[i] == 0) && (i2[i] >=2 ))
00908                   {
00909                     if (elem->point(1) != std::min(elem->point(1), elem->point(5)))
00910                       zeta_mapped = -zeta;
00911                   }
00912                 // Edge 6
00913                 else if ((i0[i] == 1) && (i1[i] == 1) && (i2[i] >=2 ))
00914                   {
00915                     if (elem->point(2) != std::min(elem->point(2), elem->point(6)))
00916                       zeta_mapped = -zeta;
00917                   }
00918                 // Edge 7
00919                 else if ((i0[i] == 0) && (i1[i] == 1) && (i2[i] >=2 ))
00920                   {
00921                     if (elem->point(3) != std::min(elem->point(3), elem->point(7)))
00922                       zeta_mapped = -zeta;
00923                   }
00924                 // Edge 8
00925                 else if ((i0[i] >=2 ) && (i1[i] == 0) && (i2[i] == 1))
00926                   {
00927                     if (elem->point(4) != std::min(elem->point(4), elem->point(5)))
00928                       xi_mapped = -xi;
00929                   }
00930                 // Edge 9
00931                 else if ((i0[i] == 1) && (i1[i] >=2 ) && (i2[i] == 1))
00932                   {
00933                     if (elem->point(5) != std::min(elem->point(5), elem->point(6)))
00934                       eta_mapped = -eta;
00935                   }
00936                 // Edge 10
00937                 else if ((i0[i] >=2 ) && (i1[i] == 1) && (i2[i] == 1))
00938                   {
00939                     if (elem->point(7) != std::min(elem->point(7), elem->point(6)))
00940                       xi_mapped = -xi;
00941                   }
00942                 // Edge 11
00943                 else if ((i0[i] == 0) && (i1[i] >=2 ) && (i2[i] == 1))
00944                   {
00945                     if (elem->point(4) != std::min(elem->point(4), elem->point(7)))
00946                       eta_mapped = -eta;
00947                   }
00948               }
00949 
00950 
00951               // handle the face orientation
00952               {
00953                 // Face 0
00954                 if (     (i2[i] == 0) && (i0[i] >= 2) && (i1[i] >= 2))
00955                   {
00956                     const Point min_point = std::min(elem->point(1),
00957                                                      std::min(elem->point(2),
00958                                                               std::min(elem->point(0),
00959                                                                        elem->point(3))));
00960                     if (elem->point(0) == min_point)
00961                       if (elem->point(1) == std::min(elem->point(1), elem->point(3)))
00962                         {
00963                           // Case 1
00964                           xi_mapped  = xi;
00965                           eta_mapped = eta;
00966                         }
00967                       else
00968                         {
00969                           // Case 2
00970                           xi_mapped  = eta;
00971                           eta_mapped = xi;
00972                         }
00973 
00974                     else if (elem->point(3) == min_point)
00975                       if (elem->point(0) == std::min(elem->point(0), elem->point(2)))
00976                         {
00977                           // Case 3
00978                           xi_mapped  = -eta;
00979                           eta_mapped = xi;
00980                         }
00981                       else
00982                         {
00983                           // Case 4
00984                           xi_mapped  = xi;
00985                           eta_mapped = -eta;
00986                         }
00987 
00988                     else if (elem->point(2) == min_point)
00989                       if (elem->point(3) == std::min(elem->point(3), elem->point(1)))
00990                         {
00991                           // Case 5
00992                           xi_mapped  = -xi;
00993                           eta_mapped = -eta;
00994                         }
00995                       else
00996                         {
00997                           // Case 6
00998                           xi_mapped  = -eta;
00999                           eta_mapped = -xi;
01000                         }
01001 
01002                     else if (elem->point(1) == min_point)
01003                       {
01004                         if (elem->point(2) == std::min(elem->point(2), elem->point(0)))
01005                           {
01006                             // Case 7
01007                             xi_mapped  = eta;
01008                             eta_mapped = -xi;
01009                           }
01010                         else
01011                           {
01012                             // Case 8
01013                             xi_mapped  = -xi;
01014                             eta_mapped = eta;
01015                           }
01016                       }
01017                   }
01018 
01019 
01020                 // Face 1
01021                 else if ((i1[i] == 0) && (i0[i] >= 2) && (i2[i] >= 2))
01022                   {
01023                     const Point min_point = std::min(elem->point(0),
01024                                                      std::min(elem->point(1),
01025                                                               std::min(elem->point(5),
01026                                                                        elem->point(4))));
01027                     if (elem->point(0) == min_point)
01028                       if (elem->point(1) == std::min(elem->point(1), elem->point(4)))
01029                         {
01030                           // Case 1
01031                           xi_mapped   = xi;
01032                           zeta_mapped = zeta;
01033                         }
01034                       else
01035                         {
01036                           // Case 2
01037                           xi_mapped   = zeta;
01038                           zeta_mapped = xi;
01039                         }
01040 
01041                     else if (elem->point(1) == min_point)
01042                       if (elem->point(5) == std::min(elem->point(5), elem->point(0)))
01043                         {
01044                           // Case 3
01045                           xi_mapped   = zeta;
01046                           zeta_mapped = -xi;
01047                         }
01048                       else
01049                         {
01050                           // Case 4
01051                           xi_mapped   = -xi;
01052                           zeta_mapped = zeta;
01053                         }
01054 
01055                     else if (elem->point(5) == min_point)
01056                       if (elem->point(4) == std::min(elem->point(4), elem->point(1)))
01057                         {
01058                           // Case 5
01059                           xi_mapped   = -xi;
01060                           zeta_mapped = -zeta;
01061                         }
01062                       else
01063                         {
01064                           // Case 6
01065                           xi_mapped   = -zeta;
01066                           zeta_mapped = -xi;
01067                         }
01068 
01069                     else if (elem->point(4) == min_point)
01070                       {
01071                         if (elem->point(0) == std::min(elem->point(0), elem->point(5)))
01072                           {
01073                             // Case 7
01074                             xi_mapped   = -xi;
01075                             zeta_mapped = zeta;
01076                           }
01077                         else
01078                           {
01079                             // Case 8
01080                             xi_mapped   = xi;
01081                             zeta_mapped = -zeta;
01082                           }
01083                       }
01084                   }
01085 
01086 
01087                 // Face 2
01088                 else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] >= 2))
01089                   {
01090                     const Point min_point = std::min(elem->point(1),
01091                                                      std::min(elem->point(2),
01092                                                               std::min(elem->point(6),
01093                                                                        elem->point(5))));
01094                     if (elem->point(1) == min_point)
01095                       if (elem->point(2) == std::min(elem->point(2), elem->point(5)))
01096                         {
01097                           // Case 1
01098                           eta_mapped  = eta;
01099                           zeta_mapped = zeta;
01100                         }
01101                       else
01102                         {
01103                           // Case 2
01104                           eta_mapped  = zeta;
01105                           zeta_mapped = eta;
01106                         }
01107 
01108                     else if (elem->point(2) == min_point)
01109                       if (elem->point(6) == std::min(elem->point(6), elem->point(1)))
01110                         {
01111                           // Case 3
01112                           eta_mapped  = zeta;
01113                           zeta_mapped = -eta;
01114                         }
01115                       else
01116                         {
01117                           // Case 4
01118                           eta_mapped  = -eta;
01119                           zeta_mapped = zeta;
01120                         }
01121 
01122                     else if (elem->point(6) == min_point)
01123                       if (elem->point(5) == std::min(elem->point(5), elem->point(2)))
01124                         {
01125                           // Case 5
01126                           eta_mapped  = -eta;
01127                           zeta_mapped = -zeta;
01128                         }
01129                       else
01130                         {
01131                           // Case 6
01132                           eta_mapped  = -zeta;
01133                           zeta_mapped = -eta;
01134                         }
01135 
01136                     else if (elem->point(5) == min_point)
01137                       {
01138                         if (elem->point(1) == std::min(elem->point(1), elem->point(6)))
01139                           {
01140                             // Case 7
01141                             eta_mapped  = -zeta;
01142                             zeta_mapped = eta;
01143                           }
01144                         else
01145                           {
01146                             // Case 8
01147                             eta_mapped   = eta;
01148                             zeta_mapped = -zeta;
01149                           }
01150                       }
01151                   }
01152 
01153 
01154                 // Face 3
01155                 else if ((i1[i] == 1) && (i0[i] >= 2) && (i2[i] >= 2))
01156                   {
01157                     const Point min_point = std::min(elem->point(2),
01158                                                      std::min(elem->point(3),
01159                                                               std::min(elem->point(7),
01160                                                                        elem->point(6))));
01161                     if (elem->point(3) == min_point)
01162                       if (elem->point(2) == std::min(elem->point(2), elem->point(7)))
01163                         {
01164                           // Case 1
01165                           xi_mapped   = xi;
01166                           zeta_mapped = zeta;
01167                         }
01168                       else
01169                         {
01170                           // Case 2
01171                           xi_mapped   = zeta;
01172                           zeta_mapped = xi;
01173                         }
01174 
01175                     else if (elem->point(7) == min_point)
01176                       if (elem->point(3) == std::min(elem->point(3), elem->point(6)))
01177                         {
01178                           // Case 3
01179                           xi_mapped   = -zeta;
01180                           zeta_mapped = xi;
01181                         }
01182                       else
01183                         {
01184                           // Case 4
01185                           xi_mapped   = xi;
01186                           zeta_mapped = -zeta;
01187                         }
01188 
01189                     else if (elem->point(6) == min_point)
01190                       if (elem->point(7) == std::min(elem->point(7), elem->point(2)))
01191                         {
01192                           // Case 5
01193                           xi_mapped   = -xi;
01194                           zeta_mapped = -zeta;
01195                         }
01196                       else
01197                         {
01198                           // Case 6
01199                           xi_mapped   = -zeta;
01200                           zeta_mapped = -xi;
01201                         }
01202 
01203                     else if (elem->point(2) == min_point)
01204                       {
01205                         if (elem->point(6) == std::min(elem->point(3), elem->point(6)))
01206                           {
01207                             // Case 7
01208                             xi_mapped   = zeta;
01209                             zeta_mapped = -xi;
01210                           }
01211                         else
01212                           {
01213                             // Case 8
01214                             xi_mapped   = -xi;
01215                             zeta_mapped = zeta;
01216                           }
01217                       }
01218                   }
01219 
01220 
01221                 // Face 4
01222                 else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] >= 2))
01223                   {
01224                     const Point min_point = std::min(elem->point(3),
01225                                                      std::min(elem->point(0),
01226                                                               std::min(elem->point(4),
01227                                                                        elem->point(7))));
01228                     if (elem->point(0) == min_point)
01229                       if (elem->point(3) == std::min(elem->point(3), elem->point(4)))
01230                         {
01231                           // Case 1
01232                           eta_mapped  = eta;
01233                           zeta_mapped = zeta;
01234                         }
01235                       else
01236                         {
01237                           // Case 2
01238                           eta_mapped  = zeta;
01239                           zeta_mapped = eta;
01240                         }
01241 
01242                     else if (elem->point(4) == min_point)
01243                       if (elem->point(0) == std::min(elem->point(0), elem->point(7)))
01244                         {
01245                           // Case 3
01246                           eta_mapped  = -zeta;
01247                           zeta_mapped = eta;
01248                         }
01249                       else
01250                         {
01251                           // Case 4
01252                           eta_mapped  = eta;
01253                           zeta_mapped = -zeta;
01254                         }
01255 
01256                     else if (elem->point(7) == min_point)
01257                       if (elem->point(4) == std::min(elem->point(4), elem->point(3)))
01258                         {
01259                           // Case 5
01260                           eta_mapped  = -eta;
01261                           zeta_mapped = -zeta;
01262                         }
01263                       else
01264                         {
01265                           // Case 6
01266                           eta_mapped  = -zeta;
01267                           zeta_mapped = -eta;
01268                         }
01269 
01270                     else if (elem->point(3) == min_point)
01271                       {
01272                         if (elem->point(7) == std::min(elem->point(7), elem->point(0)))
01273                           {
01274                             // Case 7
01275                             eta_mapped   = zeta;
01276                             zeta_mapped = -eta;
01277                           }
01278                         else
01279                           {
01280                             // Case 8
01281                             eta_mapped  = -eta;
01282                             zeta_mapped = zeta;
01283                           }
01284                       }
01285                   }
01286 
01287 
01288                 // Face 5
01289                 else if ((i2[i] == 1) && (i0[i] >= 2) && (i1[i] >= 2))
01290                   {
01291                     const Point min_point = std::min(elem->point(4),
01292                                                      std::min(elem->point(5),
01293                                                               std::min(elem->point(6),
01294                                                                        elem->point(7))));
01295                     if (elem->point(4) == min_point)
01296                       if (elem->point(5) == std::min(elem->point(5), elem->point(7)))
01297                         {
01298                           // Case 1
01299                           xi_mapped  = xi;
01300                           eta_mapped = eta;
01301                         }
01302                       else
01303                         {
01304                           // Case 2
01305                           xi_mapped  = eta;
01306                           eta_mapped = xi;
01307                         }
01308 
01309                     else if (elem->point(5) == min_point)
01310                       if (elem->point(6) == std::min(elem->point(6), elem->point(4)))
01311                         {
01312                           // Case 3
01313                           xi_mapped  = eta;
01314                           eta_mapped = -xi;
01315                         }
01316                       else
01317                         {
01318                           // Case 4
01319                           xi_mapped  = -xi;
01320                           eta_mapped = eta;
01321                         }
01322 
01323                     else if (elem->point(6) == min_point)
01324                       if (elem->point(7) == std::min(elem->point(7), elem->point(5)))
01325                         {
01326                           // Case 5
01327                           xi_mapped  = -xi;
01328                           eta_mapped = -eta;
01329                         }
01330                       else
01331                         {
01332                           // Case 6
01333                           xi_mapped  = -eta;
01334                           eta_mapped = -xi;
01335                         }
01336 
01337                     else if (elem->point(7) == min_point)
01338                       {
01339                         if (elem->point(4) == std::min(elem->point(4), elem->point(6)))
01340                           {
01341                             // Case 7
01342                             xi_mapped  = -eta;
01343                             eta_mapped = xi;
01344                           }
01345                         else
01346                           {
01347                             // Case 8
01348                             xi_mapped  = xi;
01349                             eta_mapped = eta;
01350                           }
01351                       }
01352                   }
01353 
01354 
01355               }
01356 
01357 
01358               return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi_mapped)*
01359                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta_mapped)*
01360                       FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[i], zeta_mapped));
01361             }
01362 
01363 
01364           default:
01365             libmesh_error_msg("Invalid element type = " << type);
01366           }
01367       }
01368 
01369 
01370     default:
01371       libmesh_error_msg("Invalid totalorder = " << totalorder);
01372     }
01373 
01374 #endif
01375 
01376   libmesh_error_msg("We'll never get here!");
01377   return 0.;
01378 }
01379 
01380 
01381 
01382 
01383 template <>
01384 Real FE<3,BERNSTEIN>::shape_deriv(const ElemType,
01385                                   const Order,
01386                                   const unsigned int,
01387                                   const unsigned int,
01388                                   const Point& )
01389 {
01390   libmesh_error_msg("Bernstein polynomials require the element type \nbecause edge and face orientation is needed.");
01391   return 0.;
01392 }
01393 
01394 
01395 
01396 template <>
01397 Real FE<3,BERNSTEIN>::shape_deriv(const Elem* elem,
01398                                   const Order order,
01399                                   const unsigned int i,
01400                                   const unsigned int j,
01401                                   const Point& p)
01402 {
01403 
01404 #if LIBMESH_DIM == 3
01405   libmesh_assert(elem);
01406   const ElemType type = elem->type();
01407 
01408   const Order totalorder = static_cast<Order>(order + elem->p_level());
01409 
01410   libmesh_assert_less (j, 3);
01411 
01412   switch (totalorder)
01413     {
01414       // 1st order Bernstein.
01415     case FIRST:
01416       {
01417         switch (type)
01418           {
01419             // Bernstein shape functions on the tetrahedron.
01420           case TET4:
01421           case TET10:
01422             {
01423               // I have been lazy here and am using finite differences
01424               // to compute the derivatives!
01425               const Real eps = 1.e-6;
01426 
01427               libmesh_assert_less (i, 4);
01428               libmesh_assert_less (j, 3);
01429 
01430 
01431               switch (j)
01432                 {
01433                   //  d()/dxi
01434                 case 0:
01435                   {
01436                     const Point pp(p(0)+eps, p(1), p(2));
01437                     const Point pm(p(0)-eps, p(1), p(2));
01438 
01439                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01440                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01441                   }
01442 
01443                   // d()/deta
01444                 case 1:
01445                   {
01446                     const Point pp(p(0), p(1)+eps, p(2));
01447                     const Point pm(p(0), p(1)-eps, p(2));
01448 
01449                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01450                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01451                   }
01452                   // d()/dzeta
01453                 case 2:
01454                   {
01455                     const Point pp(p(0), p(1), p(2)+eps);
01456                     const Point pm(p(0), p(1), p(2)-eps);
01457 
01458                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01459                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01460                   }
01461                 default:
01462                   libmesh_error_msg("Invalid derivative index j = " << j);
01463                 }
01464             }
01465 
01466 
01467 
01468 
01469             // Bernstein shape functions on the hexahedral.
01470           case HEX20:
01471           case HEX27:
01472             {
01473               libmesh_assert_less (i, 8);
01474 
01475               // Compute hex shape functions as a tensor-product
01476               const Real xi   = p(0);
01477               const Real eta  = p(1);
01478               const Real zeta = p(2);
01479 
01480               // The only way to make any sense of this
01481               // is to look at the mgflo/mg2/mgf documentation
01482               // and make the cut-out cube!
01483               //                                0  1  2  3  4  5  6  7
01484               static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0};
01485               static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1};
01486               static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1};
01487 
01488               switch (j)
01489                 {
01490                   // d()/dxi
01491                 case 0:
01492                   return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
01493                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[i],    eta)*
01494                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[i],    zeta));
01495 
01496                   // d()/deta
01497                 case 1:
01498                   return (FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[i],     xi)*
01499                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta)*
01500                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[i],    zeta));
01501 
01502                   // d()/dzeta
01503                 case 2:
01504                   return (FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[i],    xi)*
01505                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[i],    eta)*
01506                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[i], 0, zeta));
01507 
01508                 default:
01509                   libmesh_error_msg("Invalid derivative index j = " << j);
01510                 }
01511             }
01512 
01513           default:
01514             libmesh_error_msg("Invalid element type = " << type);
01515           }
01516       }
01517 
01518 
01519 
01520 
01521     case SECOND:
01522       {
01523         switch (type)
01524           {
01525             // Bernstein shape functions on the tetrahedron.
01526           case TET10:
01527             {
01528               // I have been lazy here and am using finite differences
01529               // to compute the derivatives!
01530               const Real eps = 1.e-6;
01531 
01532               libmesh_assert_less (i, 10);
01533               libmesh_assert_less (j, 3);
01534 
01535 
01536               switch (j)
01537                 {
01538                   //  d()/dxi
01539                 case 0:
01540                   {
01541                     const Point pp(p(0)+eps, p(1), p(2));
01542                     const Point pm(p(0)-eps, p(1), p(2));
01543 
01544                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01545                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01546                   }
01547 
01548                   // d()/deta
01549                 case 1:
01550                   {
01551                     const Point pp(p(0), p(1)+eps, p(2));
01552                     const Point pm(p(0), p(1)-eps, p(2));
01553 
01554                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01555                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01556                   }
01557                   // d()/dzeta
01558                 case 2:
01559                   {
01560                     const Point pp(p(0), p(1), p(2)+eps);
01561                     const Point pm(p(0), p(1), p(2)-eps);
01562 
01563                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01564                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01565                   }
01566                 default:
01567                   libmesh_error_msg("Invalid derivative index j = " << j);
01568                 }
01569             }
01570 
01571             // Bernstein shape functions on the hexahedral.
01572           case HEX20:
01573             {
01574               libmesh_assert_less (i, 20);
01575 
01576               // Compute hex shape functions as a tensor-product
01577               const Real xi   = p(0);
01578               const Real eta  = p(1);
01579               const Real zeta = p(2);
01580 
01581               // The only way to make any sense of this
01582               // is to look at the mgflo/mg2/mgf documentation
01583               // and make the cut-out cube!
01584               //                                0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
01585               static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
01586               static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
01587               static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
01588               static const Real scal20[] =     {-0.25, -0.25, -0.25, -0.25, 0,     0,     0,     0,     0.5,   0.5,   0.5,   0.5,   0,     0,     0,     0,     0,     0,     0,     0};
01589               static const Real scal21[] =     {-0.25, -0.25, 0,     0,     -0.25, -0.25, 0,     0,     0.5,   0,     0,     0,     0.5,   0.5,   0,     0,     0.5,   0,     0,     0};
01590               static const Real scal22[] =     {0,     -0.25, -0.25, 0,     0,     -0.25, -0.25, 0,     0,     0.5,   0,     0,     0,     0.5,   0.5,   0,     0,     0.5,   0,     0};
01591               static const Real scal23[] =     {0,     0,     -0.25, -0.25, 0,     0,     -0.25, -0.25, 0,     0,     0.5,   0,     0,     0,     0.5,   0.5,   0,     0,     0.5,   0};
01592               static const Real scal24[] =     {-0.25, 0,     0,     -0.25, -0.25, 0,     0,     -0.25, 0,     0,     0,     0.5,   0.5,   0,     0,     0.5,   0,     0,     0,     0.5};
01593               static const Real scal25[] =     {0,     0,     0,     0,     -0.25, -0.25, -0.25, -0.25, 0,     0,     0,     0,     0,     0,     0,     0,     0.5,   0.5,   0.5,   0.5};
01594               static const Real scal26[] =     {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25};
01595 
01596               switch (j)
01597                 {
01598                   // d()/dxi
01599                 case 0:
01600                   return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
01601                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[i],    eta)*
01602                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[i],    zeta)
01603                           +scal20[i]*
01604                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[20], 0, xi)*
01605                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[20],    eta)*
01606                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[20],    zeta)
01607                           +scal21[i]*
01608                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[21], 0, xi)*
01609                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[21],    eta)*
01610                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[21],    zeta)
01611                           +scal22[i]*
01612                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[22], 0, xi)*
01613                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[22],    eta)*
01614                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[22],    zeta)
01615                           +scal23[i]*
01616                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[23], 0, xi)*
01617                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[23],    eta)*
01618                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[23],    zeta)
01619                           +scal24[i]*
01620                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[24], 0, xi)*
01621                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[24],    eta)*
01622                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[24],    zeta)
01623                           +scal25[i]*
01624                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[25], 0, xi)*
01625                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[25],    eta)*
01626                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[25],    zeta)
01627                           +scal26[i]*
01628                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[26], 0, xi)*
01629                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[26],    eta)*
01630                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[26],    zeta));
01631 
01632                   // d()/deta
01633                 case 1:
01634                   return (FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[i],     xi)*
01635                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta)*
01636                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[i],    zeta)
01637                           +scal20[i]*
01638                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[20],     xi)*
01639                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[20], 0, eta)*
01640                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[20],    zeta)
01641                           +scal21[i]*
01642                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[21],     xi)*
01643                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[21], 0, eta)*
01644                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[21],    zeta)
01645                           +scal22[i]*
01646                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[22],     xi)*
01647                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[22], 0, eta)*
01648                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[22],    zeta)
01649                           +scal23[i]*
01650                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[23],     xi)*
01651                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[23], 0, eta)*
01652                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[23],    zeta)
01653                           +scal24[i]*
01654                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[24],     xi)*
01655                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[24], 0, eta)*
01656                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[24],    zeta)
01657                           +scal25[i]*
01658                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[25],     xi)*
01659                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[25], 0, eta)*
01660                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[25],    zeta)
01661                           +scal26[i]*
01662                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[26],     xi)*
01663                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[26], 0, eta)*
01664                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[26],    zeta));
01665 
01666                   // d()/dzeta
01667                 case 2:
01668                   return (FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[i],    xi)*
01669                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[i],    eta)*
01670                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[i], 0, zeta)
01671                           +scal20[i]*
01672                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[20],    xi)*
01673                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[20],    eta)*
01674                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[20], 0, zeta)
01675                           +scal21[i]*
01676                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[21],    xi)*
01677                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[21],    eta)*
01678                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[21], 0, zeta)
01679                           +scal22[i]*
01680                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[22],    xi)*
01681                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[22],    eta)*
01682                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[22], 0, zeta)
01683                           +scal23[i]*
01684                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[23],    xi)*
01685                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[23],    eta)*
01686                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[23], 0, zeta)
01687                           +scal24[i]*
01688                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[24],    xi)*
01689                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[24],    eta)*
01690                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[24], 0, zeta)
01691                           +scal25[i]*
01692                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[25],    xi)*
01693                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[25],    eta)*
01694                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[25], 0, zeta)
01695                           +scal26[i]*
01696                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[26],    xi)*
01697                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[26],    eta)*
01698                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[26], 0, zeta));
01699 
01700                 default:
01701                   libmesh_error_msg("Invalid derivative index j = " << j);
01702                 }
01703             }
01704 
01705             // Bernstein shape functions on the hexahedral.
01706           case HEX27:
01707             {
01708               libmesh_assert_less (i, 27);
01709 
01710               // Compute hex shape functions as a tensor-product
01711               const Real xi   = p(0);
01712               const Real eta  = p(1);
01713               const Real zeta = p(2);
01714 
01715               // The only way to make any sense of this
01716               // is to look at the mgflo/mg2/mgf documentation
01717               // and make the cut-out cube!
01718               //                                0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
01719               static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
01720               static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
01721               static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
01722 
01723               switch (j)
01724                 {
01725                   // d()/dxi
01726                 case 0:
01727                   return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
01728                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[i],    eta)*
01729                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[i],    zeta));
01730 
01731                   // d()/deta
01732                 case 1:
01733                   return (FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[i],     xi)*
01734                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta)*
01735                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[i],    zeta));
01736 
01737                   // d()/dzeta
01738                 case 2:
01739                   return (FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[i],    xi)*
01740                           FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[i],    eta)*
01741                           FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[i], 0, zeta));
01742 
01743                 default:
01744                   libmesh_error_msg("Invalid derivative index j = " << j);
01745                 }
01746             }
01747 
01748 
01749           default:
01750             libmesh_error_msg("Invalid element type = " << type);
01751           }
01752       }
01753 
01754 
01755 
01756       // 3rd-order Bernstein.
01757     case THIRD:
01758       {
01759         switch (type)
01760           {
01761 
01762             //     // Bernstein shape functions derivatives.
01763             //   case TET10:
01764             //     {
01765             //       // I have been lazy here and am using finite differences
01766             //       // to compute the derivatives!
01767             //       const Real eps = 1.e-6;
01768 
01769             //       libmesh_assert_less (i, 20);
01770             //       libmesh_assert_less (j, 3);
01771 
01772             // switch (j)
01773             // {
01774             //   //  d()/dxi
01775             // case 0:
01776             //   {
01777             //     const Point pp(p(0)+eps, p(1), p(2));
01778             //     const Point pm(p(0)-eps, p(1), p(2));
01779 
01780             //     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01781             //     FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01782             //   }
01783 
01784             //   // d()/deta
01785             // case 1:
01786             //   {
01787             //     const Point pp(p(0), p(1)+eps, p(2));
01788             //     const Point pm(p(0), p(1)-eps, p(2));
01789 
01790             //     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01791             //     FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01792             //   }
01793             //   // d()/dzeta
01794             // case 2:
01795             //   {
01796             //     const Point pp(p(0), p(1), p(2)+eps);
01797             //     const Point pm(p(0), p(1), p(2)-eps);
01798 
01799             //     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01800             //     FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01801             //   }
01802             // default:
01803             // libmesh_error_msg("Invalid derivative index j = " << j);
01804             // }
01805 
01806 
01807             //     }
01808 
01809 
01810             // Bernstein shape functions on the hexahedral.
01811           case HEX27:
01812             {
01813               // I have been lazy here and am using finite differences
01814               // to compute the derivatives!
01815               const Real eps = 1.e-6;
01816 
01817               libmesh_assert_less (i, 64);
01818               libmesh_assert_less (j, 3);
01819 
01820               switch (j)
01821                 {
01822                   //  d()/dxi
01823                 case 0:
01824                   {
01825                     const Point pp(p(0)+eps, p(1), p(2));
01826                     const Point pm(p(0)-eps, p(1), p(2));
01827 
01828                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01829                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01830                   }
01831 
01832                   // d()/deta
01833                 case 1:
01834                   {
01835                     const Point pp(p(0), p(1)+eps, p(2));
01836                     const Point pm(p(0), p(1)-eps, p(2));
01837 
01838                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01839                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01840                   }
01841                   // d()/dzeta
01842                 case 2:
01843                   {
01844                     const Point pp(p(0), p(1), p(2)+eps);
01845                     const Point pm(p(0), p(1), p(2)-eps);
01846 
01847                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
01848                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
01849                   }
01850                 default:
01851                   libmesh_error_msg("Invalid derivative index j = " << j);
01852                 }
01853 
01854             }
01855 
01856             //       // Compute hex shape functions as a tensor-product
01857             //       const Real xi    = p(0);
01858             //       const Real eta   = p(1);
01859             //       const Real zeta  = p(2);
01860             //       Real xi_mapped   = p(0);
01861             //       Real eta_mapped  = p(1);
01862             //       Real zeta_mapped = p(2);
01863 
01864             //       // The only way to make any sense of this
01865             //       // is to look at the mgflo/mg2/mgf documentation
01866             //       // and make the cut-out cube!
01867             //       //  Nodes                         0  1  2  3  4  5  6  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24 25 25 25 25 26 26 26 26 26 26 26 26
01868             //       //  DOFS                          0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 18 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 60 62 63
01869             //       static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 3, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 2, 3, 2, 3, 0, 0, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3};
01870             //       static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 2, 2, 3, 3, 0, 0, 0, 0, 2, 3, 2, 3, 1, 1, 1, 1, 2, 3, 2, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3};
01871             //       static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3};
01872 
01873 
01874 
01875             //       // handle the edge orientation
01876             //       {
01877             // // Edge 0
01878             // if ((i1[i] == 0) && (i2[i] == 0))
01879             //   {
01880             //     if (elem->node(0) != std::min(elem->node(0), elem->node(1)))
01881             //       xi_mapped = -xi;
01882             //   }
01883             // // Edge 1
01884             // else if ((i0[i] == 1) && (i2[i] == 0))
01885             //   {
01886             //     if (elem->node(1) != std::min(elem->node(1), elem->node(2)))
01887             //       eta_mapped = -eta;
01888             //   }
01889             // // Edge 2
01890             // else if ((i1[i] == 1) && (i2[i] == 0))
01891             //   {
01892             //     if (elem->node(3) != std::min(elem->node(3), elem->node(2)))
01893             //       xi_mapped = -xi;
01894             //   }
01895             // // Edge 3
01896             // else if ((i0[i] == 0) && (i2[i] == 0))
01897             //   {
01898             //     if (elem->node(0) != std::min(elem->node(0), elem->node(3)))
01899             //       eta_mapped = -eta;
01900             //   }
01901             // // Edge 4
01902             // else if ((i0[i] == 0) && (i1[i] == 0))
01903             //   {
01904             //     if (elem->node(0) != std::min(elem->node(0), elem->node(4)))
01905             //       zeta_mapped = -zeta;
01906             //   }
01907             // // Edge 5
01908             // else if ((i0[i] == 1) && (i1[i] == 0))
01909             //   {
01910             //     if (elem->node(1) != std::min(elem->node(1), elem->node(5)))
01911             //       zeta_mapped = -zeta;
01912             //   }
01913             // // Edge 6
01914             // else if ((i0[i] == 1) && (i1[i] == 1))
01915             //   {
01916             //     if (elem->node(2) != std::min(elem->node(2), elem->node(6)))
01917             //       zeta_mapped = -zeta;
01918             //   }
01919             // // Edge 7
01920             // else if ((i0[i] == 0) && (i1[i] == 1))
01921             //   {
01922             //     if (elem->node(3) != std::min(elem->node(3), elem->node(7)))
01923             //       zeta_mapped = -zeta;
01924             //   }
01925             // // Edge 8
01926             // else if ((i1[i] == 0) && (i2[i] == 1))
01927             //   {
01928             //     if (elem->node(4) != std::min(elem->node(4), elem->node(5)))
01929             //       xi_mapped = -xi;
01930             //   }
01931             // // Edge 9
01932             // else if ((i0[i] == 1) && (i2[i] == 1))
01933             //   {
01934             //     if (elem->node(5) != std::min(elem->node(5), elem->node(6)))
01935             //       eta_mapped = -eta;
01936             //   }
01937             // // Edge 10
01938             // else if ((i1[i] == 1) && (i2[i] == 1))
01939             //   {
01940             //     if (elem->node(7) != std::min(elem->node(7), elem->node(6)))
01941             //       xi_mapped = -xi;
01942             //   }
01943             // // Edge 11
01944             // else if ((i0[i] == 0) && (i2[i] == 1))
01945             //   {
01946             //     if (elem->node(4) != std::min(elem->node(4), elem->node(7)))
01947             //       eta_mapped = -eta;
01948             //   }
01949             //       }
01950 
01951 
01952             //       // handle the face orientation
01953             //       {
01954             // // Face 0
01955             // if (     (i2[i] == 0) && (i0[i] >= 2) && (i1[i] >= 2))
01956             //   {
01957             //     const unsigned int min_node = std::min(elem->node(1),
01958             //    std::min(elem->node(2),
01959             //     std::min(elem->node(0),
01960             //      elem->node(3))));
01961             //     if (elem->node(0) == min_node)
01962             //       if (elem->node(1) == std::min(elem->node(1), elem->node(3)))
01963             // {
01964             //   // Case 1
01965             //   xi_mapped  = xi;
01966             //   eta_mapped = eta;
01967             // }
01968             //       else
01969             // {
01970             //   // Case 2
01971             //   xi_mapped  = eta;
01972             //   eta_mapped = xi;
01973             // }
01974 
01975             //     else if (elem->node(3) == min_node)
01976             //       if (elem->node(0) == std::min(elem->node(0), elem->node(2)))
01977             // {
01978             //   // Case 3
01979             //   xi_mapped  = -eta;
01980             //   eta_mapped = xi;
01981             // }
01982             //       else
01983             // {
01984             //   // Case 4
01985             //   xi_mapped  = xi;
01986             //   eta_mapped = -eta;
01987             // }
01988 
01989             //     else if (elem->node(2) == min_node)
01990             //       if (elem->node(3) == std::min(elem->node(3), elem->node(1)))
01991             // {
01992             //   // Case 5
01993             //   xi_mapped  = -xi;
01994             //   eta_mapped = -eta;
01995             // }
01996             //       else
01997             // {
01998             //   // Case 6
01999             //   xi_mapped  = -eta;
02000             //   eta_mapped = -xi;
02001             // }
02002 
02003             //     else if (elem->node(1) == min_node)
02004             //       if (elem->node(2) == std::min(elem->node(2), elem->node(0)))
02005             // {
02006             //   // Case 7
02007             //   xi_mapped  = eta;
02008             //   eta_mapped = -xi;
02009             // }
02010             //       else
02011             // {
02012             //   // Case 8
02013             //   xi_mapped  = -xi;
02014             //   eta_mapped = eta;
02015             // }
02016             //   }
02017 
02018 
02019             // // Face 1
02020             // else if ((i1[i] == 0) && (i0[i] >= 2) && (i2[i] >= 2))
02021             //   {
02022             //     const unsigned int min_node = std::min(elem->node(0),
02023             //    std::min(elem->node(1),
02024             //     std::min(elem->node(5),
02025             //      elem->node(4))));
02026             //     if (elem->node(0) == min_node)
02027             //       if (elem->node(1) == std::min(elem->node(1), elem->node(4)))
02028             // {
02029             //   // Case 1
02030             //   xi_mapped   = xi;
02031             //   zeta_mapped = zeta;
02032             // }
02033             //       else
02034             // {
02035             //   // Case 2
02036             //   xi_mapped   = zeta;
02037             //   zeta_mapped = xi;
02038             // }
02039 
02040             //     else if (elem->node(1) == min_node)
02041             //       if (elem->node(5) == std::min(elem->node(5), elem->node(0)))
02042             // {
02043             //   // Case 3
02044             //   xi_mapped   = zeta;
02045             //   zeta_mapped = -xi;
02046             // }
02047             //       else
02048             // {
02049             //   // Case 4
02050             //   xi_mapped   = -xi;
02051             //   zeta_mapped = zeta;
02052             // }
02053 
02054             //     else if (elem->node(5) == min_node)
02055             //       if (elem->node(4) == std::min(elem->node(4), elem->node(1)))
02056             // {
02057             //   // Case 5
02058             //   xi_mapped   = -xi;
02059             //   zeta_mapped = -zeta;
02060             // }
02061             //       else
02062             // {
02063             //   // Case 6
02064             //   xi_mapped   = -zeta;
02065             //   zeta_mapped = -xi;
02066             // }
02067 
02068             //     else if (elem->node(4) == min_node)
02069             //       if (elem->node(0) == std::min(elem->node(0), elem->node(5)))
02070             // {
02071             //   // Case 7
02072             //   xi_mapped   = -xi;
02073             //   zeta_mapped = zeta;
02074             // }
02075             //       else
02076             // {
02077             //   // Case 8
02078             //   xi_mapped   = xi;
02079             //   zeta_mapped = -zeta;
02080             // }
02081             //   }
02082 
02083 
02084             // // Face 2
02085             // else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] >= 2))
02086             //   {
02087             //     const unsigned int min_node = std::min(elem->node(1),
02088             //    std::min(elem->node(2),
02089             //     std::min(elem->node(6),
02090             //      elem->node(5))));
02091             //     if (elem->node(1) == min_node)
02092             //       if (elem->node(2) == std::min(elem->node(2), elem->node(5)))
02093             // {
02094             //   // Case 1
02095             //   eta_mapped  = eta;
02096             //   zeta_mapped = zeta;
02097             // }
02098             //       else
02099             // {
02100             //   // Case 2
02101             //   eta_mapped  = zeta;
02102             //   zeta_mapped = eta;
02103             // }
02104 
02105             //     else if (elem->node(2) == min_node)
02106             //       if (elem->node(6) == std::min(elem->node(6), elem->node(1)))
02107             // {
02108             //   // Case 3
02109             //   eta_mapped  = zeta;
02110             //   zeta_mapped = -eta;
02111             // }
02112             //       else
02113             // {
02114             //   // Case 4
02115             //   eta_mapped  = -eta;
02116             //   zeta_mapped = zeta;
02117             // }
02118 
02119             //     else if (elem->node(6) == min_node)
02120             //       if (elem->node(5) == std::min(elem->node(5), elem->node(2)))
02121             // {
02122             //   // Case 5
02123             //   eta_mapped  = -eta;
02124             //   zeta_mapped = -zeta;
02125             // }
02126             //       else
02127             // {
02128             //   // Case 6
02129             //   eta_mapped  = -zeta;
02130             //   zeta_mapped = -eta;
02131             // }
02132 
02133             //     else if (elem->node(5) == min_node)
02134             //       if (elem->node(1) == std::min(elem->node(1), elem->node(6)))
02135             // {
02136             //   // Case 7
02137             //   eta_mapped  = -zeta;
02138             //   zeta_mapped = eta;
02139             // }
02140             //       else
02141             // {
02142             //   // Case 8
02143             //   eta_mapped   = eta;
02144             //   zeta_mapped = -zeta;
02145             // }
02146             //   }
02147 
02148 
02149             // // Face 3
02150             // else if ((i1[i] == 1) && (i0[i] >= 2) && (i2[i] >= 2))
02151             //   {
02152             //     const unsigned int min_node = std::min(elem->node(2),
02153             //    std::min(elem->node(3),
02154             //     std::min(elem->node(7),
02155             //      elem->node(6))));
02156             //     if (elem->node(3) == min_node)
02157             //       if (elem->node(2) == std::min(elem->node(2), elem->node(7)))
02158             // {
02159             //   // Case 1
02160             //   xi_mapped   = xi;
02161             //   zeta_mapped = zeta;
02162             // }
02163             //       else
02164             // {
02165             //   // Case 2
02166             //   xi_mapped   = zeta;
02167             //   zeta_mapped = xi;
02168             // }
02169 
02170             //     else if (elem->node(7) == min_node)
02171             //       if (elem->node(3) == std::min(elem->node(3), elem->node(6)))
02172             // {
02173             //   // Case 3
02174             //   xi_mapped   = -zeta;
02175             //   zeta_mapped = xi;
02176             // }
02177             //       else
02178             // {
02179             //   // Case 4
02180             //   xi_mapped   = xi;
02181             //   zeta_mapped = -zeta;
02182             // }
02183 
02184             //     else if (elem->node(6) == min_node)
02185             //       if (elem->node(7) == std::min(elem->node(7), elem->node(2)))
02186             // {
02187             //   // Case 5
02188             //   xi_mapped   = -xi;
02189             //   zeta_mapped = -zeta;
02190             // }
02191             //       else
02192             // {
02193             //   // Case 6
02194             //   xi_mapped   = -zeta;
02195             //   zeta_mapped = -xi;
02196             // }
02197 
02198             //     else if (elem->node(2) == min_node)
02199             //       if (elem->node(6) == std::min(elem->node(3), elem->node(6)))
02200             // {
02201             //   // Case 7
02202             //   xi_mapped   = zeta;
02203             //   zeta_mapped = -xi;
02204             // }
02205             //       else
02206             // {
02207             //   // Case 8
02208             //   xi_mapped   = -xi;
02209             //   zeta_mapped = zeta;
02210             // }
02211             //   }
02212 
02213 
02214             // // Face 4
02215             // else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] >= 2))
02216             //   {
02217             //     const unsigned int min_node = std::min(elem->node(3),
02218             //    std::min(elem->node(0),
02219             //     std::min(elem->node(4),
02220             //      elem->node(7))));
02221             //     if (elem->node(0) == min_node)
02222             //       if (elem->node(3) == std::min(elem->node(3), elem->node(4)))
02223             // {
02224             //   // Case 1
02225             //   eta_mapped  = eta;
02226             //   zeta_mapped = zeta;
02227             // }
02228             //       else
02229             // {
02230             //   // Case 2
02231             //   eta_mapped  = zeta;
02232             //   zeta_mapped = eta;
02233             // }
02234 
02235             //     else if (elem->node(4) == min_node)
02236             //       if (elem->node(0) == std::min(elem->node(0), elem->node(7)))
02237             // {
02238             //   // Case 3
02239             //   eta_mapped  = -zeta;
02240             //   zeta_mapped = eta;
02241             // }
02242             //       else
02243             // {
02244             //   // Case 4
02245             //   eta_mapped  = eta;
02246             //   zeta_mapped = -zeta;
02247             // }
02248 
02249             //     else if (elem->node(7) == min_node)
02250             //       if (elem->node(4) == std::min(elem->node(4), elem->node(3)))
02251             // {
02252             //   // Case 5
02253             //   eta_mapped  = -eta;
02254             //   zeta_mapped = -zeta;
02255             // }
02256             //       else
02257             // {
02258             //   // Case 6
02259             //   eta_mapped  = -zeta;
02260             //   zeta_mapped = -eta;
02261             // }
02262 
02263             //     else if (elem->node(3) == min_node)
02264             //       if (elem->node(7) == std::min(elem->node(7), elem->node(0)))
02265             // {
02266             //   // Case 7
02267             //   eta_mapped   = zeta;
02268             //   zeta_mapped = -eta;
02269             // }
02270             //       else
02271             // {
02272             //   // Case 8
02273             //   eta_mapped  = -eta;
02274             //   zeta_mapped = zeta;
02275             // }
02276             //   }
02277 
02278 
02279             // // Face 5
02280             // else if ((i2[i] == 1) && (i0[i] >= 2) && (i1[i] >= 2))
02281             //   {
02282             //     const unsigned int min_node = std::min(elem->node(4),
02283             //    std::min(elem->node(5),
02284             //     std::min(elem->node(6),
02285             //      elem->node(7))));
02286             //     if (elem->node(4) == min_node)
02287             //       if (elem->node(5) == std::min(elem->node(5), elem->node(7)))
02288             // {
02289             //   // Case 1
02290             //   xi_mapped  = xi;
02291             //   eta_mapped = eta;
02292             // }
02293             //       else
02294             // {
02295             //   // Case 2
02296             //   xi_mapped  = eta;
02297             //   eta_mapped = xi;
02298             // }
02299 
02300             //     else if (elem->node(5) == min_node)
02301             //       if (elem->node(6) == std::min(elem->node(6), elem->node(4)))
02302             // {
02303             //   // Case 3
02304             //   xi_mapped  = eta;
02305             //   eta_mapped = -xi;
02306             // }
02307             //       else
02308             // {
02309             //   // Case 4
02310             //   xi_mapped  = -xi;
02311             //   eta_mapped = eta;
02312             // }
02313 
02314             //     else if (elem->node(6) == min_node)
02315             //       if (elem->node(7) == std::min(elem->node(7), elem->node(5)))
02316             // {
02317             //   // Case 5
02318             //   xi_mapped  = -xi;
02319             //   eta_mapped = -eta;
02320             // }
02321             //       else
02322             // {
02323             //   // Case 6
02324             //   xi_mapped  = -eta;
02325             //   eta_mapped = -xi;
02326             // }
02327 
02328             //     else if (elem->node(7) == min_node)
02329             //       if (elem->node(4) == std::min(elem->node(4), elem->node(6)))
02330             // {
02331             //   // Case 7
02332             //   xi_mapped  = -eta;
02333             //   eta_mapped = xi;
02334             // }
02335             //       else
02336             // {
02337             //   // Case 8
02338             //   xi_mapped  = xi;
02339             //   eta_mapped = eta;
02340             // }
02341             //   }
02342 
02343 
02344             //       }
02345 
02346 
02347 
02348             //       libmesh_assert_less (j, 3);
02349 
02350             //       switch (j)
02351             // {
02352             //   // d()/dxi
02353             // case 0:
02354             //   return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi_mapped)*
02355             //   FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[i],    eta_mapped)*
02356             //   FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[i],    zeta_mapped));
02357 
02358             //   // d()/deta
02359             // case 1:
02360             //   return (FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[i],    xi_mapped)*
02361             //   FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta_mapped)*
02362             //   FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[i],    zeta_mapped));
02363 
02364             //   // d()/dzeta
02365             // case 2:
02366             //   return (FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[i],    xi_mapped)*
02367             //   FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[i],    eta_mapped)*
02368             //   FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[i], 0, zeta_mapped));
02369 
02370             // default:
02371             // libmesh_error_msg("Invalid derivative index j = " << j);
02372             // }
02373             //     }
02374 
02375 
02376           default:
02377             libmesh_error_msg("Invalid element type = " << type);
02378           }
02379       }
02380 
02381       // 4th-order Bernstein.
02382     case FOURTH:
02383       {
02384         switch (type)
02385           {
02386 
02387             // Bernstein shape functions derivatives on the hexahedral.
02388           case HEX27:
02389             {
02390               const Real eps = 1.e-6;
02391 
02392               libmesh_assert_less (i, 125);
02393               libmesh_assert_less (j, 3);
02394 
02395               switch (j)
02396                 {
02397                   //  d()/dxi
02398                 case 0:
02399                   {
02400                     const Point pp(p(0)+eps, p(1), p(2));
02401                     const Point pm(p(0)-eps, p(1), p(2));
02402 
02403                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
02404                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
02405                   }
02406 
02407                   // d()/deta
02408                 case 1:
02409                   {
02410                     const Point pp(p(0), p(1)+eps, p(2));
02411                     const Point pm(p(0), p(1)-eps, p(2));
02412 
02413                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
02414                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
02415                   }
02416                   // d()/dzeta
02417                 case 2:
02418                   {
02419                     const Point pp(p(0), p(1), p(2)+eps);
02420                     const Point pm(p(0), p(1), p(2)-eps);
02421 
02422                     return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
02423                             FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
02424                   }
02425                 default:
02426                   libmesh_error_msg("Invalid derivative index j = " << j);
02427                 }
02428             }
02429 
02430             //       // Compute hex shape functions as a tensor-product
02431             //       const Real xi    = p(0);
02432             //       const Real eta   = p(1);
02433             //       const Real zeta  = p(2);
02434             //       Real xi_mapped   = p(0);
02435             //       Real eta_mapped  = p(1);
02436             //       Real zeta_mapped = p(2);
02437 
02438             //       // The only way to make any sense of this
02439             //       // is to look at the mgflo/mg2/mgf documentation
02440             //       // and make the cut-out cube!
02441             //       //  Nodes                         0  1  2  3  4  5  6  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24 25 25 25 25 26 26 26 26 26 26 26 26
02442             //       //  DOFS                          0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 18 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 60 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
02443             //       static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4};
02444             //       static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4};
02445             //       static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4};
02446 
02447 
02448 
02449             //       // handle the edge orientation
02450             //       {
02451             // // Edge 0
02452             // if ((i1[i] == 0) && (i2[i] == 0))
02453             //   {
02454             //     if (elem->node(0) != std::min(elem->node(0), elem->node(1)))
02455             //       xi_mapped = -xi;
02456             //   }
02457             // // Edge 1
02458             // else if ((i0[i] == 1) && (i2[i] == 0))
02459             //   {
02460             //     if (elem->node(1) != std::min(elem->node(1), elem->node(2)))
02461             //       eta_mapped = -eta;
02462             //   }
02463             // // Edge 2
02464             // else if ((i1[i] == 1) && (i2[i] == 0))
02465             //   {
02466             //     if (elem->node(3) != std::min(elem->node(3), elem->node(2)))
02467             //       xi_mapped = -xi;
02468             //   }
02469             // // Edge 3
02470             // else if ((i0[i] == 0) && (i2[i] == 0))
02471             //   {
02472             //     if (elem->node(0) != std::min(elem->node(0), elem->node(3)))
02473             //       eta_mapped = -eta;
02474             //   }
02475             // // Edge 4
02476             // else if ((i0[i] == 0) && (i1[i] == 0))
02477             //   {
02478             //     if (elem->node(0) != std::min(elem->node(0), elem->node(4)))
02479             //       zeta_mapped = -zeta;
02480             //   }
02481             // // Edge 5
02482             // else if ((i0[i] == 1) && (i1[i] == 0))
02483             //   {
02484             //     if (elem->node(1) != std::min(elem->node(1), elem->node(5)))
02485             //       zeta_mapped = -zeta;
02486             //   }
02487             // // Edge 6
02488             // else if ((i0[i] == 1) && (i1[i] == 1))
02489             //   {
02490             //     if (elem->node(2) != std::min(elem->node(2), elem->node(6)))
02491             //       zeta_mapped = -zeta;
02492             //   }
02493             // // Edge 7
02494             // else if ((i0[i] == 0) && (i1[i] == 1))
02495             //   {
02496             //     if (elem->node(3) != std::min(elem->node(3), elem->node(7)))
02497             //       zeta_mapped = -zeta;
02498             //   }
02499             // // Edge 8
02500             // else if ((i1[i] == 0) && (i2[i] == 1))
02501             //   {
02502             //     if (elem->node(4) != std::min(elem->node(4), elem->node(5)))
02503             //       xi_mapped = -xi;
02504             //   }
02505             // // Edge 9
02506             // else if ((i0[i] == 1) && (i2[i] == 1))
02507             //   {
02508             //     if (elem->node(5) != std::min(elem->node(5), elem->node(6)))
02509             //       eta_mapped = -eta;
02510             //   }
02511             // // Edge 10
02512             // else if ((i1[i] == 1) && (i2[i] == 1))
02513             //   {
02514             //     if (elem->node(7) != std::min(elem->node(7), elem->node(6)))
02515             //       xi_mapped = -xi;
02516             //   }
02517             // // Edge 11
02518             // else if ((i0[i] == 0) && (i2[i] == 1))
02519             //   {
02520             //     if (elem->node(4) != std::min(elem->node(4), elem->node(7)))
02521             //       eta_mapped = -eta;
02522             //   }
02523             //       }
02524 
02525 
02526             //       // handle the face orientation
02527             //       {
02528             // // Face 0
02529             // if (     (i2[i] == 0) && (i0[i] >= 2) && (i1[i] >= 2))
02530             //   {
02531             //     const unsigned int min_node = std::min(elem->node(1),
02532             //    std::min(elem->node(2),
02533             //     std::min(elem->node(0),
02534             //      elem->node(3))));
02535             //     if (elem->node(0) == min_node)
02536             //       if (elem->node(1) == std::min(elem->node(1), elem->node(3)))
02537             // {
02538             //   // Case 1
02539             //   xi_mapped  = xi;
02540             //   eta_mapped = eta;
02541             // }
02542             //       else
02543             // {
02544             //   // Case 2
02545             //   xi_mapped  = eta;
02546             //   eta_mapped = xi;
02547             // }
02548 
02549             //     else if (elem->node(3) == min_node)
02550             //       if (elem->node(0) == std::min(elem->node(0), elem->node(2)))
02551             // {
02552             //   // Case 3
02553             //   xi_mapped  = -eta;
02554             //   eta_mapped = xi;
02555             // }
02556             //       else
02557             // {
02558             //   // Case 4
02559             //   xi_mapped  = xi;
02560             //   eta_mapped = -eta;
02561             // }
02562 
02563             //     else if (elem->node(2) == min_node)
02564             //       if (elem->node(3) == std::min(elem->node(3), elem->node(1)))
02565             // {
02566             //   // Case 5
02567             //   xi_mapped  = -xi;
02568             //   eta_mapped = -eta;
02569             // }
02570             //       else
02571             // {
02572             //   // Case 6
02573             //   xi_mapped  = -eta;
02574             //   eta_mapped = -xi;
02575             // }
02576 
02577             //     else if (elem->node(1) == min_node)
02578             //       if (elem->node(2) == std::min(elem->node(2), elem->node(0)))
02579             // {
02580             //   // Case 7
02581             //   xi_mapped  = eta;
02582             //   eta_mapped = -xi;
02583             // }
02584             //       else
02585             // {
02586             //   // Case 8
02587             //   xi_mapped  = -xi;
02588             //   eta_mapped = eta;
02589             // }
02590             //   }
02591 
02592 
02593             // // Face 1
02594             // else if ((i1[i] == 0) && (i0[i] >= 2) && (i2[i] >= 2))
02595             //   {
02596             //     const unsigned int min_node = std::min(elem->node(0),
02597             //    std::min(elem->node(1),
02598             //     std::min(elem->node(5),
02599             //      elem->node(4))));
02600             //     if (elem->node(0) == min_node)
02601             //       if (elem->node(1) == std::min(elem->node(1), elem->node(4)))
02602             // {
02603             //   // Case 1
02604             //   xi_mapped   = xi;
02605             //   zeta_mapped = zeta;
02606             // }
02607             //       else
02608             // {
02609             //   // Case 2
02610             //   xi_mapped   = zeta;
02611             //   zeta_mapped = xi;
02612             // }
02613 
02614             //     else if (elem->node(1) == min_node)
02615             //       if (elem->node(5) == std::min(elem->node(5), elem->node(0)))
02616             // {
02617             //   // Case 3
02618             //   xi_mapped   = zeta;
02619             //   zeta_mapped = -xi;
02620             // }
02621             //       else
02622             // {
02623             //   // Case 4
02624             //   xi_mapped   = -xi;
02625             //   zeta_mapped = zeta;
02626             // }
02627 
02628             //     else if (elem->node(5) == min_node)
02629             //       if (elem->node(4) == std::min(elem->node(4), elem->node(1)))
02630             // {
02631             //   // Case 5
02632             //   xi_mapped   = -xi;
02633             //   zeta_mapped = -zeta;
02634             // }
02635             //       else
02636             // {
02637             //   // Case 6
02638             //   xi_mapped   = -zeta;
02639             //   zeta_mapped = -xi;
02640             // }
02641 
02642             //     else if (elem->node(4) == min_node)
02643             //       if (elem->node(0) == std::min(elem->node(0), elem->node(5)))
02644             // {
02645             //   // Case 7
02646             //   xi_mapped   = -xi;
02647             //   zeta_mapped = zeta;
02648             // }
02649             //       else
02650             // {
02651             //   // Case 8
02652             //   xi_mapped   = xi;
02653             //   zeta_mapped = -zeta;
02654             // }
02655             //   }
02656 
02657 
02658             // // Face 2
02659             // else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] >= 2))
02660             //   {
02661             //     const unsigned int min_node = std::min(elem->node(1),
02662             //    std::min(elem->node(2),
02663             //     std::min(elem->node(6),
02664             //      elem->node(5))));
02665             //     if (elem->node(1) == min_node)
02666             //       if (elem->node(2) == std::min(elem->node(2), elem->node(5)))
02667             // {
02668             //   // Case 1
02669             //   eta_mapped  = eta;
02670             //   zeta_mapped = zeta;
02671             // }
02672             //       else
02673             // {
02674             //   // Case 2
02675             //   eta_mapped  = zeta;
02676             //   zeta_mapped = eta;
02677             // }
02678 
02679             //     else if (elem->node(2) == min_node)
02680             //       if (elem->node(6) == std::min(elem->node(6), elem->node(1)))
02681             // {
02682             //   // Case 3
02683             //   eta_mapped  = zeta;
02684             //   zeta_mapped = -eta;
02685             // }
02686             //       else
02687             // {
02688             //   // Case 4
02689             //   eta_mapped  = -eta;
02690             //   zeta_mapped = zeta;
02691             // }
02692 
02693             //     else if (elem->node(6) == min_node)
02694             //       if (elem->node(5) == std::min(elem->node(5), elem->node(2)))
02695             // {
02696             //   // Case 5
02697             //   eta_mapped  = -eta;
02698             //   zeta_mapped = -zeta;
02699             // }
02700             //       else
02701             // {
02702             //   // Case 6
02703             //   eta_mapped  = -zeta;
02704             //   zeta_mapped = -eta;
02705             // }
02706 
02707             //     else if (elem->node(5) == min_node)
02708             //       if (elem->node(1) == std::min(elem->node(1), elem->node(6)))
02709             // {
02710             //   // Case 7
02711             //   eta_mapped  = -zeta;
02712             //   zeta_mapped = eta;
02713             // }
02714             //       else
02715             // {
02716             //   // Case 8
02717             //   eta_mapped   = eta;
02718             //   zeta_mapped = -zeta;
02719             // }
02720             //   }
02721 
02722 
02723             // // Face 3
02724             // else if ((i1[i] == 1) && (i0[i] >= 2) && (i2[i] >= 2))
02725             //   {
02726             //     const unsigned int min_node = std::min(elem->node(2),
02727             //    std::min(elem->node(3),
02728             //     std::min(elem->node(7),
02729             //      elem->node(6))));
02730             //     if (elem->node(3) == min_node)
02731             //       if (elem->node(2) == std::min(elem->node(2), elem->node(7)))
02732             // {
02733             //   // Case 1
02734             //   xi_mapped   = xi;
02735             //   zeta_mapped = zeta;
02736             // }
02737             //       else
02738             // {
02739             //   // Case 2
02740             //   xi_mapped   = zeta;
02741             //   zeta_mapped = xi;
02742             // }
02743 
02744             //     else if (elem->node(7) == min_node)
02745             //       if (elem->node(3) == std::min(elem->node(3), elem->node(6)))
02746             // {
02747             //   // Case 3
02748             //   xi_mapped   = -zeta;
02749             //   zeta_mapped = xi;
02750             // }
02751             //       else
02752             // {
02753             //   // Case 4
02754             //   xi_mapped   = xi;
02755             //   zeta_mapped = -zeta;
02756             // }
02757 
02758             //     else if (elem->node(6) == min_node)
02759             //       if (elem->node(7) == std::min(elem->node(7), elem->node(2)))
02760             // {
02761             //   // Case 5
02762             //   xi_mapped   = -xi;
02763             //   zeta_mapped = -zeta;
02764             // }
02765             //       else
02766             // {
02767             //   // Case 6
02768             //   xi_mapped   = -zeta;
02769             //   zeta_mapped = -xi;
02770             // }
02771 
02772             //     else if (elem->node(2) == min_node)
02773             //       if (elem->node(6) == std::min(elem->node(3), elem->node(6)))
02774             // {
02775             //   // Case 7
02776             //   xi_mapped   = zeta;
02777             //   zeta_mapped = -xi;
02778             // }
02779             //       else
02780             // {
02781             //   // Case 8
02782             //   xi_mapped   = -xi;
02783             //   zeta_mapped = zeta;
02784             // }
02785             //   }
02786 
02787 
02788             // // Face 4
02789             // else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] >= 2))
02790             //   {
02791             //     const unsigned int min_node = std::min(elem->node(3),
02792             //    std::min(elem->node(0),
02793             //     std::min(elem->node(4),
02794             //      elem->node(7))));
02795             //     if (elem->node(0) == min_node)
02796             //       if (elem->node(3) == std::min(elem->node(3), elem->node(4)))
02797             // {
02798             //   // Case 1
02799             //   eta_mapped  = eta;
02800             //   zeta_mapped = zeta;
02801             // }
02802             //       else
02803             // {
02804             //   // Case 2
02805             //   eta_mapped  = zeta;
02806             //   zeta_mapped = eta;
02807             // }
02808 
02809             //     else if (elem->node(4) == min_node)
02810             //       if (elem->node(0) == std::min(elem->node(0), elem->node(7)))
02811             // {
02812             //   // Case 3
02813             //   eta_mapped  = -zeta;
02814             //   zeta_mapped = eta;
02815             // }
02816             //       else
02817             // {
02818             //   // Case 4
02819             //   eta_mapped  = eta;
02820             //   zeta_mapped = -zeta;
02821             // }
02822 
02823             //     else if (elem->node(7) == min_node)
02824             //       if (elem->node(4) == std::min(elem->node(4), elem->node(3)))
02825             // {
02826             //   // Case 5
02827             //   eta_mapped  = -eta;
02828             //   zeta_mapped = -zeta;
02829             // }
02830             //       else
02831             // {
02832             //   // Case 6
02833             //   eta_mapped  = -zeta;
02834             //   zeta_mapped = -eta;
02835             // }
02836 
02837             //     else if (elem->node(3) == min_node)
02838             //       if (elem->node(7) == std::min(elem->node(7), elem->node(0)))
02839             // {
02840             //   // Case 7
02841             //   eta_mapped   = zeta;
02842             //   zeta_mapped = -eta;
02843             // }
02844             //       else
02845             // {
02846             //   // Case 8
02847             //   eta_mapped  = -eta;
02848             //   zeta_mapped = zeta;
02849             // }
02850             //   }
02851 
02852 
02853             // // Face 5
02854             // else if ((i2[i] == 1) && (i0[i] >= 2) && (i1[i] >= 2))
02855             //   {
02856             //     const unsigned int min_node = std::min(elem->node(4),
02857             //    std::min(elem->node(5),
02858             //     std::min(elem->node(6),
02859             //      elem->node(7))));
02860             //     if (elem->node(4) == min_node)
02861             //       if (elem->node(5) == std::min(elem->node(5), elem->node(7)))
02862             // {
02863             //   // Case 1
02864             //   xi_mapped  = xi;
02865             //   eta_mapped = eta;
02866             // }
02867             //       else
02868             // {
02869             //   // Case 2
02870             //   xi_mapped  = eta;
02871             //   eta_mapped = xi;
02872             // }
02873 
02874             //     else if (elem->node(5) == min_node)
02875             //       if (elem->node(6) == std::min(elem->node(6), elem->node(4)))
02876             // {
02877             //   // Case 3
02878             //   xi_mapped  = eta;
02879             //   eta_mapped = -xi;
02880             // }
02881             //       else
02882             // {
02883             //   // Case 4
02884             //   xi_mapped  = -xi;
02885             //   eta_mapped = eta;
02886             // }
02887 
02888             //     else if (elem->node(6) == min_node)
02889             //       if (elem->node(7) == std::min(elem->node(7), elem->node(5)))
02890             // {
02891             //   // Case 5
02892             //   xi_mapped  = -xi;
02893             //   eta_mapped = -eta;
02894             // }
02895             //       else
02896             // {
02897             //   // Case 6
02898             //   xi_mapped  = -eta;
02899             //   eta_mapped = -xi;
02900             // }
02901 
02902             //     else if (elem->node(7) == min_node)
02903             //       if (elem->node(4) == std::min(elem->node(4), elem->node(6)))
02904             // {
02905             //   // Case 7
02906             //   xi_mapped  = -eta;
02907             //   eta_mapped = xi;
02908             // }
02909             //       else
02910             // {
02911             //   // Case 8
02912             //   xi_mapped  = xi;
02913             //   eta_mapped = eta;
02914             // }
02915             //   }
02916 
02917 
02918             //       }
02919 
02920 
02921 
02922             //       libmesh_assert_less (j, 3);
02923 
02924             //       switch (j)
02925             // {
02926             //   // d()/dxi
02927             // case 0:
02928             //   return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi_mapped)*
02929             //   FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[i],    eta_mapped)*
02930             //   FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[i],    zeta_mapped));
02931 
02932             //   // d()/deta
02933             // case 1:
02934             //   return (FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[i],    xi_mapped)*
02935             //   FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta_mapped)*
02936             //   FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i2[i],    zeta_mapped));
02937 
02938             //   // d()/dzeta
02939             // case 2:
02940             //   return (FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i0[i],    xi_mapped)*
02941             //   FE<1,BERNSTEIN>::shape      (EDGE3, totalorder, i1[i],    eta_mapped)*
02942             //   FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[i], 0, zeta_mapped));
02943 
02944             // default:
02945             //   libmesh_error_msg("Invalid derivative index j = " << j);
02946             // }
02947             //    }
02948 
02949 
02950           default:
02951             libmesh_error_msg("Invalid element type = " << type);
02952           }
02953       }
02954 
02955 
02956     default:
02957       libmesh_error_msg("Invalid totalorder = " << totalorder);
02958     }
02959 
02960 #endif
02961 
02962   libmesh_error_msg("We'll never get here!");
02963   return 0.;
02964 }
02965 
02966 
02967 
02968 template <>
02969 Real FE<3,BERNSTEIN>::shape_second_deriv(const ElemType,
02970                                          const Order,
02971                                          const unsigned int,
02972                                          const unsigned int,
02973                                          const Point&)
02974 {
02975   static bool warning_given = false;
02976 
02977   if (!warning_given)
02978     libMesh::err << "Second derivatives for Bernstein elements "
02979                  << "are not yet implemented!"
02980                  << std::endl;
02981 
02982   warning_given = true;
02983   return 0.;
02984 }
02985 
02986 
02987 
02988 template <>
02989 Real FE<3,BERNSTEIN>::shape_second_deriv(const Elem*,
02990                                          const Order,
02991                                          const unsigned int,
02992                                          const unsigned int,
02993                                          const Point&)
02994 {
02995   static bool warning_given = false;
02996 
02997   if (!warning_given)
02998     libMesh::err << "Second derivatives for Bernstein elements "
02999                  << "are not yet implemented!"
03000                  << std::endl;
03001 
03002   warning_given = true;
03003   return 0.;
03004 }
03005 
03006 } // namespace libMesh
03007 
03008 
03009 
03010 #endif //LIBMESH_ENABLE_HIGHER_ORDER_SHAPES