libMesh
fe_rational_shape_3D.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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/libmesh_config.h"
21 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
22 
23 #include "libmesh/elem.h"
24 #include "libmesh/fe.h"
25 #include "libmesh/fe_interface.h"
26 
27 
28 namespace {
29 static const libMesh::FEFamily _underlying_fe_family = libMesh::BERNSTEIN;
30 }
31 
32 
33 namespace libMesh
34 {
35 
36 template <>
38  const Order,
39  const unsigned int,
40  const Point &)
41 {
42  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
43  return 0.;
44 }
45 
46 
47 
48 template <>
50  const Order order,
51  const unsigned int i,
52  const Point & p,
53  const bool add_p_level)
54 {
55  libmesh_assert(elem);
56 
57  const ElemType elem_type = elem->type();
58 
59  const Order totalorder = static_cast<Order>(order + add_p_level * elem->p_level());
60 
61  // FEType object to be passed to various FEInterface functions below.
62  FEType fe_type(totalorder, _underlying_fe_family);
63 
64  const unsigned int n_sf =
65  FEInterface::n_shape_functions(3, fe_type, elem_type);
66 
67  const unsigned int n_nodes = elem->n_nodes();
68  libmesh_assert_equal_to (n_sf, n_nodes);
69 
70  std::vector<Real> node_weights(n_nodes);
71 
72  const unsigned char datum_index = elem->mapping_data();
73  for (unsigned int n=0; n<n_nodes; n++)
74  node_weights[n] =
75  elem->node_ref(n).get_extra_datum<Real>(datum_index);
76 
77  Real weighted_shape_i = 0, weighted_sum = 0;
78 
79  for (unsigned int sf=0; sf<n_sf; sf++)
80  {
81  Real weighted_shape = node_weights[sf] *
82  FEInterface::shape(3, fe_type, elem, sf, p);
83  weighted_sum += weighted_shape;
84  if (sf == i)
85  weighted_shape_i = weighted_shape;
86  }
87 
88  return weighted_shape_i / weighted_sum;
89 }
90 
91 
92 
93 template <>
95  const Order,
96  const unsigned int,
97  const unsigned int,
98  const Point &)
99 {
100  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
101  return 0.;
102 }
103 
104 
105 
106 template <>
108  const Order order,
109  const unsigned int i,
110  const unsigned int j,
111  const Point & p,
112  const bool add_p_level)
113 {
114  libmesh_assert(elem);
115 
116  const ElemType elem_type = elem->type();
117 
118  const Order totalorder = static_cast<Order>(order + add_p_level * elem->p_level());
119 
120  // FEType object to be passed to various FEInterface functions below.
121  FEType fe_type(totalorder, _underlying_fe_family);
122 
123  const unsigned int n_sf =
124  FEInterface::n_shape_functions(3, fe_type, elem_type);
125 
126  const unsigned int n_nodes = elem->n_nodes();
127  libmesh_assert_equal_to (n_sf, n_nodes);
128 
129  std::vector<Real> node_weights(n_nodes);
130 
131  const unsigned char datum_index = elem->mapping_data();
132  for (unsigned int n=0; n<n_nodes; n++)
133  node_weights[n] =
134  elem->node_ref(n).get_extra_datum<Real>(datum_index);
135 
136  Real weighted_shape_i = 0, weighted_sum = 0,
137  weighted_grad_i = 0, weighted_grad_sum = 0;
138 
139  for (unsigned int sf=0; sf<n_sf; sf++)
140  {
141  Real weighted_shape = node_weights[sf] *
142  FEInterface::shape(3, fe_type, elem, sf, p);
143  Real weighted_grad = node_weights[sf] *
144  FEInterface::shape_deriv(3, fe_type, elem, sf, j, p);
145  weighted_sum += weighted_shape;
146  weighted_grad_sum += weighted_grad;
147  if (sf == i)
148  {
149  weighted_shape_i = weighted_shape;
150  weighted_grad_i = weighted_grad;
151  }
152  }
153 
154  return (weighted_sum * weighted_grad_i - weighted_shape_i * weighted_grad_sum) /
155  weighted_sum / weighted_sum;
156 }
157 
158 
159 
160 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
161 template <>
163  const Order,
164  const unsigned int,
165  const unsigned int,
166  const Point &)
167 {
168  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
169  return 0.;
170 }
171 
172 
173 
174 template <>
176  const Order order,
177  const unsigned int i,
178  const unsigned int j,
179  const Point & p,
180  const bool add_p_level)
181 {
182  unsigned int j1, j2;
183  switch (j)
184  {
185  case 0:
186  // j = 0 ==> d^2 phi / dxi^2
187  j1 = j2 = 0;
188  break;
189  case 1:
190  // j = 1 ==> d^2 phi / dxi deta
191  j1 = 0;
192  j2 = 1;
193  break;
194  case 2:
195  // j = 2 ==> d^2 phi / deta^2
196  j1 = j2 = 1;
197  break;
198  case 3:
199  // j = 3 ==> d^2 phi / dxi dzeta
200  j1 = 0;
201  j2 = 2;
202  break;
203  case 4:
204  // j = 4 ==> d^2 phi / deta dzeta
205  j1 = 1;
206  j2 = 2;
207  break;
208  case 5:
209  // j = 5 ==> d^2 phi / dzeta^2
210  j1 = j2 = 2;
211  break;
212  default:
213  libmesh_error();
214  }
215 
216  libmesh_assert(elem);
217 
218  const ElemType elem_type = elem->type();
219 
220  const Order totalorder = static_cast<Order>(order + add_p_level * elem->p_level());
221 
222  // FEType object to be passed to various FEInterface functions below.
223  FEType fe_type(totalorder, _underlying_fe_family);
224 
225  const unsigned int n_sf =
226  FEInterface::n_shape_functions(3, fe_type, elem_type);
227 
228  const unsigned int n_nodes = elem->n_nodes();
229  libmesh_assert_equal_to (n_sf, n_nodes);
230 
231  std::vector<Real> node_weights(n_nodes);
232 
233  const unsigned char datum_index = elem->mapping_data();
234  for (unsigned int n=0; n<n_nodes; n++)
235  node_weights[n] =
236  elem->node_ref(n).get_extra_datum<Real>(datum_index);
237 
238  Real weighted_shape_i = 0, weighted_sum = 0,
239  weighted_grada_i = 0, weighted_grada_sum = 0,
240  weighted_gradb_i = 0, weighted_gradb_sum = 0,
241  weighted_hess_i = 0, weighted_hess_sum = 0;
242 
243  for (unsigned int sf=0; sf<n_sf; sf++)
244  {
245  Real weighted_shape = node_weights[sf] *
246  FEInterface::shape(3, fe_type, elem, sf, p);
247  Real weighted_grada = node_weights[sf] *
248  FEInterface::shape_deriv(3, fe_type, elem, sf, j1, p);
249  Real weighted_hess = node_weights[sf] *
250  FEInterface::shape_second_deriv(3, fe_type, elem, sf, j, p);
251  weighted_sum += weighted_shape;
252  weighted_grada_sum += weighted_grada;
253  Real weighted_gradb = weighted_grada;
254  if (j1 != j2)
255  {
256  weighted_gradb = (j1 == j2) ? weighted_grada :
257  node_weights[sf] *
258  FEInterface::shape_deriv(3, fe_type, elem, sf, j2, p);
259  weighted_grada_sum += weighted_grada;
260  }
261  weighted_hess_sum += weighted_hess;
262  if (sf == i)
263  {
264  weighted_shape_i = weighted_shape;
265  weighted_grada_i = weighted_grada;
266  weighted_gradb_i = weighted_gradb;
267  weighted_hess_i = weighted_hess;
268  }
269  }
270 
271  if (j1 == j2)
272  weighted_gradb_sum = weighted_grada_sum;
273 
274  return (weighted_sum * weighted_hess_i - weighted_grada_i * weighted_gradb_sum -
275  weighted_shape_i * weighted_hess_sum - weighted_gradb_i * weighted_grada_sum +
276  2 * weighted_grada_sum * weighted_shape_i * weighted_gradb_sum / weighted_sum) /
277  weighted_sum / weighted_sum;
278 }
279 
280 #endif
281 
282 } // namespace libMesh
283 
284 
285 #endif// LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
libMesh::Elem::mapping_data
unsigned char mapping_data() const
Definition: elem.h:2540
libMesh::FE::shape_second_deriv
static OutputShape shape_second_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
libMesh::FEInterface::n_shape_functions
static unsigned int n_shape_functions(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:446
libMesh::Elem::n_nodes
virtual unsigned int n_nodes() const =0
libMesh::FEInterface::shape_second_deriv
static Real shape_second_deriv(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const unsigned int j, const Point &p)
Definition: fe_interface.C:924
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::Order
Order
Definition: enum_order.h:40
libMesh::Elem::p_level
unsigned int p_level() const
Definition: elem.h:2512
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::DofObject::get_extra_datum
T get_extra_datum(const unsigned int index) const
Gets the value on this object of the extra datum associated with index, which should have been obtain...
Definition: dof_object.h:1062
libMesh::FE::shape
static OutputShape shape(const ElemType t, const Order o, const unsigned int i, const Point &p)
libMesh::FE::shape_deriv
static OutputShape shape_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::BERNSTEIN
Definition: enum_fe_family.h:43
n_nodes
const dof_id_type n_nodes
Definition: tecplot_io.C:68
libMesh::FEInterface::shape_deriv
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)
Definition: fe_interface.C:845
libMesh::FEType
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:178
libMesh::FEFamily
FEFamily
Definition: enum_fe_family.h:34
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::Elem::node_ref
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2031
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::Elem::type
virtual ElemType type() const =0
libMesh::ElemType
ElemType
Defines an enum for geometric element types.
Definition: enum_elem_type.h:33
libMesh::FEInterface::shape
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:687