libMesh
fe_szabab.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 // Local includes
21 #include "libmesh/libmesh_config.h"
22 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
23 
24 #include "libmesh/elem.h"
25 #include "libmesh/enum_to_string.h"
26 #include "libmesh/fe.h"
27 #include "libmesh/fe_interface.h"
28 #include "libmesh/fe_macro.h"
29 
30 namespace libMesh
31 {
32 
33 // ------------------------------------------------------------
34 // Szabo-Babuska-specific implementations, Steffen Petersen 2004
35 
36 // Anonymous namespace for local helper functions
37 namespace {
38 
39 void szabab_nodal_soln(const Elem * elem,
40  const Order order,
41  const std::vector<Number> & elem_soln,
42  std::vector<Number> & nodal_soln,
43  const bool add_p_level)
44 {
45  const unsigned int n_nodes = elem->n_nodes();
46 
47  const ElemType elem_type = elem->type();
48 
49  nodal_soln.resize(n_nodes);
50 
51  const Order totalorder = static_cast<Order>(order + add_p_level*elem->p_level());
52 
53  // FEType object to be passed to various FEInterface functions below.
54  FEType fe_type(order, SZABAB);
55 
56  switch (totalorder)
57  {
58  // Constant shape functions
59  case CONSTANT:
60  {
61  libmesh_assert_equal_to (elem_soln.size(), 1);
62 
63  const Number val = elem_soln[0];
64 
65  for (unsigned int n=0; n<n_nodes; n++)
66  nodal_soln[n] = val;
67 
68  return;
69  }
70 
71 
72  // For other bases do interpolation at the nodes
73  // explicitly.
74  case FIRST:
75  case SECOND:
76  case THIRD:
77  case FOURTH:
78  case FIFTH:
79  case SIXTH:
80  case SEVENTH:
81  {
82  const unsigned int n_sf =
83  FEInterface::n_shape_functions(fe_type, elem);
84 
85  std::vector<Point> refspace_nodes;
86  FEBase::get_refspace_nodes(elem_type,refspace_nodes);
87  libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);
88 
89  for (unsigned int n=0; n<n_nodes; n++)
90  {
91  libmesh_assert_equal_to (elem_soln.size(), n_sf);
92 
93  // Zero before summation
94  nodal_soln[n] = 0;
95 
96  // u_i = Sum (alpha_i phi_i)
97  for (unsigned int i=0; i<n_sf; i++)
98  nodal_soln[n] += elem_soln[i] *
99  FEInterface::shape(fe_type, elem, i, refspace_nodes[n]);
100  }
101 
102  return;
103  }
104 
105  default:
106  libmesh_error_msg("ERROR: Invalid total order " << totalorder);
107  }
108 } // szabab_nodal_soln()
109 
110 
111 
112 
113 unsigned int szabab_n_dofs(const ElemType t, const Order o)
114 {
115  switch (o)
116  {
117  // Szabo-Babuska 1st-order polynomials.
118  case FIRST:
119  {
120  switch (t)
121  {
122  case NODEELEM:
123  return 1;
124 
125  case EDGE2:
126  case EDGE3:
127  return 2;
128 
129  case TRI3:
130  case TRI6:
131  case TRI7:
132  return 3;
133 
134  case QUAD4:
135  case QUAD8:
136  case QUAD9:
137  return 4;
138 
139  case INVALID_ELEM:
140  return 0;
141 
142  default:
143  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
144  }
145  }
146 
147 
148  // Szabo-Babuska 2nd-order polynomials.
149  case SECOND:
150  {
151  switch (t)
152  {
153  case NODEELEM:
154  return 1;
155 
156  case EDGE2:
157  case EDGE3:
158  return 3;
159 
160  case TRI6:
161  case TRI7:
162  return 6;
163 
164  case QUAD8:
165  return 8;
166  case QUAD9:
167  return 9;
168 
169  case INVALID_ELEM:
170  return 0;
171 
172  default:
173  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
174  }
175  }
176 
177 
178  // Szabo-Babuska 3rd-order polynomials.
179  case THIRD:
180  {
181  switch (t)
182  {
183  case NODEELEM:
184  return 1;
185 
186  case EDGE2:
187  case EDGE3:
188  return 4;
189 
190  case TRI6:
191  case TRI7:
192  return 10;
193 
194  case QUAD8:
195  case QUAD9:
196  return 16;
197 
198  case INVALID_ELEM:
199  return 0;
200 
201  default:
202  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
203  }
204  }
205 
206 
207  // Szabo-Babuska 4th-order polynomials.
208  case FOURTH:
209  {
210  switch (t)
211  {
212  case NODEELEM:
213  return 1;
214 
215  case EDGE2:
216  case EDGE3:
217  return 5;
218 
219  case TRI6:
220  case TRI7:
221  return 15;
222 
223  case QUAD8:
224  case QUAD9:
225  return 25;
226 
227  case INVALID_ELEM:
228  return 0;
229 
230  default:
231  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
232  }
233  }
234 
235 
236  // Szabo-Babuska 5th-order polynomials.
237  case FIFTH:
238  {
239  switch (t)
240  {
241  case NODEELEM:
242  return 1;
243 
244  case EDGE2:
245  case EDGE3:
246  return 6;
247 
248  case TRI6:
249  case TRI7:
250  return 21;
251 
252  case QUAD8:
253  case QUAD9:
254  return 36;
255 
256  case INVALID_ELEM:
257  return 0;
258 
259  default:
260  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
261  }
262  }
263 
264 
265  // Szabo-Babuska 6th-order polynomials.
266  case SIXTH:
267  {
268  switch (t)
269  {
270  case NODEELEM:
271  return 1;
272 
273  case EDGE2:
274  case EDGE3:
275  return 7;
276 
277  case TRI6:
278  case TRI7:
279  return 28;
280 
281  case QUAD8:
282  case QUAD9:
283  return 49;
284 
285  case INVALID_ELEM:
286  return 0;
287 
288  default:
289  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
290  }
291  }
292 
293  // Szabo-Babuska 7th-order polynomials.
294  case SEVENTH:
295  {
296  switch (t)
297  {
298  case NODEELEM:
299  return 1;
300 
301  case EDGE2:
302  case EDGE3:
303  return 8;
304 
305  case TRI6:
306  case TRI7:
307  return 36;
308 
309  case QUAD8:
310  case QUAD9:
311  return 64;
312 
313  case INVALID_ELEM:
314  return 0;
315 
316  default:
317  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
318  }
319  }
320 
321 
322  default:
323  libmesh_error_msg("ERROR: Invalid Order " << Utility::enum_to_string(o) << " selected for SZABAB FE family!");
324  }
325 } // szabab_n_dofs()
326 
327 
328 
329 
330 
331 unsigned int szabab_n_dofs_at_node(const ElemType t,
332  const Order o,
333  const unsigned int n)
334 {
335  switch (o)
336  {
337  // The first-order Szabo-Babuska shape functions
338  case FIRST:
339  {
340  switch (t)
341  {
342  case NODEELEM:
343  return 1;
344 
345  // The 1D Szabo-Babuska defined on a three-noded edge
346  case EDGE2:
347  case EDGE3:
348  {
349  switch (n)
350  {
351  case 0:
352  case 1:
353  return 1;
354 
355  case 2:
356  return 0;
357 
358  default:
359  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!");
360  }
361  }
362 
363 
364  // The 2D Szabo-Babuska defined on a 6-noded triangle
365  case TRI3:
366  case TRI6:
367  case TRI7:
368  {
369  switch (n)
370  {
371  case 0:
372  case 1:
373  case 2:
374  return 1;
375 
376  case 3:
377  case 4:
378  case 5:
379  return 0;
380 
381  case 6:
382  libmesh_assert(t == TRI7);
383  return 0;
384 
385  default:
386  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI3/6/7!");
387  }
388  }
389 
390 
391  // The 2D tensor-product Szabo-Babuska defined on a
392  // nine-noded quadrilateral.
393  case QUAD4:
394  case QUAD8:
395  case QUAD9:
396  {
397  switch (n)
398  {
399  case 0:
400  case 1:
401  case 2:
402  case 3:
403  return 1;
404 
405  case 4:
406  case 5:
407  case 6:
408  case 7:
409  return 0;
410 
411  case 8:
412  return 0;
413 
414  default:
415  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD4/8/9!");
416  }
417  }
418 
419  case INVALID_ELEM:
420  return 0;
421 
422  default:
423  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
424  }
425  }
426 
427 
428 
429  // The second-order Szabo-Babuska shape functions
430  case SECOND:
431  {
432  switch (t)
433  {
434  case NODEELEM:
435  return 1;
436 
437  // The 1D Szabo-Babuska defined on a three-noded edge
438  case EDGE2:
439  case EDGE3:
440  {
441  switch (n)
442  {
443  case 0:
444  case 1:
445  return 1;
446 
447  case 2:
448  return 1;
449 
450  default:
451  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!");
452  }
453  }
454 
455 
456  // The 2D Szabo-Babuska defined on a 6-noded triangle
457  case TRI6:
458  case TRI7:
459  {
460  switch (n)
461  {
462  case 0:
463  case 1:
464  case 2:
465  return 1;
466 
467  case 3:
468  case 4:
469  case 5:
470  return 1;
471 
472  case 6:
473  libmesh_assert(t == TRI7);
474  return 0;
475 
476  default:
477  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6/7!");
478  }
479  }
480 
481 
482  // The 2D tensor-product Szabo-Babuska defined on a
483  // nine-noded quadrilateral.
484  case QUAD8:
485  case QUAD9:
486  {
487  switch (n)
488  {
489  case 0:
490  case 1:
491  case 2:
492  case 3:
493  return 1;
494 
495  case 4:
496  case 5:
497  case 6:
498  case 7:
499  return 1;
500 
501  case 8:
502  return 1;
503 
504  default:
505  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!");
506  }
507  }
508 
509  case INVALID_ELEM:
510  return 0;
511 
512  default:
513  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
514  }
515  }
516 
517 
518 
519  // The third-order Szabo-Babuska shape functions
520  case THIRD:
521  {
522  switch (t)
523  {
524  case NODEELEM:
525  return 1;
526 
527  // The 1D Szabo-Babuska defined on a three-noded edge
528  case EDGE2:
529  case EDGE3:
530  {
531  switch (n)
532  {
533  case 0:
534  case 1:
535  return 1;
536 
537  case 2:
538  return 2;
539 
540  default:
541  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!");
542  }
543  }
544 
545 
546  // The 2D Szabo-Babuska defined on a 6-noded triangle
547  case TRI7:
548  if (n == 6)
549  return 1;
550  libmesh_fallthrough();
551  case TRI6:
552  {
553  switch (n)
554  {
555  case 0:
556  case 1:
557  case 2:
558  return 1;
559 
560  case 3:
561  case 4:
562  case 5:
563  return 2;
564 
565  default:
566  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6/7!");
567  }
568  }
569 
570 
571  // The 2D tensor-product Szabo-Babuska defined on a
572  // nine-noded quadrilateral.
573  case QUAD8:
574  case QUAD9:
575  {
576  switch (n)
577  {
578  case 0:
579  case 1:
580  case 2:
581  case 3:
582  return 1;
583 
584  case 4:
585  case 5:
586  case 6:
587  case 7:
588  return 2;
589 
590  case 8:
591  return 4;
592 
593  default:
594  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!");
595  }
596  }
597 
598  case INVALID_ELEM:
599  return 0;
600 
601  default:
602  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
603  }
604  }
605 
606 
607 
608  // The fourth-order Szabo-Babuska shape functions
609  case FOURTH:
610  {
611  switch (t)
612  {
613  case NODEELEM:
614  return 1;
615 
616  // The 1D Szabo-Babuska defined on a three-noded edge
617  case EDGE2:
618  case EDGE3:
619  {
620  switch (n)
621  {
622  case 0:
623  case 1:
624  return 1;
625 
626  case 2:
627  return 3;
628 
629  default:
630  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!");
631  }
632  }
633 
634 
635  // The 2D Szabo-Babuska defined on a 6/7-noded triangle
636  case TRI7:
637  if (n == 6)
638  return 3;
639  libmesh_fallthrough();
640  case TRI6:
641  {
642  switch (n)
643  {
644  case 0:
645  case 1:
646  case 2:
647  return 1;
648 
649  case 3:
650  case 4:
651  case 5:
652  return 3;
653 
654  default:
655  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!");
656  }
657  }
658 
659 
660  // The 2D tensor-product Szabo-Babuska defined on a
661  // nine-noded quadrilateral.
662  case QUAD8:
663  case QUAD9:
664  {
665  switch (n)
666  {
667  case 0:
668  case 1:
669  case 2:
670  case 3:
671  return 1;
672 
673  case 4:
674  case 5:
675  case 6:
676  case 7:
677  return 3;
678 
679  case 8:
680  return 9;
681 
682  default:
683  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!");
684  }
685  }
686 
687  case INVALID_ELEM:
688  return 0;
689 
690  default:
691  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
692  }
693  }
694 
695 
696 
697  // The fifth-order Szabo-Babuska shape functions
698  case FIFTH:
699  {
700  switch (t)
701  {
702  case NODEELEM:
703  return 1;
704 
705  // The 1D Szabo-Babuska defined on a three-noded edge
706  case EDGE2:
707  case EDGE3:
708  {
709  switch (n)
710  {
711  case 0:
712  case 1:
713  return 1;
714 
715  case 2:
716  return 4;
717 
718  default:
719  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!");
720  }
721  }
722 
723 
724  // The 2D Szabo-Babuska defined on a 6/7-noded triangle
725  case TRI7:
726  if (n == 6)
727  return 6;
728  libmesh_fallthrough();
729  case TRI6:
730  {
731  switch (n)
732  {
733  case 0:
734  case 1:
735  case 2:
736  return 1;
737 
738  case 3:
739  case 4:
740  case 5:
741  return 4;
742 
743  default:
744  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!");
745  }
746  }
747 
748 
749  // The 2D tensor-product Szabo-Babuska defined on a
750  // nine-noded quadrilateral.
751  case QUAD8:
752  case QUAD9:
753  {
754  switch (n)
755  {
756  case 0:
757  case 1:
758  case 2:
759  case 3:
760  return 1;
761 
762  case 4:
763  case 5:
764  case 6:
765  case 7:
766  return 4;
767 
768  case 8:
769  return 16;
770 
771  default:
772  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!");
773  }
774  }
775 
776  case INVALID_ELEM:
777  return 0;
778 
779  default:
780  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
781  }
782  }
783 
784 
785 
786  // The sixth-order Szabo-Babuska shape functions
787  case SIXTH:
788  {
789  switch (t)
790  {
791  case NODEELEM:
792  return 1;
793 
794  // The 1D Szabo-Babuska defined on a three-noded edge
795  case EDGE2:
796  case EDGE3:
797  {
798  switch (n)
799  {
800  case 0:
801  case 1:
802  return 1;
803 
804  case 2:
805  return 5;
806 
807  default:
808  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!");
809  }
810  }
811 
812 
813  // The 2D Szabo-Babuska defined on a 6/7-noded triangle
814  case TRI7:
815  if (n == 6)
816  return 10;
817  libmesh_fallthrough();
818  case TRI6:
819  {
820  switch (n)
821  {
822  case 0:
823  case 1:
824  case 2:
825  return 1;
826 
827  case 3:
828  case 4:
829  case 5:
830  return 5;
831 
832  default:
833  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!");
834  }
835  }
836 
837 
838  // The 2D tensor-product Szabo-Babuska defined on a
839  // nine-noded quadrilateral.
840  case QUAD8:
841  case QUAD9:
842  {
843  switch (n)
844  {
845  case 0:
846  case 1:
847  case 2:
848  case 3:
849  return 1;
850 
851  case 4:
852  case 5:
853  case 6:
854  case 7:
855  return 5;
856 
857  case 8:
858  return 25;
859 
860  default:
861  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!");
862  }
863  }
864 
865  case INVALID_ELEM:
866  return 0;
867 
868  default:
869  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
870  }
871  }
872 
873 
874  // The seventh-order Szabo-Babuska shape functions
875  case SEVENTH:
876  {
877  switch (t)
878  {
879  case NODEELEM:
880  return 1;
881 
882  // The 1D Szabo-Babuska defined on a three-noded edge
883  case EDGE2:
884  case EDGE3:
885  {
886  switch (n)
887  {
888  case 0:
889  case 1:
890  return 1;
891 
892  case 2:
893  return 6;
894 
895  default:
896  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for EDGE2/3!");
897  }
898  }
899 
900 
901  // The 2D Szabo-Babuska defined on a 6/7-noded triangle
902  case TRI7:
903  if (n == 6)
904  return 15;
905  libmesh_fallthrough();
906  case TRI6:
907  {
908  switch (n)
909  {
910  case 0:
911  case 1:
912  case 2:
913  return 1;
914 
915  case 3:
916  case 4:
917  case 5:
918  return 6;
919 
920  default:
921  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for TRI6!");
922  }
923  }
924 
925 
926  // The 2D tensor-product Szabo-Babuska defined on a
927  // nine-noded quadrilateral.
928  case QUAD8:
929  case QUAD9:
930  {
931  switch (n)
932  {
933  case 0:
934  case 1:
935  case 2:
936  case 3:
937  return 1;
938 
939  case 4:
940  case 5:
941  case 6:
942  case 7:
943  return 6;
944 
945  case 8:
946  return 36;
947 
948  default:
949  libmesh_error_msg("ERROR: Invalid node ID " << n << " selected for QUAD8/9!");
950  }
951  }
952 
953  case INVALID_ELEM:
954  return 0;
955 
956  default:
957  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
958  }
959  }
960 
961 
962  default:
963  libmesh_error_msg("ERROR: Invalid Order " << Utility::enum_to_string(o) << " selected for SZABAB FE family!");
964  }
965 } // szabab_n_dofs_at_node()
966 
967 
968 
969 unsigned int szabab_n_dofs_per_elem(const ElemType t, const Order o)
970 {
971  switch (o)
972  {
973  // The first-order Szabo-Babuska shape functions
974  case FIRST:
975  {
976  switch (t)
977  {
978  case NODEELEM:
979  return 0;
980 
981  // The 1D Szabo-Babuska defined on an edge
982  case EDGE2:
983  case EDGE3:
984  return 0;
985 
986  // The 2D Szabo-Babuska defined on a triangle
987  case TRI3:
988  case TRI6:
989  case TRI7:
990  return 0;
991 
992  // The 2D tensor-product Szabo-Babuska defined on a
993  // quadrilateral.
994  case QUAD4:
995  case QUAD8:
996  case QUAD9:
997  return 0;
998 
999  case INVALID_ELEM:
1000  return 0;
1001 
1002  default:
1003  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
1004  }
1005  }
1006 
1007 
1008 
1009  // The second-order Szabo-Babuska shape functions
1010  case SECOND:
1011  {
1012  switch (t)
1013  {
1014  case NODEELEM:
1015  return 0;
1016 
1017  // The 1D Szabo-Babuska defined on a two-noded edge
1018  case EDGE2:
1019  return 1;
1020 
1021  // The 1D Szabo-Babuska defined on a three-noded edge
1022  case EDGE3:
1023  return 0;
1024 
1025  // The 2D Szabo-Babuska defined on a 6-noded triangle
1026  case TRI6:
1027  case TRI7:
1028  return 0;
1029 
1030  // The 2D tensor-product Szabo-Babuska defined on a
1031  // eight-noded quadrilateral.
1032  case QUAD8:
1033  return 0;
1034 
1035  // The 2D tensor-product Szabo-Babuska defined on a
1036  // nine-noded quadrilateral.
1037  case QUAD9:
1038  return 0;
1039 
1040  case INVALID_ELEM:
1041  return 0;
1042 
1043  default:
1044  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
1045  }
1046  }
1047 
1048 
1049 
1050  // The third-order Szabo-Babuska shape functions
1051  case THIRD:
1052  {
1053  switch (t)
1054  {
1055  case NODEELEM:
1056  return 0;
1057 
1058  // The 1D Szabo-Babuska defined on a two-noded edge
1059  case EDGE2:
1060  return 2;
1061 
1062  // The 1D Szabo-Babuska defined on a three-noded edge
1063  case EDGE3:
1064  return 0;
1065 
1066  // The 2D Szabo-Babuska defined on a 6-noded triangle
1067  case TRI6:
1068  return 1;
1069 
1070  case TRI7:
1071  return 0;
1072 
1073  // The 2D tensor-product Szabo-Babuska defined on a
1074  // eight-noded quadrilateral.
1075  case QUAD8:
1076  return 4;
1077 
1078  // The 2D tensor-product Szabo-Babuska defined on a
1079  // nine-noded quadrilateral.
1080  case QUAD9:
1081  return 0;
1082 
1083  case INVALID_ELEM:
1084  return 0;
1085 
1086  default:
1087  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
1088  }
1089  }
1090 
1091 
1092 
1093  // The fourth-order Szabo-Babuska shape functions
1094  case FOURTH:
1095  {
1096  switch (t)
1097  {
1098  case NODEELEM:
1099  return 0;
1100 
1101  // The 1D Szabo-Babuska defined on a two-noded edge
1102  case EDGE2:
1103  return 3;
1104 
1105  // The 1D Szabo-Babuska defined on a three-noded edge
1106  case EDGE3:
1107  return 0;
1108 
1109  // The 2D Szabo-Babuska defined on a 6-noded triangle
1110  case TRI6:
1111  return 3;
1112 
1113  case TRI7:
1114  return 0;
1115 
1116  // The 2D tensor-product Szabo-Babuska defined on a
1117  // eight-noded quadrilateral.
1118  case QUAD8:
1119  return 9;
1120 
1121  // The 2D tensor-product Szabo-Babuska defined on a
1122  // nine-noded quadrilateral.
1123  case QUAD9:
1124  return 0;
1125 
1126  case INVALID_ELEM:
1127  return 0;
1128 
1129  default:
1130  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
1131  }
1132  }
1133 
1134 
1135 
1136  // The fifth-order Szabo-Babuska shape functions
1137  case FIFTH:
1138  {
1139  switch (t)
1140  {
1141  case NODEELEM:
1142  return 0;
1143 
1144  // The 1D Szabo-Babuska defined on a two-noded edge
1145  case EDGE2:
1146  return 4;
1147 
1148  // The 1D Szabo-Babuska defined on a three-noded edge
1149  case EDGE3:
1150  return 0;
1151 
1152  // The 2D Szabo-Babuska defined on a 6-noded triangle
1153  case TRI6:
1154  return 6;
1155 
1156  case TRI7:
1157  return 0;
1158 
1159  // The 2D tensor-product Szabo-Babuska defined on a
1160  // eight-noded quadrilateral.
1161  case QUAD8:
1162  return 16;
1163 
1164  // The 2D tensor-product Szabo-Babuska defined on a
1165  // nine-noded quadrilateral.
1166  case QUAD9:
1167  return 0;
1168 
1169  case INVALID_ELEM:
1170  return 0;
1171 
1172  default:
1173  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
1174  }
1175  }
1176 
1177 
1178  // The sixth-order Szabo-Babuska shape functions
1179  case SIXTH:
1180  {
1181  switch (t)
1182  {
1183  case NODEELEM:
1184  return 0;
1185 
1186  // The 1D Szabo-Babuska defined on a two-noded edge
1187  case EDGE2:
1188  return 5;
1189 
1190  // The 1D Szabo-Babuska defined on a three-noded edge
1191  case EDGE3:
1192  return 0;
1193 
1194  // The 2D Szabo-Babuska defined on a 6-noded triangle
1195  case TRI6:
1196  return 10;
1197 
1198  case TRI7:
1199  return 0;
1200 
1201  // The 2D tensor-product Szabo-Babuska defined on a
1202  // eight-noded quadrilateral.
1203  case QUAD8:
1204  return 25;
1205 
1206  // The 2D tensor-product Szabo-Babuska defined on a
1207  // nine-noded quadrilateral.
1208  case QUAD9:
1209  return 0;
1210 
1211  case INVALID_ELEM:
1212  return 0;
1213 
1214  default:
1215  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
1216  }
1217  }
1218 
1219 
1220  // The seventh-order Szabo-Babuska shape functions
1221  case SEVENTH:
1222  {
1223  switch (t)
1224  {
1225  case NODEELEM:
1226  return 0;
1227 
1228  // The 1D Szabo-Babuska defined on a two-noded edge
1229  case EDGE2:
1230  return 6;
1231 
1232  // The 1D Szabo-Babuska defined on a three-noded edge
1233  case EDGE3:
1234  return 0;
1235 
1236  // The 2D Szabo-Babuska defined on a 6-noded triangle
1237  case TRI6:
1238  return 15;
1239 
1240  case TRI7:
1241  return 0;
1242 
1243  // The 2D tensor-product Szabo-Babuska defined on a
1244  // eight-noded quadrilateral.
1245  case QUAD8:
1246  return 36;
1247 
1248  // The 2D tensor-product Szabo-Babuska defined on a
1249  // nine-noded quadrilateral.
1250  case QUAD9:
1251  return 0;
1252 
1253  case INVALID_ELEM:
1254  return 0;
1255 
1256  default:
1257  libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for SZABAB FE family!");
1258  }
1259  }
1260 
1261 
1262  // Otherwise no DOFS per element
1263  default:
1264  return 0;
1265  }
1266 } // szabab_n_dofs_per_elem
1267 
1268 } // anonymous namespace
1269 
1270 
1271 // Instantiate (side_) nodal_soln() function for every dimension
1272 LIBMESH_FE_NODAL_SOLN(SZABAB, szabab_nodal_soln)
1274 
1275 
1276 // Full specialization of n_dofs() function for every dimension
1277 template <> unsigned int FE<0,SZABAB>::n_dofs(const ElemType t, const Order o) { return szabab_n_dofs(t, o); }
1278 template <> unsigned int FE<1,SZABAB>::n_dofs(const ElemType t, const Order o) { return szabab_n_dofs(t, o); }
1279 template <> unsigned int FE<2,SZABAB>::n_dofs(const ElemType t, const Order o) { return szabab_n_dofs(t, o); }
1280 template <> unsigned int FE<3,SZABAB>::n_dofs(const ElemType t, const Order o) { return szabab_n_dofs(t, o); }
1281 
1282 // Full specialization of n_dofs_at_node() function for every dimension.
1283 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); }
1284 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); }
1285 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); }
1286 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); }
1287 
1288 // Full specialization of n_dofs_per_elem() function for every dimension.
1289 template <> unsigned int FE<0,SZABAB>::n_dofs_per_elem(const ElemType t, const Order o) { return szabab_n_dofs_per_elem(t, o); }
1290 template <> unsigned int FE<1,SZABAB>::n_dofs_per_elem(const ElemType t, const Order o) { return szabab_n_dofs_per_elem(t, o); }
1291 template <> unsigned int FE<2,SZABAB>::n_dofs_per_elem(const ElemType t, const Order o) { return szabab_n_dofs_per_elem(t, o); }
1292 template <> unsigned int FE<3,SZABAB>::n_dofs_per_elem(const ElemType t, const Order o) { return szabab_n_dofs_per_elem(t, o); }
1293 
1294 // Szabab FEMs are C^0 continuous
1295 template <> FEContinuity FE<0,SZABAB>::get_continuity() const { return C_ZERO; }
1296 template <> FEContinuity FE<1,SZABAB>::get_continuity() const { return C_ZERO; }
1297 template <> FEContinuity FE<2,SZABAB>::get_continuity() const { return C_ZERO; }
1298 template <> FEContinuity FE<3,SZABAB>::get_continuity() const { return C_ZERO; }
1299 
1300 // Szabab FEMs are hierarchic
1301 template <> bool FE<0,SZABAB>::is_hierarchic() const { return true; }
1302 template <> bool FE<1,SZABAB>::is_hierarchic() const { return true; }
1303 template <> bool FE<2,SZABAB>::is_hierarchic() const { return true; }
1304 template <> bool FE<3,SZABAB>::is_hierarchic() const { return true; }
1305 
1306 #ifdef LIBMESH_ENABLE_AMR
1307 // compute_constraints() specializations are only needed for 2 and 3D
1308 template <>
1310  DofMap & dof_map,
1311  const unsigned int variable_number,
1312  const Elem * elem)
1313 { compute_proj_constraints(constraints, dof_map, variable_number, elem); }
1314 
1315 template <>
1317  DofMap & dof_map,
1318  const unsigned int variable_number,
1319  const Elem * elem)
1320 { compute_proj_constraints(constraints, dof_map, variable_number, elem); }
1321 #endif // #ifdef LIBMESH_ENABLE_AMR
1322 
1323 // Szabab shapes need reinit only for approximation orders >= 3,
1324 // but we might reach that with p refinement
1325 template <> bool FE<0,SZABAB>::shapes_need_reinit() const { return true; }
1326 template <> bool FE<1,SZABAB>::shapes_need_reinit() const { return true; }
1327 template <> bool FE<2,SZABAB>::shapes_need_reinit() const { return true; }
1328 template <> bool FE<3,SZABAB>::shapes_need_reinit() const { return true; }
1329 
1330 } // namespace libMesh
1331 
1332 #endif //LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
static unsigned int n_dofs(const ElemType t, const Order o)
ElemType
Defines an enum for geometric element types.
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
static unsigned int n_dofs_at_node(const ElemType t, const Order o, const unsigned int n)
virtual bool shapes_need_reinit() const override
The libMesh namespace provides an interface to certain functionality in the library.
virtual bool is_hierarchic() const override
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:169
LIBMESH_FE_NODAL_SOLN(BERNSTEIN, bernstein_nodal_soln)
Definition: fe_bernstein.C:397
LIBMESH_FE_SIDE_NODAL_SOLN(HIERARCHIC_VEC)
const dof_id_type n_nodes
Definition: tecplot_io.C:67
static unsigned int n_shape_functions(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:515
static Real shape(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const Point &p)
static void get_refspace_nodes(const ElemType t, std::vector< Point > &nodes)
Definition: fe_abstract.C:373
libmesh_assert(ctx)
static unsigned int n_dofs_per_elem(const ElemType t, const Order o)
virtual FEContinuity get_continuity() const override
std::string enum_to_string(const T e)
static void compute_constraints(DofConstraints &constraints, DofMap &dof_map, const unsigned int variable_number, const Elem *elem)
Computes the constraint matrix contributions (for non-conforming adapted meshes) corresponding to var...
FEContinuity
defines an enum for finite element types to libmesh_assert a certain level (or type? Hcurl?) of continuity.
The constraint matrix storage format.
Definition: dof_map.h:98