$extrastylesheet
fe_szabab.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 
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