libMesh
fe_xyz_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 // C++ includes
20 
21 // Local includes
22 #include "libmesh/fe.h"
23 #include "libmesh/elem.h"
24 
25 
26 namespace libMesh
27 {
28 
29 
31 
32 
33 template <>
34 Real FE<1,XYZ>::shape(const Elem * elem,
35  const Order libmesh_dbg_var(order),
36  const unsigned int i,
37  const Point & point_in,
38  const bool libmesh_dbg_var(add_p_level))
39 {
40  libmesh_assert(elem);
41  libmesh_assert_less_equal (i, order + add_p_level * elem->p_level());
42 
43  Point avg = elem->vertex_average();
44  Real max_distance = 0.;
45  for (const Point & p : elem->node_ref_range())
46  {
47  const Real distance = std::abs(avg(0) - p(0));
48  max_distance = std::max(distance, max_distance);
49  }
50 
51  const Real x = point_in(0);
52  const Real xc = avg(0);
53  const Real dx = (x - xc)/max_distance;
54 
55  // monomials. since they are hierarchic we only need one case block.
56  switch (i)
57  {
58  case 0:
59  return 1.;
60 
61  case 1:
62  return dx;
63 
64  case 2:
65  return dx*dx;
66 
67  case 3:
68  return dx*dx*dx;
69 
70  case 4:
71  return dx*dx*dx*dx;
72 
73  default:
74  Real val = 1.;
75  for (unsigned int index = 0; index != i; ++index)
76  val *= dx;
77  return val;
78  }
79 }
80 
81 
82 
83 template <>
85  const Order,
86  const unsigned int,
87  const Point &)
88 {
89  libmesh_error_msg("XYZ polynomials require the element.");
90  return 0.;
91 }
92 
93 
94 
95 
96 template <>
98  const Elem * elem,
99  const unsigned int i,
100  const Point & p,
101  const bool add_p_level)
102 {
103  return FE<1,XYZ>::shape(elem, fet.order, i, p, add_p_level);
104 }
105 
106 
107 template <>
109  const Order libmesh_dbg_var(order),
110  const unsigned int i,
111  const unsigned int libmesh_dbg_var(j),
112  const Point & point_in,
113  const bool libmesh_dbg_var(add_p_level))
114 {
115  libmesh_assert(elem);
116  libmesh_assert_less_equal (i, order + add_p_level * elem->p_level());
117 
118  // only d()/dxi in 1D!
119 
120  libmesh_assert_equal_to (j, 0);
121 
122  Point avg = elem->vertex_average();
123  Real max_distance = 0.;
124  for (const Point & p : elem->node_ref_range())
125  {
126  const Real distance = std::abs(avg(0) - p(0));
127  max_distance = std::max(distance, max_distance);
128  }
129 
130  const Real x = point_in(0);
131  const Real xc = avg(0);
132  const Real dx = (x - xc)/max_distance;
133 
134  // monomials. since they are hierarchic we only need one case block.
135  switch (i)
136  {
137  case 0:
138  return 0.;
139 
140  case 1:
141  return 1./max_distance;
142 
143  case 2:
144  return 2.*dx/max_distance;
145 
146  case 3:
147  return 3.*dx*dx/max_distance;
148 
149  case 4:
150  return 4.*dx*dx*dx/max_distance;
151 
152  default:
153  Real val = i;
154  for (unsigned int index = 1; index != i; ++index)
155  val *= dx;
156  return val/max_distance;
157  }
158 }
159 
160 
161 
162 template <>
164  const Order,
165  const unsigned int,
166  const unsigned int,
167  const Point &)
168 {
169  libmesh_error_msg("XYZ polynomials require the element.");
170  return 0.;
171 }
172 
173 
174 template <>
176  const Elem * elem,
177  const unsigned int i,
178  const unsigned int j,
179  const Point & p,
180  const bool add_p_level)
181 {
182  return FE<1,XYZ>::shape_deriv(elem, fet.order, i, j, p, add_p_level);
183 }
184 
185 
186 
187 
188 
189 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
190 
191 
192 
193 template <>
195  const Order libmesh_dbg_var(order),
196  const unsigned int i,
197  const unsigned int libmesh_dbg_var(j),
198  const Point & point_in,
199  const bool libmesh_dbg_var(add_p_level))
200 {
201  libmesh_assert(elem);
202  libmesh_assert_less_equal (i, order + add_p_level * elem->p_level());
203 
204  // only d2()/dxi2 in 1D!
205 
206  libmesh_assert_equal_to (j, 0);
207 
208  Point avg = elem->vertex_average();
209  Real max_distance = 0.;
210  for (const Point & p : elem->node_ref_range())
211  {
212  const Real distance = std::abs(avg(0) - p(0));
213  max_distance = std::max(distance, max_distance);
214  }
215 
216  const Real x = point_in(0);
217  const Real xc = avg(0);
218  const Real dx = (x - xc)/max_distance;
219  const Real dist2 = pow(max_distance,2.);
220 
221  // monomials. since they are hierarchic we only need one case block.
222  switch (i)
223  {
224  case 0:
225  case 1:
226  return 0.;
227 
228  case 2:
229  return 2./dist2;
230 
231  case 3:
232  return 6.*dx/dist2;
233 
234  case 4:
235  return 12.*dx*dx/dist2;
236 
237  default:
238  Real val = 2.;
239  for (unsigned int index = 2; index != i; ++index)
240  val *= (index+1) * dx;
241  return val/dist2;
242  }
243 }
244 
245 
246 template <>
248  const Order,
249  const unsigned int,
250  const unsigned int,
251  const Point &)
252 {
253  libmesh_error_msg("XYZ polynomials require the element.");
254  return 0.;
255 }
256 
257 
258 
259 template <>
261  const Elem * elem,
262  const unsigned int i,
263  const unsigned int j,
264  const Point & p,
265  const bool add_p_level)
266 {
267  return FE<1,XYZ>::shape_second_deriv(elem, fet.order, i, j, p, add_p_level);
268 }
269 
270 #endif
271 
272 } // namespace libMesh
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.
Real distance(const Point &p)
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
Definition: type_vector.h:57
LIBMESH_DEFAULT_VECTORIZED_FE(template<>Real FE< 0, BERNSTEIN)
T pow(const T &x)
Definition: utility.h:328
libmesh_assert(ctx)
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
Definition: elem.h:2474
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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)
Point vertex_average() const
Definition: elem.C:498