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