$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 00020 // Local includes 00021 #include "libmesh/libmesh_config.h" 00022 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 00023 00024 #include "libmesh/fe.h" 00025 #include "libmesh/elem.h" 00026 #include "libmesh/fe_interface.h" 00027 #include "libmesh/string_to_enum.h" 00028 00029 namespace libMesh 00030 { 00031 00032 // ------------------------------------------------------------ 00033 // Szabo-Babuska-specific implementations, Steffen Petersen 2004 00034 00035 // Anonymous namespace for local helper functions 00036 namespace { 00037 00038 void szabab_nodal_soln(const Elem* elem, 00039 const Order order, 00040 const std::vector<Number>& elem_soln, 00041 std::vector<Number>& nodal_soln, 00042 unsigned Dim) 00043 { 00044 const unsigned int n_nodes = elem->n_nodes(); 00045 00046 const ElemType elem_type = elem->type(); 00047 00048 nodal_soln.resize(n_nodes); 00049 00050 const Order totalorder = static_cast<Order>(order+elem->p_level()); 00051 00052 // FEType object to be passed to various FEInterface functions below. 00053 FEType fe_type(totalorder, SZABAB); 00054 00055 switch (totalorder) 00056 { 00057 // Constant shape functions 00058 case CONSTANT: 00059 { 00060 libmesh_assert_equal_to (elem_soln.size(), 1); 00061 00062 const Number val = elem_soln[0]; 00063 00064 for (unsigned int n=0; n<n_nodes; n++) 00065 nodal_soln[n] = val; 00066 00067 return; 00068 } 00069 00070 00071 // For other bases do interpolation at the nodes 00072 // explicitly. 00073 case FIRST: 00074 case SECOND: 00075 case THIRD: 00076 case FOURTH: 00077 case FIFTH: 00078 case SIXTH: 00079 case SEVENTH: 00080 { 00081 00082 const unsigned int n_sf = 00083 // FE<Dim,T>::n_shape_functions(elem_type, totalorder); 00084 FEInterface::n_shape_functions(Dim, fe_type, elem_type); 00085 00086 std::vector<Point> refspace_nodes; 00087 FEBase::get_refspace_nodes(elem_type,refspace_nodes); 00088 libmesh_assert_equal_to (refspace_nodes.size(), n_nodes); 00089 00090 for (unsigned int n=0; n<n_nodes; n++) 00091 { 00092 libmesh_assert_equal_to (elem_soln.size(), n_sf); 00093 00094 // Zero before summation 00095 nodal_soln[n] = 0; 00096 00097 // u_i = Sum (alpha_i phi_i) 00098 for (unsigned int i=0; i<n_sf; i++) 00099 nodal_soln[n] += elem_soln[i] * 00100 // FE<Dim,T>::shape(elem, order, i, mapped_point); 00101 FEInterface::shape(Dim, fe_type, elem, i, refspace_nodes[n]); 00102 } 00103 00104 return; 00105 } 00106 00107 default: 00108 libmesh_error_msg("ERROR: Invalid total order " << totalorder); 00109 } 00110 } // szabab_nodal_soln() 00111 00112 00113 00114 00115 unsigned int szabab_n_dofs(const ElemType t, const Order o) 00116 { 00117 switch (o) 00118 { 00119 // Szabo-Babuska 1st-order polynomials. 00120 case FIRST: 00121 { 00122 switch (t) 00123 { 00124 case NODEELEM: 00125 return 1; 00126 00127 case EDGE2: 00128 case EDGE3: 00129 return 2; 00130 00131 case TRI6: 00132 return 3; 00133 00134 case QUAD8: 00135 case QUAD9: 00136 return 4; 00137 00138 case INVALID_ELEM: 00139 return 0; 00140 00141 default: 00142 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00143 } 00144 } 00145 00146 00147 // Szabo-Babuska 2nd-order polynomials. 00148 case SECOND: 00149 { 00150 switch (t) 00151 { 00152 case NODEELEM: 00153 return 1; 00154 00155 case EDGE2: 00156 case EDGE3: 00157 return 3; 00158 00159 case TRI6: 00160 return 6; 00161 00162 case QUAD8: 00163 return 8; 00164 case QUAD9: 00165 return 9; 00166 00167 case INVALID_ELEM: 00168 return 0; 00169 00170 default: 00171 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00172 } 00173 } 00174 00175 00176 // Szabo-Babuska 3rd-order polynomials. 00177 case THIRD: 00178 { 00179 switch (t) 00180 { 00181 case NODEELEM: 00182 return 1; 00183 00184 case EDGE2: 00185 case EDGE3: 00186 return 4; 00187 00188 case TRI6: 00189 return 10; 00190 00191 case QUAD8: 00192 case QUAD9: 00193 return 16; 00194 00195 case INVALID_ELEM: 00196 return 0; 00197 00198 default: 00199 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00200 } 00201 } 00202 00203 00204 // Szabo-Babuska 4th-order polynomials. 00205 case FOURTH: 00206 { 00207 switch (t) 00208 { 00209 case NODEELEM: 00210 return 1; 00211 00212 case EDGE2: 00213 case EDGE3: 00214 return 5; 00215 00216 case TRI6: 00217 return 15; 00218 00219 case QUAD8: 00220 case QUAD9: 00221 return 25; 00222 00223 case INVALID_ELEM: 00224 return 0; 00225 00226 default: 00227 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00228 } 00229 } 00230 00231 00232 // Szabo-Babuska 5th-order polynomials. 00233 case FIFTH: 00234 { 00235 switch (t) 00236 { 00237 case NODEELEM: 00238 return 1; 00239 00240 case EDGE2: 00241 case EDGE3: 00242 return 6; 00243 00244 case TRI6: 00245 return 21; 00246 00247 case QUAD8: 00248 case QUAD9: 00249 return 36; 00250 00251 case INVALID_ELEM: 00252 return 0; 00253 00254 default: 00255 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00256 } 00257 } 00258 00259 00260 // Szabo-Babuska 6th-order polynomials. 00261 case SIXTH: 00262 { 00263 switch (t) 00264 { 00265 case NODEELEM: 00266 return 1; 00267 00268 case EDGE2: 00269 case EDGE3: 00270 return 7; 00271 00272 case TRI6: 00273 return 28; 00274 00275 case QUAD8: 00276 case QUAD9: 00277 return 49; 00278 00279 case INVALID_ELEM: 00280 return 0; 00281 00282 default: 00283 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00284 } 00285 } 00286 00287 // Szabo-Babuska 7th-order polynomials. 00288 case SEVENTH: 00289 { 00290 switch (t) 00291 { 00292 case NODEELEM: 00293 return 1; 00294 00295 case EDGE2: 00296 case EDGE3: 00297 return 8; 00298 00299 case TRI6: 00300 return 36; 00301 00302 case QUAD8: 00303 case QUAD9: 00304 return 64; 00305 00306 case INVALID_ELEM: 00307 return 0; 00308 00309 default: 00310 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00311 } 00312 } 00313 00314 00315 default: 00316 libmesh_error_msg("ERROR: Invalid Order " << Utility::enum_to_string(o) << " selected for SZABAB FE family!"); 00317 } 00318 00319 libmesh_error_msg("We'll never get here!"); 00320 return 0; 00321 } // szabab_n_dofs() 00322 00323 00324 00325 00326 00327 unsigned int szabab_n_dofs_at_node(const ElemType t, 00328 const Order o, 00329 const unsigned int n) 00330 { 00331 switch (o) 00332 { 00333 // The first-order Szabo-Babuska shape functions 00334 case FIRST: 00335 { 00336 switch (t) 00337 { 00338 case NODEELEM: 00339 return 1; 00340 00341 // The 1D Szabo-Babuska defined on a three-noded edge 00342 case EDGE2: 00343 case EDGE3: 00344 { 00345 switch (n) 00346 { 00347 case 0: 00348 case 1: 00349 return 1; 00350 00351 case 2: 00352 return 0; 00353 00354 default: 00355 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!"); 00356 } 00357 } 00358 00359 00360 // The 2D Szabo-Babuska defined on a 6-noded triangle 00361 case TRI6: 00362 { 00363 switch (n) 00364 { 00365 case 0: 00366 case 1: 00367 case 2: 00368 return 1; 00369 00370 case 3: 00371 case 4: 00372 case 5: 00373 return 0; 00374 00375 default: 00376 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!"); 00377 } 00378 } 00379 00380 00381 // The 2D tensor-product Szabo-Babuska defined on a 00382 // nine-noded quadrilateral. 00383 case QUAD8: 00384 case QUAD9: 00385 { 00386 switch (n) 00387 { 00388 case 0: 00389 case 1: 00390 case 2: 00391 case 3: 00392 return 1; 00393 00394 case 4: 00395 case 5: 00396 case 6: 00397 case 7: 00398 return 0; 00399 00400 case 8: 00401 return 0; 00402 00403 default: 00404 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!"); 00405 } 00406 } 00407 00408 case INVALID_ELEM: 00409 return 0; 00410 00411 default: 00412 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00413 } 00414 } 00415 00416 00417 00418 // The second-order Szabo-Babuska shape functions 00419 case SECOND: 00420 { 00421 switch (t) 00422 { 00423 case NODEELEM: 00424 return 1; 00425 00426 // The 1D Szabo-Babuska defined on a three-noded edge 00427 case EDGE2: 00428 case EDGE3: 00429 { 00430 switch (n) 00431 { 00432 case 0: 00433 case 1: 00434 return 1; 00435 00436 case 2: 00437 return 1; 00438 00439 default: 00440 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!"); 00441 } 00442 } 00443 00444 00445 // The 2D Szabo-Babuska defined on a 6-noded triangle 00446 case TRI6: 00447 { 00448 switch (n) 00449 { 00450 case 0: 00451 case 1: 00452 case 2: 00453 return 1; 00454 00455 case 3: 00456 case 4: 00457 case 5: 00458 return 1; 00459 00460 default: 00461 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!"); 00462 } 00463 } 00464 00465 00466 // The 2D tensor-product Szabo-Babuska defined on a 00467 // nine-noded quadrilateral. 00468 case QUAD8: 00469 case QUAD9: 00470 { 00471 switch (n) 00472 { 00473 case 0: 00474 case 1: 00475 case 2: 00476 case 3: 00477 return 1; 00478 00479 case 4: 00480 case 5: 00481 case 6: 00482 case 7: 00483 return 1; 00484 00485 case 8: 00486 return 1; 00487 00488 default: 00489 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!"); 00490 } 00491 } 00492 00493 case INVALID_ELEM: 00494 return 0; 00495 00496 default: 00497 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00498 } 00499 } 00500 00501 00502 00503 // The third-order Szabo-Babuska shape functions 00504 case THIRD: 00505 { 00506 switch (t) 00507 { 00508 case NODEELEM: 00509 return 1; 00510 00511 // The 1D Szabo-Babuska defined on a three-noded edge 00512 case EDGE2: 00513 case EDGE3: 00514 { 00515 switch (n) 00516 { 00517 case 0: 00518 case 1: 00519 return 1; 00520 00521 case 2: 00522 return 2; 00523 00524 default: 00525 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!"); 00526 } 00527 } 00528 00529 00530 // The 2D Szabo-Babuska defined on a 6-noded triangle 00531 case TRI6: 00532 { 00533 switch (n) 00534 { 00535 case 0: 00536 case 1: 00537 case 2: 00538 return 1; 00539 00540 case 3: 00541 case 4: 00542 case 5: 00543 return 2; 00544 00545 default: 00546 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!"); 00547 } 00548 } 00549 00550 00551 // The 2D tensor-product Szabo-Babuska defined on a 00552 // nine-noded quadrilateral. 00553 case QUAD8: 00554 case QUAD9: 00555 { 00556 switch (n) 00557 { 00558 case 0: 00559 case 1: 00560 case 2: 00561 case 3: 00562 return 1; 00563 00564 case 4: 00565 case 5: 00566 case 6: 00567 case 7: 00568 return 2; 00569 00570 case 8: 00571 return 4; 00572 00573 default: 00574 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!"); 00575 } 00576 } 00577 00578 case INVALID_ELEM: 00579 return 0; 00580 00581 default: 00582 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00583 } 00584 } 00585 00586 00587 00588 // The fourth-order Szabo-Babuska shape functions 00589 case FOURTH: 00590 { 00591 switch (t) 00592 { 00593 case NODEELEM: 00594 return 1; 00595 00596 // The 1D Szabo-Babuska defined on a three-noded edge 00597 case EDGE2: 00598 case EDGE3: 00599 { 00600 switch (n) 00601 { 00602 case 0: 00603 case 1: 00604 return 1; 00605 00606 case 2: 00607 return 3; 00608 00609 default: 00610 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!"); 00611 } 00612 } 00613 00614 00615 // The 2D Szabo-Babuska defined on a 6-noded triangle 00616 case TRI6: 00617 { 00618 switch (n) 00619 { 00620 case 0: 00621 case 1: 00622 case 2: 00623 return 1; 00624 00625 case 3: 00626 case 4: 00627 case 5: 00628 return 3; 00629 00630 default: 00631 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!"); 00632 } 00633 } 00634 00635 00636 // The 2D tensor-product Szabo-Babuska defined on a 00637 // nine-noded quadrilateral. 00638 case QUAD8: 00639 case QUAD9: 00640 { 00641 switch (n) 00642 { 00643 case 0: 00644 case 1: 00645 case 2: 00646 case 3: 00647 return 1; 00648 00649 case 4: 00650 case 5: 00651 case 6: 00652 case 7: 00653 return 3; 00654 00655 case 8: 00656 return 9; 00657 00658 default: 00659 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!"); 00660 } 00661 } 00662 00663 case INVALID_ELEM: 00664 return 0; 00665 00666 default: 00667 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00668 } 00669 } 00670 00671 00672 00673 // The fifth-order Szabo-Babuska shape functions 00674 case FIFTH: 00675 { 00676 switch (t) 00677 { 00678 case NODEELEM: 00679 return 1; 00680 00681 // The 1D Szabo-Babuska defined on a three-noded edge 00682 case EDGE2: 00683 case EDGE3: 00684 { 00685 switch (n) 00686 { 00687 case 0: 00688 case 1: 00689 return 1; 00690 00691 case 2: 00692 return 4; 00693 00694 default: 00695 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!"); 00696 } 00697 } 00698 00699 00700 // The 2D Szabo-Babuska defined on a 6-noded triangle 00701 case TRI6: 00702 { 00703 switch (n) 00704 { 00705 case 0: 00706 case 1: 00707 case 2: 00708 return 1; 00709 00710 case 3: 00711 case 4: 00712 case 5: 00713 return 4; 00714 00715 default: 00716 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!"); 00717 } 00718 } 00719 00720 00721 // The 2D tensor-product Szabo-Babuska defined on a 00722 // nine-noded quadrilateral. 00723 case QUAD8: 00724 case QUAD9: 00725 { 00726 switch (n) 00727 { 00728 case 0: 00729 case 1: 00730 case 2: 00731 case 3: 00732 return 1; 00733 00734 case 4: 00735 case 5: 00736 case 6: 00737 case 7: 00738 return 4; 00739 00740 case 8: 00741 return 16; 00742 00743 default: 00744 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!"); 00745 } 00746 } 00747 00748 case INVALID_ELEM: 00749 return 0; 00750 00751 default: 00752 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00753 } 00754 } 00755 00756 00757 00758 // The sixth-order Szabo-Babuska shape functions 00759 case SIXTH: 00760 { 00761 switch (t) 00762 { 00763 case NODEELEM: 00764 return 1; 00765 00766 // The 1D Szabo-Babuska defined on a three-noded edge 00767 case EDGE2: 00768 case EDGE3: 00769 { 00770 switch (n) 00771 { 00772 case 0: 00773 case 1: 00774 return 1; 00775 00776 case 2: 00777 return 5; 00778 00779 default: 00780 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!"); 00781 } 00782 } 00783 00784 00785 // The 2D Szabo-Babuska defined on a 6-noded triangle 00786 case TRI6: 00787 { 00788 switch (n) 00789 { 00790 case 0: 00791 case 1: 00792 case 2: 00793 return 1; 00794 00795 case 3: 00796 case 4: 00797 case 5: 00798 return 5; 00799 00800 default: 00801 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!"); 00802 } 00803 } 00804 00805 00806 // The 2D tensor-product Szabo-Babuska defined on a 00807 // nine-noded quadrilateral. 00808 case QUAD8: 00809 case QUAD9: 00810 { 00811 switch (n) 00812 { 00813 case 0: 00814 case 1: 00815 case 2: 00816 case 3: 00817 return 1; 00818 00819 case 4: 00820 case 5: 00821 case 6: 00822 case 7: 00823 return 5; 00824 00825 case 8: 00826 return 25; 00827 00828 default: 00829 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!"); 00830 } 00831 } 00832 00833 case INVALID_ELEM: 00834 return 0; 00835 00836 default: 00837 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00838 } 00839 } 00840 00841 00842 // The seventh-order Szabo-Babuska shape functions 00843 case SEVENTH: 00844 { 00845 switch (t) 00846 { 00847 case NODEELEM: 00848 return 1; 00849 00850 // The 1D Szabo-Babuska defined on a three-noded edge 00851 case EDGE2: 00852 case EDGE3: 00853 { 00854 switch (n) 00855 { 00856 case 0: 00857 case 1: 00858 return 1; 00859 00860 case 2: 00861 return 6; 00862 00863 default: 00864 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!"); 00865 } 00866 } 00867 00868 00869 // The 2D Szabo-Babuska defined on a 6-noded triangle 00870 case TRI6: 00871 { 00872 switch (n) 00873 { 00874 case 0: 00875 case 1: 00876 case 2: 00877 return 1; 00878 00879 case 3: 00880 case 4: 00881 case 5: 00882 return 6; 00883 00884 default: 00885 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!"); 00886 } 00887 } 00888 00889 00890 // The 2D tensor-product Szabo-Babuska defined on a 00891 // nine-noded quadrilateral. 00892 case QUAD8: 00893 case QUAD9: 00894 { 00895 switch (n) 00896 { 00897 case 0: 00898 case 1: 00899 case 2: 00900 case 3: 00901 return 1; 00902 00903 case 4: 00904 case 5: 00905 case 6: 00906 case 7: 00907 return 6; 00908 00909 case 8: 00910 return 36; 00911 00912 default: 00913 libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!"); 00914 } 00915 } 00916 00917 case INVALID_ELEM: 00918 return 0; 00919 00920 default: 00921 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00922 } 00923 } 00924 00925 00926 default: 00927 libmesh_error_msg("ERROR: Invalid Order " << Utility::enum_to_string(o) << " selected for SZABAB FE family!"); 00928 } 00929 00930 libmesh_error_msg("We'll never get here!"); 00931 return 0; 00932 } // szabab_n_dofs_at_node() 00933 00934 00935 00936 unsigned int szabab_n_dofs_per_elem(const ElemType t, const Order o) 00937 { 00938 switch (o) 00939 { 00940 // The first-order Szabo-Babuska shape functions 00941 case FIRST: 00942 { 00943 switch (t) 00944 { 00945 case NODEELEM: 00946 return 0; 00947 00948 // The 1D Szabo-Babuska defined on a two-noded edge 00949 case EDGE2: 00950 return 0; 00951 00952 // The 1D Szabo-Babuska defined on a three-noded edge 00953 case EDGE3: 00954 return 0; 00955 00956 // The 2D Szabo-Babuska defined on a 6-noded triangle 00957 case TRI6: 00958 return 0; 00959 00960 // The 2D tensor-product Szabo-Babuska defined on a 00961 // nine-noded quadrilateral. 00962 case QUAD8: 00963 return 0; 00964 00965 // The 2D tensor-product Szabo-Babuska defined on a 00966 // nine-noded quadrilateral. 00967 00968 case QUAD9: 00969 return 0; 00970 00971 case INVALID_ELEM: 00972 return 0; 00973 00974 default: 00975 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 00976 } 00977 } 00978 00979 00980 00981 // The second-order Szabo-Babuska shape functions 00982 case SECOND: 00983 { 00984 switch (t) 00985 { 00986 case NODEELEM: 00987 return 0; 00988 00989 // The 1D Szabo-Babuska defined on a two-noded edge 00990 case EDGE2: 00991 return 1; 00992 00993 // The 1D Szabo-Babuska defined on a three-noded edge 00994 case EDGE3: 00995 return 0; 00996 00997 // The 2D Szabo-Babuska defined on a 6-noded triangle 00998 case TRI6: 00999 return 0; 01000 01001 // The 2D tensor-product Szabo-Babuska defined on a 01002 // eight-noded quadrilateral. 01003 case QUAD8: 01004 return 0; 01005 01006 // The 2D tensor-product Szabo-Babuska defined on a 01007 // nine-noded quadrilateral. 01008 case QUAD9: 01009 return 0; 01010 01011 case INVALID_ELEM: 01012 return 0; 01013 01014 default: 01015 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 01016 } 01017 } 01018 01019 01020 01021 // The third-order Szabo-Babuska shape functions 01022 case THIRD: 01023 { 01024 switch (t) 01025 { 01026 case NODEELEM: 01027 return 0; 01028 01029 // The 1D Szabo-Babuska defined on a two-noded edge 01030 case EDGE2: 01031 return 2; 01032 01033 // The 1D Szabo-Babuska defined on a three-noded edge 01034 case EDGE3: 01035 return 0; 01036 01037 // The 2D Szabo-Babuska defined on a 6-noded triangle 01038 case TRI6: 01039 return 1; 01040 01041 // The 2D tensor-product Szabo-Babuska defined on a 01042 // eight-noded quadrilateral. 01043 case QUAD8: 01044 return 4; 01045 01046 // The 2D tensor-product Szabo-Babuska defined on a 01047 // nine-noded quadrilateral. 01048 case QUAD9: 01049 return 0; 01050 01051 case INVALID_ELEM: 01052 return 0; 01053 01054 default: 01055 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 01056 } 01057 } 01058 01059 01060 01061 // The fourth-order Szabo-Babuska shape functions 01062 case FOURTH: 01063 { 01064 switch (t) 01065 { 01066 case NODEELEM: 01067 return 0; 01068 01069 // The 1D Szabo-Babuska defined on a two-noded edge 01070 case EDGE2: 01071 return 3; 01072 01073 // The 1D Szabo-Babuska defined on a three-noded edge 01074 case EDGE3: 01075 return 0; 01076 01077 // The 2D Szabo-Babuska defined on a 6-noded triangle 01078 case TRI6: 01079 return 3; 01080 01081 // The 2D tensor-product Szabo-Babuska defined on a 01082 // eight-noded quadrilateral. 01083 case QUAD8: 01084 return 9; 01085 01086 // The 2D tensor-product Szabo-Babuska defined on a 01087 // nine-noded quadrilateral. 01088 case QUAD9: 01089 return 0; 01090 01091 case INVALID_ELEM: 01092 return 0; 01093 01094 default: 01095 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 01096 } 01097 } 01098 01099 01100 01101 // The fifth-order Szabo-Babuska shape functions 01102 case FIFTH: 01103 { 01104 switch (t) 01105 { 01106 case NODEELEM: 01107 return 0; 01108 01109 // The 1D Szabo-Babuska defined on a two-noded edge 01110 case EDGE2: 01111 return 4; 01112 01113 // The 1D Szabo-Babuska defined on a three-noded edge 01114 case EDGE3: 01115 return 0; 01116 01117 // The 2D Szabo-Babuska defined on a 6-noded triangle 01118 case TRI6: 01119 return 6; 01120 01121 // The 2D tensor-product Szabo-Babuska defined on a 01122 // eight-noded quadrilateral. 01123 case QUAD8: 01124 return 16; 01125 01126 // The 2D tensor-product Szabo-Babuska defined on a 01127 // nine-noded quadrilateral. 01128 case QUAD9: 01129 return 0; 01130 01131 case INVALID_ELEM: 01132 return 0; 01133 01134 default: 01135 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 01136 } 01137 } 01138 01139 01140 // The sixth-order Szabo-Babuska shape functions 01141 case SIXTH: 01142 { 01143 switch (t) 01144 { 01145 case NODEELEM: 01146 return 0; 01147 01148 // The 1D Szabo-Babuska defined on a two-noded edge 01149 case EDGE2: 01150 return 5; 01151 01152 // The 1D Szabo-Babuska defined on a three-noded edge 01153 case EDGE3: 01154 return 0; 01155 01156 // The 2D Szabo-Babuska defined on a 6-noded triangle 01157 case TRI6: 01158 return 10; 01159 01160 // The 2D tensor-product Szabo-Babuska defined on a 01161 // eight-noded quadrilateral. 01162 case QUAD8: 01163 return 25; 01164 01165 // The 2D tensor-product Szabo-Babuska defined on a 01166 // nine-noded quadrilateral. 01167 case QUAD9: 01168 return 0; 01169 01170 case INVALID_ELEM: 01171 return 0; 01172 01173 default: 01174 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 01175 } 01176 } 01177 01178 01179 // The seventh-order Szabo-Babuska shape functions 01180 case SEVENTH: 01181 { 01182 switch (t) 01183 { 01184 case NODEELEM: 01185 return 0; 01186 01187 // The 1D Szabo-Babuska defined on a two-noded edge 01188 case EDGE2: 01189 return 6; 01190 01191 // The 1D Szabo-Babuska defined on a three-noded edge 01192 case EDGE3: 01193 return 0; 01194 01195 // The 2D Szabo-Babuska defined on a 6-noded triangle 01196 case TRI6: 01197 return 15; 01198 01199 // The 2D tensor-product Szabo-Babuska defined on a 01200 // eight-noded quadrilateral. 01201 case QUAD8: 01202 return 36; 01203 01204 // The 2D tensor-product Szabo-Babuska defined on a 01205 // nine-noded quadrilateral. 01206 case QUAD9: 01207 return 0; 01208 01209 case INVALID_ELEM: 01210 return 0; 01211 01212 default: 01213 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!"); 01214 } 01215 } 01216 01217 01218 // Otherwise no DOFS per element 01219 default: 01220 return 0; 01221 } 01222 } // szabab_n_dofs_per_elem 01223 01224 } // anonymous namespace 01225 01226 01227 01228 01229 // Do full-specialization of nodal_soln() function for every 01230 // dimension, instead of explicit instantiation at the end of this 01231 // file. 01232 // This could be macro-ified so that it fits on one line... 01233 template <> 01234 void FE<0,SZABAB>::nodal_soln(const Elem* elem, 01235 const Order order, 01236 const std::vector<Number>& elem_soln, 01237 std::vector<Number>& nodal_soln) 01238 { szabab_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/0); } 01239 01240 template <> 01241 void FE<1,SZABAB>::nodal_soln(const Elem* elem, 01242 const Order order, 01243 const std::vector<Number>& elem_soln, 01244 std::vector<Number>& nodal_soln) 01245 { szabab_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/1); } 01246 01247 template <> 01248 void FE<2,SZABAB>::nodal_soln(const Elem* elem, 01249 const Order order, 01250 const std::vector<Number>& elem_soln, 01251 std::vector<Number>& nodal_soln) 01252 { szabab_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/2); } 01253 01254 template <> 01255 void FE<3,SZABAB>::nodal_soln(const Elem* elem, 01256 const Order order, 01257 const std::vector<Number>& elem_soln, 01258 std::vector<Number>& nodal_soln) 01259 { szabab_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/3); } 01260 01261 01262 // Full specialization of n_dofs() function for every dimension 01263 template <> unsigned int FE<0,SZABAB>::n_dofs(const ElemType t, const Order o) { return szabab_n_dofs(t, o); } 01264 template <> unsigned int FE<1,SZABAB>::n_dofs(const ElemType t, const Order o) { return szabab_n_dofs(t, o); } 01265 template <> unsigned int FE<2,SZABAB>::n_dofs(const ElemType t, const Order o) { return szabab_n_dofs(t, o); } 01266 template <> unsigned int FE<3,SZABAB>::n_dofs(const ElemType t, const Order o) { return szabab_n_dofs(t, o); } 01267 01268 // Full specialization of n_dofs_at_node() function for every dimension. 01269 template <> unsigned int FE<0,SZABAB>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return szabab_n_dofs_at_node(t, o, n); } 01270 template <> unsigned int FE<1,SZABAB>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return szabab_n_dofs_at_node(t, o, n); } 01271 template <> unsigned int FE<2,SZABAB>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return szabab_n_dofs_at_node(t, o, n); } 01272 template <> unsigned int FE<3,SZABAB>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return szabab_n_dofs_at_node(t, o, n); } 01273 01274 // Full specialization of n_dofs_per_elem() function for every dimension. 01275 template <> unsigned int FE<0,SZABAB>::n_dofs_per_elem(const ElemType t, const Order o) { return szabab_n_dofs_per_elem(t, o); } 01276 template <> unsigned int FE<1,SZABAB>::n_dofs_per_elem(const ElemType t, const Order o) { return szabab_n_dofs_per_elem(t, o); } 01277 template <> unsigned int FE<2,SZABAB>::n_dofs_per_elem(const ElemType t, const Order o) { return szabab_n_dofs_per_elem(t, o); } 01278 template <> unsigned int FE<3,SZABAB>::n_dofs_per_elem(const ElemType t, const Order o) { return szabab_n_dofs_per_elem(t, o); } 01279 01280 // Szabab FEMs are C^0 continuous 01281 template <> FEContinuity FE<0,SZABAB>::get_continuity() const { return C_ZERO; } 01282 template <> FEContinuity FE<1,SZABAB>::get_continuity() const { return C_ZERO; } 01283 template <> FEContinuity FE<2,SZABAB>::get_continuity() const { return C_ZERO; } 01284 template <> FEContinuity FE<3,SZABAB>::get_continuity() const { return C_ZERO; } 01285 01286 // Szabab FEMs are hierarchic 01287 template <> bool FE<0,SZABAB>::is_hierarchic() const { return true; } 01288 template <> bool FE<1,SZABAB>::is_hierarchic() const { return true; } 01289 template <> bool FE<2,SZABAB>::is_hierarchic() const { return true; } 01290 template <> bool FE<3,SZABAB>::is_hierarchic() const { return true; } 01291 01292 #ifdef LIBMESH_ENABLE_AMR 01293 // compute_constraints() specializations are only needed for 2 and 3D 01294 template <> 01295 void FE<2,SZABAB>::compute_constraints (DofConstraints &constraints, 01296 DofMap &dof_map, 01297 const unsigned int variable_number, 01298 const Elem* elem) 01299 { compute_proj_constraints(constraints, dof_map, variable_number, elem); } 01300 01301 template <> 01302 void FE<3,SZABAB>::compute_constraints (DofConstraints &constraints, 01303 DofMap &dof_map, 01304 const unsigned int variable_number, 01305 const Elem* elem) 01306 { compute_proj_constraints(constraints, dof_map, variable_number, elem); } 01307 #endif // #ifdef LIBMESH_ENABLE_AMR 01308 01309 // Szabab shapes need reinit only for approximation orders >= 3, 01310 // but we might reach that with p refinement 01311 template <> bool FE<0,SZABAB>::shapes_need_reinit() const { return true; } 01312 template <> bool FE<1,SZABAB>::shapes_need_reinit() const { return true; } 01313 template <> bool FE<2,SZABAB>::shapes_need_reinit() const { return true; } 01314 template <> bool FE<3,SZABAB>::shapes_need_reinit() const { return true; } 01315 01316 } // namespace libMesh 01317 01318 #endif //LIBMESH_ENABLE_HIGHER_ORDER_SHAPES