libMesh
fe_interface_inf_fe.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2026 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 
23 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
24 
25 #include "libmesh/fe_interface.h"
26 #include "libmesh/fe_interface_macros.h"
27 #include "libmesh/inf_fe.h"
28 #include "libmesh/elem.h"
29 #include "libmesh/enum_to_string.h"
30 
31 namespace libMesh
32 {
33 
34 //------------------------------------------------------------
35 //FEInterface class members handling calls to InfFE
36 
37 
38 
39 unsigned int FEInterface::ifem_n_shape_functions(const FEType & fe_t,
40  const Elem * elem)
41 {
42  switch (elem->dim())
43  {
44  // 1D
45  case 1:
46  /*
47  * Since InfFE<Dim,T_radial,T_map>::n_shape_functions(...)
48  * is actually independent of T_radial and T_map, we can use
49  * just any T_radial and T_map
50  */
52 
53  // 2D
54  case 2:
56 
57  // 3D
58  case 3:
60 
61  default:
62  libmesh_error_msg("Unsupported dim = " << elem->dim());
63  }
64 }
65 
66 
67 
68 unsigned int
70  const Elem * elem)
71 {
72  switch (elem->dim())
73  {
74  // 1D
75  case 1:
76  /*
77  * Since InfFE<Dim,T_radial,T_map>::n_dofs(...)
78  * is actually independent of T_radial and T_map, we can use
79  * just any T_radial and T_map
80  */
81  return InfFE<1,JACOBI_20_00,CARTESIAN>::n_dofs(fe_t, elem);
82 
83  // 2D
84  case 2:
85  return InfFE<2,JACOBI_20_00,CARTESIAN>::n_dofs(fe_t, elem);
86 
87  // 3D
88  case 3:
89  return InfFE<3,JACOBI_20_00,CARTESIAN>::n_dofs(fe_t, elem);
90 
91  default:
92  libmesh_error_msg("Unsupported dim = " << elem->dim());
93  }
94 }
95 
96 
97 
98 #ifdef LIBMESH_ENABLE_DEPRECATED
99 unsigned int FEInterface::ifem_n_dofs_at_node(const unsigned int dim,
100  const FEType & fe_t,
101  const ElemType t,
102  const unsigned int n)
103 {
104  libmesh_deprecated();
105 
106  switch (dim)
107  {
108  // 1D
109  case 1:
110  /*
111  * Since InfFE<Dim,T_radial,T_map>::n_dofs_at_node(...)
112  * is actually independent of T_radial and T_map, we can use
113  * just any T_radial and T_map
114  */
116 
117  // 2D
118  case 2:
120 
121  // 3D
122  case 3:
124 
125  default:
126  libmesh_error_msg("Unsupported dim = " << dim);
127  }
128 }
129 #endif // LIBMESH_ENABLE_DEPRECATED
130 
131 
132 
133 unsigned int FEInterface::ifem_n_dofs_at_node(const FEType & fe_t,
134  const Elem * elem,
135  const unsigned int n)
136 {
137  switch (elem->dim())
138  {
139  // 1D
140  case 1:
141  /*
142  * Since InfFE<Dim,T_radial,T_map>::n_dofs_at_node(...)
143  * is actually independent of T_radial and T_map, we can use
144  * just any T_radial and T_map
145  */
147 
148  // 2D
149  case 2:
151 
152  // 3D
153  case 3:
155 
156  default:
157  libmesh_error_msg("Unsupported dim = " << elem->dim());
158  }
159 }
160 
161 
162 
163 
164 
165 #ifdef LIBMESH_ENABLE_DEPRECATED
166 unsigned int FEInterface::ifem_n_dofs_per_elem(const unsigned int dim,
167  const FEType & fe_t,
168  const ElemType t)
169 {
170  libmesh_deprecated();
171 
172  switch (dim)
173  {
174  // 1D
175  case 1:
176  /*
177  * Since InfFE<Dim,T_radial,T_map>::n_dofs(...)
178  * is actually independent of T_radial and T_map, we can use
179  * just any T_radial and T_map
180  */
182 
183  // 2D
184  case 2:
186 
187  // 3D
188  case 3:
190 
191  default:
192  libmesh_error_msg("Unsupported dim = " << dim);
193  }
194 }
195 #endif // LIBMESH_ENABLE_DEPRECATED
196 
197 
198 
199 unsigned int FEInterface::ifem_n_dofs_per_elem(const FEType & fe_t,
200  const Elem * elem)
201 {
202  switch (elem->dim())
203  {
204  // 1D
205  case 1:
206  /*
207  * Since InfFE<Dim,T_radial,T_map>::n_dofs(...)
208  * is actually independent of T_radial and T_map, we can use
209  * just any T_radial and T_map
210  */
212 
213  // 2D
214  case 2:
216 
217  // 3D
218  case 3:
220 
221  default:
222  libmesh_error_msg("Unsupported dim = " << elem->dim());
223  }
224 }
225 
226 
227 
228 
229 void FEInterface::ifem_nodal_soln(const unsigned int dim,
230  const FEType & fe_t,
231  const Elem * elem,
232  const std::vector<Number> & elem_soln,
233  std::vector<Number> & nodal_soln)
234 {
235  switch (dim)
236  {
237 
238  // 1D
239  case 1:
240  {
241  switch (fe_t.radial_family)
242  {
243  case INFINITE_MAP:
244  libmesh_error_msg("ERROR: INFINITE_MAP is not a valid shape family for radial approximation.");
245 
246  case JACOBI_20_00:
247  {
248  switch (fe_t.inf_map)
249  {
250  case CARTESIAN:
251  {
253  break;
254  }
255  default:
256  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
257  }
258  break;
259  }
260 
261  case JACOBI_30_00:
262  {
263  switch (fe_t.inf_map)
264  {
265  case CARTESIAN:
266  {
268  break;
269  }
270  default:
271  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
272  }
273  break;
274  }
275 
276  case LEGENDRE:
277  {
278  switch (fe_t.inf_map)
279  {
280  case CARTESIAN:
281  {
282  InfFE<1,LEGENDRE,CARTESIAN>::nodal_soln(fe_t, elem, elem_soln, nodal_soln);
283  break;
284  }
285  default:
286  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
287  }
288  break;
289  }
290 
291  case LAGRANGE:
292  {
293  switch (fe_t.inf_map)
294  {
295  case CARTESIAN:
296  {
297  InfFE<1,LAGRANGE,CARTESIAN>::nodal_soln(fe_t, elem, elem_soln, nodal_soln);
298  break;
299  }
300  default:
301  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
302  }
303  break;
304  }
305 
306  default:
307  libmesh_error_msg("ERROR: Bad FEType.radial_family == " << Utility::enum_to_string(fe_t.radial_family));
308  }
309 
310  break;
311  }
312 
313 
314 
315 
316  // 2D
317  case 2:
318  {
319  switch (fe_t.radial_family)
320  {
321  case INFINITE_MAP:
322  libmesh_error_msg("ERROR: INFINITE_MAP is not a valid shape family for radial approximation.");
323 
324  case JACOBI_20_00:
325  {
326  switch (fe_t.inf_map)
327  {
328  case CARTESIAN:
329  {
331  break;
332  }
333  default:
334  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
335  }
336  break;
337  }
338 
339  case JACOBI_30_00:
340  {
341  switch (fe_t.inf_map)
342  {
343  case CARTESIAN:
344  {
346  break;
347  }
348  default:
349  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
350  }
351  break;
352  }
353 
354  case LEGENDRE:
355  {
356  switch (fe_t.inf_map)
357  {
358  case CARTESIAN:
359  {
360  InfFE<2,LEGENDRE,CARTESIAN>::nodal_soln(fe_t, elem, elem_soln, nodal_soln);
361  break;
362  }
363  default:
364  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
365  }
366  break;
367  }
368 
369  case LAGRANGE:
370  {
371  switch (fe_t.inf_map)
372  {
373  case CARTESIAN:
374  {
375  InfFE<2,LAGRANGE,CARTESIAN>::nodal_soln(fe_t, elem, elem_soln, nodal_soln);
376  break;
377  }
378  default:
379  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
380  }
381  break;
382  }
383 
384  default:
385  libmesh_error_msg("ERROR: Bad FEType.radial_family == " << Utility::enum_to_string(fe_t.radial_family));
386  }
387 
388  break;
389  }
390 
391 
392 
393 
394  // 3D
395  case 3:
396  {
397  switch (fe_t.radial_family)
398  {
399  case INFINITE_MAP:
400  libmesh_error_msg("ERROR: INFINITE_MAP is not a valid shape family for radial approximation.");
401 
402  case JACOBI_20_00:
403  {
404  switch (fe_t.inf_map)
405  {
406  case CARTESIAN:
407  {
409  break;
410  }
411  default:
412  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
413  }
414  break;
415  }
416 
417  case JACOBI_30_00:
418  {
419  switch (fe_t.inf_map)
420  {
421  case CARTESIAN:
422  {
424  break;
425  }
426  default:
427  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
428  }
429  break;
430  }
431 
432  case LEGENDRE:
433  {
434  switch (fe_t.inf_map)
435  {
436  case CARTESIAN:
437  {
438  InfFE<3,LEGENDRE,CARTESIAN>::nodal_soln(fe_t, elem, elem_soln, nodal_soln);
439  break;
440  }
441  default:
442  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
443  }
444  break;
445  }
446 
447  case LAGRANGE:
448  {
449  switch (fe_t.inf_map)
450  {
451  case CARTESIAN:
452  {
453  InfFE<3,LAGRANGE,CARTESIAN>::nodal_soln(fe_t, elem, elem_soln, nodal_soln);
454  break;
455  }
456  default:
457  libmesh_error_msg("ERROR: Spherical & Ellipsoidal IFEMs not implemented.");
458  }
459  break;
460  }
461 
462 
463 
464  default:
465  libmesh_error_msg("ERROR: Bad FEType.radial_family == " << Utility::enum_to_string(fe_t.radial_family));
466  }
467 
468  break;
469  }
470 
471  default:
472  libmesh_error_msg("Invalid dim = " << dim);
473  }
474 }
475 
476 
477 
478 
479 Point FEInterface::ifem_map (const unsigned int dim,
480  const FEType & fe_t,
481  const Elem * elem,
482  const Point & p)
483 {
484  switch (fe_t.inf_map)
485  {
486  case CARTESIAN:
487  {
488  switch (dim)
489  {
490  case 1:
491  return InfFE<1,JACOBI_20_00,CARTESIAN>::map(elem, p);
492  case 2:
493  return InfFE<2,JACOBI_20_00,CARTESIAN>::map(elem, p);
494  case 3:
495  return InfFE<3,JACOBI_20_00,CARTESIAN>::map(elem, p);
496  default:
497  libmesh_error_msg("Invalid dim = " << dim);
498  }
499  }
500  case SPHERICAL:
501  case ELLIPSOIDAL:
502  libmesh_not_implemented_msg("ERROR: Spherical and Ellipsoidal IFEMs not (yet) implemented.");
503  default:
504  libmesh_error_msg("Invalid map = " << Utility::enum_to_string(fe_t.inf_map));
505  }
506 }
507 
508 
509 
511  const FEType & fe_t,
512  const Elem * elem,
513  const Point & p,
514  const Real tolerance,
515  const bool secure)
516 {
517  switch (dim)
518  {
519  // 1D
520  case 1:
521  {
522  switch (fe_t.inf_map)
523  {
524  case CARTESIAN:
525  return InfFE<1,JACOBI_20_00,CARTESIAN>::inverse_map(elem, p, tolerance, secure);
526 
527  case SPHERICAL:
528  case ELLIPSOIDAL:
529  libmesh_not_implemented_msg("ERROR: Spherical and Ellipsoidal IFEMs not (yet) implemented.");
530 
531  /*
532  case SPHERICAL:
533  return InfFE<1,JACOBI_20_00,SPHERICAL>::inverse_map(elem, p, tolerance);
534 
535  case ELLIPSOIDAL:
536  return InfFE<1,JACOBI_20_00,ELLIPSOIDAL>::inverse_map(elem, p, tolerance);
537  */
538 
539  default:
540  libmesh_error_msg("Invalid map = " << Utility::enum_to_string(fe_t.inf_map));
541  }
542  }
543 
544 
545  // 2D
546  case 2:
547  {
548  switch (fe_t.inf_map)
549  {
550  case CARTESIAN:
551  return InfFE<2,JACOBI_20_00,CARTESIAN>::inverse_map(elem, p, tolerance, secure);
552 
553  case SPHERICAL:
554  case ELLIPSOIDAL:
555  libmesh_not_implemented_msg("ERROR: Spherical and Ellipsoidal IFEMs not (yet) implemented.");
556 
557  /*
558  case SPHERICAL:
559  return InfFE<2,JACOBI_20_00,SPHERICAL>::inverse_map(elem, p, tolerance);
560 
561  case ELLIPSOIDAL:
562  return InfFE<2,JACOBI_20_00,ELLIPSOIDAL>::inverse_map(elem, p, tolerance);
563  */
564 
565  default:
566  libmesh_error_msg("Invalid map = " << Utility::enum_to_string(fe_t.inf_map));
567  }
568  }
569 
570 
571  // 3D
572  case 3:
573  {
574  switch (fe_t.inf_map)
575  {
576  case CARTESIAN:
577  return InfFE<3,JACOBI_20_00,CARTESIAN>::inverse_map(elem, p, tolerance, secure);
578 
579  case SPHERICAL:
580  case ELLIPSOIDAL:
581  libmesh_not_implemented_msg("ERROR: Spherical and Ellipsoidal IFEMs not (yet) implemented.");
582 
583  /*
584  case SPHERICAL:
585  return InfFE<3,JACOBI_20_00,SPHERICAL>::inverse_map(elem, p, tolerance);
586 
587  case ELLIPSOIDAL:
588  return InfFE<3,JACOBI_20_00,ELLIPSOIDAL>::inverse_map(elem, p, tolerance);
589  */
590 
591  default:
592  libmesh_error_msg("Invalid map = " << Utility::enum_to_string(fe_t.inf_map));
593  }
594  }
595 
596  default:
597  libmesh_error_msg("Invalid dim = " << dim);
598  }
599 }
600 
601 
602 
603 void FEInterface::ifem_inverse_map (const unsigned int dim,
604  const FEType & fe_t,
605  const Elem * elem,
606  const std::vector<Point> & physical_points,
607  std::vector<Point> & reference_points,
608  const Real tolerance,
609  const bool secure)
610 {
611  switch (dim)
612  {
613  // 1D
614  case 1:
615  {
616  switch (fe_t.inf_map)
617  {
618  case CARTESIAN:
619  InfFE<1,JACOBI_20_00,CARTESIAN>::inverse_map(elem, physical_points, reference_points, tolerance, secure);
620  return;
621 
622  default:
623  libmesh_error_msg("Invalid map = " << Utility::enum_to_string(fe_t.inf_map));
624  }
625  }
626 
627 
628  // 2D
629  case 2:
630  {
631  switch (fe_t.inf_map)
632  {
633  case CARTESIAN:
634  InfFE<2,JACOBI_20_00,CARTESIAN>::inverse_map(elem, physical_points, reference_points, tolerance, secure);
635  return;
636 
637  default:
638  libmesh_error_msg("Invalid map = " << Utility::enum_to_string(fe_t.inf_map));
639  }
640  }
641 
642 
643  // 3D
644  case 3:
645  {
646  switch (fe_t.inf_map)
647  {
648  case CARTESIAN:
649  InfFE<3,JACOBI_20_00,CARTESIAN>::inverse_map(elem, physical_points, reference_points, tolerance, secure);
650  return;
651 
652  default:
653  libmesh_error_msg("Invalid map = " << Utility::enum_to_string(fe_t.inf_map));
654  }
655  }
656 
657  default:
658  libmesh_error_msg("Invalid dim = " << dim);
659  }
660 }
661 
662 
663 
664 #ifdef LIBMESH_ENABLE_DEPRECATED
666  const ElemType t,
667  const Real eps)
668 {
669  return FEBase::on_reference_element(p,t,eps);
670 }
671 
672 
673 
674 Real FEInterface::ifem_shape(const unsigned int dim,
675  const FEType & fe_t,
676  const ElemType t,
677  const unsigned int i,
678  const Point & p)
679 {
680  libmesh_deprecated();
681 
682  inf_fe_switch(shape(fe_t, t, i, p));
683 }
684 
685 
686 
687 Real FEInterface::ifem_shape(const unsigned int dim,
688  const FEType & fe_t,
689  const Elem * elem,
690  const unsigned int i,
691  const Point & p)
692 {
693  libmesh_deprecated();
694 
695  inf_fe_switch( shape(fe_t, elem, i, p));
696 }
697 #endif // LIBMESH_ENABLE_DEPRECATED
698 
699 
700 
702  const Elem * elem,
703  const unsigned int i,
704  const Point & p)
705 {
706  // The inf_fe_switch macro requires a "dim" parameter.
707  auto dim = elem->dim();
708 
709  inf_fe_switch( shape(fe_t, elem, i, p));
710 }
711 
712 
713 
714 #ifdef LIBMESH_ENABLE_DEPRECATED
716  const FEType & fe_t,
717  const Elem * elem,
718  const unsigned int i,
719  const unsigned int j,
720  const Point & p)
721 {
722  libmesh_deprecated();
723 
724  inf_fe_switch(shape_deriv(fe_t, elem, i, j, p));
725 }
726 
727 
728 
730  const FEType & fe_t,
731  const ElemType t,
732  const unsigned int i,
733  const unsigned int j,
734  const Point & p)
735 {
736  libmesh_deprecated();
737 
738  inf_fe_switch(shape_deriv(fe_t, t, i, j, p));
739 }
740 #endif // LIBMESH_ENABLE_DEPRECATED
741 
742 
743 
745  const Elem * elem,
746  const unsigned int i,
747  const unsigned int j,
748  const Point & p)
749 {
750  // The inf_fe_switch macro requires a "dim" parameter.
751  auto dim = elem->dim();
752 
753  inf_fe_switch(shape_deriv(fe_t, elem, i, j, p));
754 }
755 
756 
757 void FEInterface::ifem_compute_data(const unsigned int dim,
758  const FEType & fe_t,
759  const Elem * elem,
760  FEComputeData & data)
761 {
762  switch (dim)
763  {
764  case 1:
765  {
766  inf_fe_family_mapping_switch(1, compute_data(fe_t, elem,data), , ;break;);
767  break;
768  }
769  case 2:
770  {
771  inf_fe_family_mapping_switch(2, compute_data(fe_t, elem,data), , ;break;);
772  break;
773  }
774  case 3:
775  {
776  inf_fe_family_mapping_switch(3, compute_data(fe_t, elem,data), , ;break;);
777  break;
778  }
779 
780 
781  default:
782  libmesh_error_msg("Invalid dim = " << dim);
783  break;
784  }
785 }
786 
787 } // namespace libMesh
788 
789 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
ElemType
Defines an enum for geometric element types.
static Point map(const Elem *inf_elem, const Point &reference_point)
Definition: inf_fe.h:457
static unsigned int n_dofs_per_elem(const FEType &fet, const ElemType inf_elem_type)
static unsigned int n_dofs_at_node(const FEType &fet, const ElemType inf_elem_type, const unsigned int n)
Definition: inf_fe_static.C:84
static bool ifem_on_reference_element(const Point &p, const ElemType t, const Real eps)
static Real shape_deriv(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const unsigned int j, const Point &p)
static Real ifem_shape(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const Point &p)
unsigned int dim
class FEComputeData hides arbitrary data to be passed to and from children of FEBase through the FEIn...
static unsigned int ifem_n_shape_functions(const FEType &fe_t, const Elem *elem)
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
The libMesh namespace provides an interface to certain functionality in the library.
static Point ifem_inverse_map(const unsigned int dim, const FEType &fe_t, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
static bool on_reference_element(const Point &p, const ElemType t, const Real eps=TOLERANCE)
Definition: fe_abstract.C:637
static void ifem_compute_data(const unsigned int dim, const FEType &fe_t, const Elem *elem, FEComputeData &data)
static Real shape(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const Point &p)
Definition: fe_interface.C:761
static void compute_data(const unsigned int dim, const FEType &fe_t, const Elem *elem, FEComputeData &data)
Lets the appropriate child of FEBase compute the requested data for the input specified in data...
InfMapType inf_map
The coordinate mapping type of the infinite element.
Definition: fe_type.h:284
static Point ifem_map(const unsigned int dim, const FEType &fe_t, const Elem *elem, const Point &p)
static void ifem_nodal_soln(const unsigned int dim, const FEType &fe_t, const Elem *elem, const std::vector< Number > &elem_soln, std::vector< Number > &nodal_soln)
static unsigned int ifem_n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
FEFamily radial_family
The type of approximation in radial direction.
Definition: fe_type.h:276
std::string enum_to_string(const T e)
static Point inverse_map(const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
Definition: inf_fe.h:465
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual unsigned short dim() const =0
static unsigned int ifem_n_dofs(const FEType &fe_t, const Elem *elem)
static void nodal_soln(const FEType &fet, const Elem *elem, const std::vector< Number > &elem_soln, std::vector< Number > &nodal_soln)
Usually, this method would build the nodal soln from the element soln.
static void nodal_soln(const unsigned int dim, const FEType &fe_t, const Elem *elem, const std::vector< Number > &elem_soln, std::vector< Number > &nodal_soln, const bool add_p_level=true, const unsigned int vdim=1)
Build the nodal soln from the element soln.
Definition: fe_interface.C:626
static Real ifem_shape_deriv(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const unsigned int j, const Point &p)
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
virtual unsigned int n_shape_functions() const override
Definition: inf_fe.h:552
static unsigned int ifem_n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
static unsigned int n_dofs(const FEType &fet, const Elem *inf_elem)
Definition: inf_fe_static.C:66