libMesh
fe_rational_shape_1D.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 
20 // Local includes
21 #include "libmesh/libmesh_config.h"
22 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
23 
24 #include "libmesh/libmesh_common.h"
25 #include "libmesh/elem.h"
26 #include "libmesh/fe.h"
27 #include "libmesh/fe_interface.h"
28 
29 
30 namespace {
31 static const libMesh::FEFamily _underlying_fe_family = libMesh::BERNSTEIN;
32 }
33 
34 
35 namespace libMesh
36 {
37 
38 template <>
40  const Order,
41  const unsigned int,
42  const Point &)
43 {
44  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
45  return 0.;
46 }
47 
48 
49 
50 template <>
52  const Order order,
53  const unsigned int i,
54  const Point & p,
55  const bool add_p_level)
56 {
57  libmesh_assert(elem);
58 
59  const ElemType elem_type = elem->type();
60 
61  const Order totalorder = static_cast<Order>(order + add_p_level * elem->p_level());
62 
63  // FEType object to be passed to various FEInterface functions below.
64  FEType fe_type(totalorder, _underlying_fe_family);
65 
66  const unsigned int n_sf =
67  FEInterface::n_shape_functions(1, fe_type, elem_type);
68 
69  const unsigned int n_nodes = elem->n_nodes();
70  libmesh_assert_equal_to (n_sf, n_nodes);
71 
72  std::vector<Real> node_weights(n_nodes);
73 
74  const unsigned char datum_index = elem->mapping_data();
75  for (unsigned int n=0; n<n_nodes; n++)
76  node_weights[n] =
77  elem->node_ref(n).get_extra_datum<Real>(datum_index);
78 
79  Real weighted_shape_i = 0, weighted_sum = 0;
80 
81  for (unsigned int sf=0; sf<n_sf; sf++)
82  {
83  Real weighted_shape = node_weights[sf] *
84  FEInterface::shape(1, fe_type, elem, sf, p);
85  weighted_sum += weighted_shape;
86  if (sf == i)
87  weighted_shape_i = weighted_shape;
88  }
89 
90  return weighted_shape_i / weighted_sum;
91 }
92 
93 
94 
95 template <>
97  const Order,
98  const unsigned int,
99  const unsigned int,
100  const Point &)
101 {
102  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
103  return 0.;
104 }
105 
106 
107 
108 template <>
110  const Order order,
111  const unsigned int i,
112  const unsigned int libmesh_dbg_var(j),
113  const Point & p,
114  const bool add_p_level)
115 {
116  // only d()/dxi in 1D!
117  libmesh_assert_equal_to (j, 0);
118 
119  libmesh_assert(elem);
120 
121  const ElemType elem_type = elem->type();
122 
123  const Order totalorder = static_cast<Order>(order + add_p_level * elem->p_level());
124 
125  // FEType object to be passed to various FEInterface functions below.
126  FEType fe_type(totalorder, _underlying_fe_family);
127 
128  const unsigned int n_sf =
129  FEInterface::n_shape_functions(1, fe_type, elem_type);
130 
131  const unsigned int n_nodes = elem->n_nodes();
132  libmesh_assert_equal_to (n_sf, n_nodes);
133 
134  std::vector<Real> node_weights(n_nodes);
135 
136  const unsigned char datum_index = elem->mapping_data();
137  for (unsigned int n=0; n<n_nodes; n++)
138  node_weights[n] =
139  elem->node_ref(n).get_extra_datum<Real>(datum_index);
140 
141  Real weighted_shape_i = 0, weighted_sum = 0,
142  weighted_grad_i = 0, weighted_grad_sum = 0;
143 
144  for (unsigned int sf=0; sf<n_sf; sf++)
145  {
146  Real weighted_shape = node_weights[sf] *
147  FEInterface::shape(1, fe_type, elem, sf, p);
148  Real weighted_grad = node_weights[sf] *
149  FEInterface::shape_deriv(1, fe_type, elem, sf, 0, p);
150  weighted_sum += weighted_shape;
151  weighted_grad_sum += weighted_grad;
152  if (sf == i)
153  {
154  weighted_shape_i = weighted_shape;
155  weighted_grad_i = weighted_grad;
156  }
157  }
158 
159  return (weighted_sum * weighted_grad_i - weighted_shape_i * weighted_grad_sum) /
160  weighted_sum / weighted_sum;
161 }
162 
163 
164 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
165 
166 template <>
168  const Order,
169  const unsigned int,
170  const unsigned int,
171  const Point &)
172 {
173  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
174  return 0.;
175 }
176 
177 
178 
179 
180 template <>
182  const Order order,
183  const unsigned int i,
184  const unsigned int libmesh_dbg_var(j),
185  const Point & p,
186  const bool add_p_level)
187 {
188  // Don't need to switch on j. 1D shape functions
189  // depend on xi only!
190  libmesh_assert_equal_to (j, 0);
191 
192  libmesh_assert(elem);
193 
194  const ElemType elem_type = elem->type();
195 
196  const Order totalorder = static_cast<Order>(order + add_p_level * elem->p_level());
197 
198  // FEType object to be passed to various FEInterface functions below.
199  FEType fe_type(totalorder, _underlying_fe_family);
200 
201  const unsigned int n_sf =
202  FEInterface::n_shape_functions(1, fe_type, elem_type);
203 
204  const unsigned int n_nodes = elem->n_nodes();
205  libmesh_assert_equal_to (n_sf, n_nodes);
206 
207  std::vector<Real> node_weights(n_nodes);
208 
209  const unsigned char datum_index = elem->mapping_data();
210  for (unsigned int n=0; n<n_nodes; n++)
211  node_weights[n] =
212  elem->node_ref(n).get_extra_datum<Real>(datum_index);
213 
214  Real weighted_shape_i = 0, weighted_sum = 0,
215  weighted_grad_i = 0, weighted_grad_sum = 0,
216  weighted_hess_i = 0, weighted_hess_sum = 0;
217 
218  for (unsigned int sf=0; sf<n_sf; sf++)
219  {
220  Real weighted_shape = node_weights[sf] *
221  FEInterface::shape(1, fe_type, elem, sf, p);
222  Real weighted_grad = node_weights[sf] *
223  FEInterface::shape_deriv(1, fe_type, elem, sf, 0, p);
224  Real weighted_hess = node_weights[sf] *
225  FEInterface::shape_second_deriv(1, fe_type, elem, sf, 0, p);
226  weighted_sum += weighted_shape;
227  weighted_grad_sum += weighted_grad;
228  weighted_hess_sum += weighted_hess;
229  if (sf == i)
230  {
231  weighted_shape_i = weighted_shape;
232  weighted_grad_i = weighted_grad;
233  weighted_hess_i = weighted_hess;
234  }
235  }
236 
237  return (weighted_sum * weighted_sum *
238  (weighted_sum * weighted_hess_i - weighted_shape_i * weighted_hess_sum) -
239  (weighted_sum * weighted_grad_i - weighted_shape_i * weighted_grad_sum) *
240  2 * weighted_sum * weighted_grad_sum) /
241  (weighted_sum * weighted_sum * weighted_sum * weighted_sum);
242 }
243 
244 #endif
245 
246 } // namespace libMesh
247 
248 
249 #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