libMesh
fe_hierarchic_shape_1D.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 // Local includes
20 #include "libmesh/fe.h"
21 #include "libmesh/elem.h"
22 #include "libmesh/utility.h"
23 
24 
25 // Anonymous namespace for functions shared by HIERARCHIC and
26 // L2_HIERARCHIC implementations. Implementations appear at the bottom
27 // of this file.
28 namespace
29 {
30 using namespace libMesh;
31 
32 Real fe_hierarchic_1D_shape(const ElemType,
33  const Order libmesh_dbg_var(order),
34  const unsigned int i,
35  const Point & p);
36 
37 Real fe_hierarchic_1D_shape_deriv(const ElemType,
38  const Order libmesh_dbg_var(order),
39  const unsigned int i,
40  const unsigned int libmesh_dbg_var(j),
41  const Point & p);
42 
43 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
44 
45 Real fe_hierarchic_1D_shape_second_deriv(const ElemType,
46  const Order libmesh_dbg_var(order),
47  const unsigned int i,
48  const unsigned int libmesh_dbg_var(j),
49  const Point & p);
50 
51 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
52 
53 } // anonymous namespace
54 
55 
56 
57 namespace libMesh
58 {
59 
60 
64 
65 
66 template <>
67 Real FE<1,HIERARCHIC>::shape(const ElemType elem_type,
68  const Order order,
69  const unsigned int i,
70  const Point & p)
71 {
72  return fe_hierarchic_1D_shape(elem_type, order, i, p);
73 }
74 
75 
76 
77 template <>
79  const Order order,
80  const unsigned int i,
81  const Point & p)
82 {
83  return fe_hierarchic_1D_shape(elem_type, order, i, p);
84 }
85 
86 
87 
88 template <>
90  const Order,
91  const unsigned int i,
92  const Point & p)
93 {
94  unsigned int right_side = p(0) > 0; // 0 false, 1 true
95  return (right_side == i);
96 }
97 
98 
99 
100 template <>
102  const Order order,
103  const unsigned int i,
104  const Point & p,
105  const bool add_p_level)
106 {
107  libmesh_assert(elem);
108 
109  return fe_hierarchic_1D_shape(elem->type(), static_cast<Order>(order + add_p_level * elem->p_level()), i, p);
110 }
111 
112 
113 
114 template <>
116  const Elem * elem,
117  const unsigned int i,
118  const Point & p,
119  const bool add_p_level)
120 {
121  libmesh_assert(elem);
122  return fe_hierarchic_1D_shape(elem->type(), static_cast<Order>(fet.order + add_p_level * elem->p_level()), i, p);
123 }
124 
125 
126 
127 
128 
129 template <>
131  const Order order,
132  const unsigned int i,
133  const Point & p,
134  const bool add_p_level)
135 {
136  libmesh_assert(elem);
137 
138  return fe_hierarchic_1D_shape(elem->type(), static_cast<Order>(order + add_p_level * elem->p_level()), i, p);
139 }
140 
141 template <>
143  const Elem * elem,
144  const unsigned int i,
145  const Point & p,
146  const bool add_p_level)
147 {
148  libmesh_assert(elem);
149  return fe_hierarchic_1D_shape(elem->type(), static_cast<Order>(fet.order + add_p_level * elem->p_level()), i, p);
150 }
151 
152 
153 
154 template <>
156  const Order,
157  const unsigned int i,
158  const Point & p,
159  const bool)
160 {
161  unsigned int right_side = p(0) > 0; // 0 false, 1 true
162  return (right_side == i);
163 }
164 
165 template <>
167  const Elem *,
168  const unsigned int i,
169  const Point & p,
170  const bool)
171 {
172  unsigned int right_side = p(0) > 0; // 0 false, 1 true
173  return (right_side == i);
174 }
175 
176 
177 template <>
179  const Order order,
180  const unsigned int i,
181  const unsigned int j,
182  const Point & p)
183 {
184  return fe_hierarchic_1D_shape_deriv(elem_type, order, i, j, p);
185 }
186 
187 
188 
189 template <>
191  const Order order,
192  const unsigned int i,
193  const unsigned int j,
194  const Point & p)
195 {
196  return fe_hierarchic_1D_shape_deriv(elem_type, order, i, j, p);
197 }
198 
199 
200 
201 template <>
203  const Order,
204  const unsigned int,
205  const unsigned int,
206  const Point &)
207 {
208  return 0;
209 }
210 
211 
212 
213 template <>
215  const Order order,
216  const unsigned int i,
217  const unsigned int j,
218  const Point & p,
219  const bool add_p_level)
220 {
221  libmesh_assert(elem);
222 
223  return fe_hierarchic_1D_shape_deriv(elem->type(),
224  static_cast<Order>(order + add_p_level * elem->p_level()), i, j, p);
225 }
226 
227 
228 
229 template <>
231  const Elem * elem,
232  const unsigned int i,
233  const unsigned int j,
234  const Point & p,
235  const bool add_p_level)
236 {
237  libmesh_assert(elem);
238  return fe_hierarchic_1D_shape_deriv(elem->type(), static_cast<Order>(fet.order + add_p_level * elem->p_level()), i, j, p);
239 }
240 
241 
242 
243 
244 template <>
246  const Order order,
247  const unsigned int i,
248  const unsigned int j,
249  const Point & p,
250  const bool add_p_level)
251 {
252  libmesh_assert(elem);
253 
254  return fe_hierarchic_1D_shape_deriv(elem->type(),
255  static_cast<Order>(order + add_p_level * elem->p_level()), i, j, p);
256 }
257 
258 
259 
260 template <>
262  const Elem * elem,
263  const unsigned int i,
264  const unsigned int j,
265  const Point & p,
266  const bool add_p_level)
267 {
268  libmesh_assert(elem);
269  return fe_hierarchic_1D_shape_deriv(elem->type(), static_cast<Order>(fet.order + add_p_level * elem->p_level()), i, j, p);
270 }
271 
272 
273 
274 template <>
276  const Order,
277  const unsigned int,
278  const unsigned int,
279  const Point &,
280  const bool)
281 {
282  return 0;
283 }
284 
285 
286 
287 template <>
289  const Elem *,
290  const unsigned int,
291  const unsigned int,
292  const Point &,
293  const bool)
294 {
295  return 0;
296 }
297 
298 
299 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
300 
301 template <>
303  const Order order,
304  const unsigned int i,
305  const unsigned int j,
306  const Point & p)
307 {
308  return fe_hierarchic_1D_shape_second_deriv(elem_type, order, i, j, p);
309 }
310 
311 
312 
313 
314 template <>
316  const Order order,
317  const unsigned int i,
318  const unsigned int j,
319  const Point & p)
320 {
321  return fe_hierarchic_1D_shape_second_deriv(elem_type, order, i, j, p);
322 }
323 
324 
325 
326 template <>
328  const Order,
329  const unsigned int,
330  const unsigned int,
331  const Point &)
332 {
333  return 0;
334 }
335 
336 
337 
338 template <>
340  const Order order,
341  const unsigned int i,
342  const unsigned int j,
343  const Point & p,
344  const bool add_p_level)
345 {
346  libmesh_assert(elem);
347 
348  return fe_hierarchic_1D_shape_second_deriv(elem->type(),
349  static_cast<Order>(order + add_p_level * elem->p_level()), i, j, p);
350 }
351 
352 
353 
354 template <>
356  const Elem * elem,
357  const unsigned int i,
358  const unsigned int j,
359  const Point & p,
360  const bool add_p_level)
361 {
362  libmesh_assert(elem);
363  return fe_hierarchic_1D_shape_second_deriv(elem->type(),
364  static_cast<Order>(fet.order + add_p_level * elem->p_level()), i, j, p);
365 }
366 
367 
368 template <>
370  const Order order,
371  const unsigned int i,
372  const unsigned int j,
373  const Point & p,
374  const bool add_p_level)
375 {
376  libmesh_assert(elem);
377 
378  return fe_hierarchic_1D_shape_second_deriv(elem->type(),
379  static_cast<Order>(order + add_p_level * elem->p_level()), i, j, p);
380 }
381 
382 
383 template <>
385  const Elem * elem,
386  const unsigned int i,
387  const unsigned int j,
388  const Point & p,
389  const bool add_p_level)
390 {
391  libmesh_assert(elem);
392  return fe_hierarchic_1D_shape_second_deriv(elem->type(),
393  static_cast<Order>(fet.order + add_p_level * elem->p_level()), i, j, p);
394 }
395 
396 
397 template <>
399  const Order,
400  const unsigned int,
401  const unsigned int,
402  const Point &,
403  const bool)
404 {
405  return 0.;
406 }
407 
408 
409 template <>
411  const Elem *,
412  const unsigned int,
413  const unsigned int,
414  const Point &,
415  const bool)
416 {
417  return 0.;
418 }
419 
420 #endif
421 
422 } // namespace libMesh
423 
424 
425 
426 namespace
427 {
428 using namespace libMesh;
429 
430 Real fe_hierarchic_1D_shape(const ElemType,
431  const Order libmesh_dbg_var(order),
432  const unsigned int i,
433  const Point & p)
434 {
435  libmesh_assert_less (i, order+1u);
436 
437  // Declare that we are using our own special power function
438  // from the Utility namespace. This saves typing later.
439  using Utility::pow;
440 
441  const Real xi = p(0);
442 
443  Real returnval = 1.;
444 
445  switch (i)
446  {
447  case 0:
448  returnval = .5*(1. - xi);
449  break;
450  case 1:
451  returnval = .5*(1. + xi);
452  break;
453  // All even-terms have the same form.
454  // (xi^p - 1.)/p!
455  case 2:
456  returnval = (xi*xi - 1.)/2.;
457  break;
458  case 4:
459  returnval = (pow<4>(xi) - 1.)/24.;
460  break;
461  case 6:
462  returnval = (pow<6>(xi) - 1.)/720.;
463  break;
464 
465  // All odd-terms have the same form.
466  // (xi^p - xi)/p!
467  case 3:
468  returnval = (xi*xi*xi - xi)/6.;
469  break;
470  case 5:
471  returnval = (pow<5>(xi) - xi)/120.;
472  break;
473  case 7:
474  returnval = (pow<7>(xi) - xi)/5040.;
475  break;
476  default:
477  Real denominator = 1.;
478  for (unsigned int n=1; n <= i; ++n)
479  {
480  returnval *= xi;
481  denominator *= n;
482  }
483  // Odd:
484  if (i % 2)
485  returnval = (returnval - xi)/denominator;
486  // Even:
487  else
488  returnval = (returnval - 1.)/denominator;
489  break;
490  }
491 
492  return returnval;
493 }
494 
495 
496 
497 Real fe_hierarchic_1D_shape_deriv(const ElemType,
498  const Order libmesh_dbg_var(order),
499  const unsigned int i,
500  const unsigned int libmesh_dbg_var(j),
501  const Point & p)
502 {
503  // only d()/dxi in 1D!
504 
505  libmesh_assert_equal_to (j, 0);
506  libmesh_assert_less (i, order+1u);
507 
508  // Declare that we are using our own special power function
509  // from the Utility namespace. This saves typing later.
510  using Utility::pow;
511 
512  const Real xi = p(0);
513 
514  Real returnval = 1.;
515 
516  switch (i)
517  {
518  case 0:
519  returnval = -.5;
520  break;
521  case 1:
522  returnval = .5;
523  break;
524  // All even-terms have the same form.
525  // xi^(p-1)/(p-1)!
526  case 2:
527  returnval = xi;
528  break;
529  case 4:
530  returnval = pow<3>(xi)/6.;
531  break;
532  case 6:
533  returnval = pow<5>(xi)/120.;
534  break;
535  // All odd-terms have the same form.
536  // (p*xi^(p-1) - 1.)/p!
537  case 3:
538  returnval = (3*xi*xi - 1.)/6.;
539  break;
540  case 5:
541  returnval = (5.*pow<4>(xi) - 1.)/120.;
542  break;
543  case 7:
544  returnval = (7.*pow<6>(xi) - 1.)/5040.;
545  break;
546  default:
547  Real denominator = 1.;
548  for (unsigned int n=1; n != i; ++n)
549  {
550  returnval *= xi;
551  denominator *= n;
552  }
553  // Odd:
554  if (i % 2)
555  returnval = (i * returnval - 1.)/denominator/i;
556  // Even:
557  else
558  returnval = returnval/denominator;
559  break;
560  }
561 
562  return returnval;
563 }
564 
565 
566 
567 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
568 
569 Real fe_hierarchic_1D_shape_second_deriv(const ElemType,
570  const Order libmesh_dbg_var(order),
571  const unsigned int i,
572  const unsigned int libmesh_dbg_var(j),
573  const Point & p)
574 {
575  // only d2()/d2xi in 1D!
576 
577  libmesh_assert_equal_to (j, 0);
578  libmesh_assert_less (i, order+1u);
579 
580  // Declare that we are using our own special power function
581  // from the Utility namespace. This saves typing later.
582  using Utility::pow;
583 
584  const Real xi = p(0);
585 
586  Real returnval = 1.;
587 
588  switch (i)
589  {
590  case 0:
591  case 1:
592  returnval = 0;
593  break;
594  // All terms have the same form.
595  // xi^(p-2)/(p-2)!
596  case 2:
597  returnval = 1;
598  break;
599  case 3:
600  returnval = xi;
601  break;
602  case 4:
603  returnval = pow<2>(xi)/2.;
604  break;
605  case 5:
606  returnval = pow<3>(xi)/6.;
607  break;
608  case 6:
609  returnval = pow<4>(xi)/24.;
610  break;
611  case 7:
612  returnval = pow<5>(xi)/120.;
613  break;
614 
615  default:
616  Real denominator = 1.;
617  for (unsigned int n=1; n != i; ++n)
618  {
619  returnval *= xi;
620  denominator *= n;
621  }
622  // Odd:
623  if (i % 2)
624  returnval = (i * returnval - 1.)/denominator/i;
625  // Even:
626  else
627  returnval = returnval/denominator;
628  break;
629  }
630 
631  return returnval;
632 }
633 
634 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
635 
636 } // anonymous namespace
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:182
ElemType
Defines an enum for geometric element types.
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
static OutputShape shape(const ElemType t, const Order o, const unsigned int i, const Point &p)
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
static OutputShape shape_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
unsigned int p_level() const
Definition: elem.h:2945
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:201
The libMesh namespace provides an interface to certain functionality in the library.
LIBMESH_DEFAULT_VECTORIZED_FE(template<>Real FE< 0, BERNSTEIN)
T pow(const T &x)
Definition: utility.h:328
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
static OutputShape shape_second_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)