libMesh
Loading...
Searching...
No Matches
fe_l2_lagrange_gll.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/elem.h"
22#include "libmesh/enum_to_string.h"
23#include "libmesh/fe.h"
24#include "libmesh/fe_interface.h"
25#include "libmesh/fe_lagrange_gll_shape_1D.h"
26#include "libmesh/fe_macro.h"
27
28
29namespace libMesh
30{
31
41unsigned int l2_lagrange_gll_n_dofs(const ElemType t, const Order o)
42{
43 libmesh_assert_greater (o, 0);
44
45 const unsigned int n = static_cast<unsigned int>(o) + 1;
46
47 libmesh_error_msg_if(n > fe_lagrange_gll_max_points_1D,
48 "The L2_LAGRANGE_GLL basis of order " << o << " needs " << n
49 << " Gauss-Lobatto points, but QGaussLobatto tabulates at most "
51
52 switch (t)
53 {
54 case NODEELEM:
55 return 1;
56
57 case EDGE2:
58 case EDGE3:
59 case EDGE4:
60 return n;
61
62 case QUAD4:
63 case QUADSHELL4:
64 case QUAD8:
65 case QUADSHELL8:
66 case QUAD9:
67 case QUADSHELL9:
68 return n*n;
69
70 case HEX8:
71 case HEX20:
72 case HEX27:
73 return n*n*n;
74
75 case INVALID_ELEM:
76 return 0;
77
78 default:
79 libmesh_error_msg("The L2_LAGRANGE_GLL basis is a tensor product and is not defined on "
80 << Utility::enum_to_string(t) << ".");
81 }
82}
83
84
85unsigned int l2_lagrange_gll_n_dofs(const Elem * e, const Order o)
86{
88 return l2_lagrange_gll_n_dofs(e->type(), o);
89}
90
99 const Order order,
100 const std::vector<Number> & elem_soln,
101 std::vector<Number> & nodal_soln,
102 const bool add_p_level)
103{
104 const unsigned int n_nodes = elem->n_nodes();
105
106 nodal_soln.resize(n_nodes);
107
108 const FEType fe_type(order, L2_LAGRANGE_GLL);
109
110 const unsigned int n_sf =
111 FEInterface::n_shape_functions(fe_type, elem, add_p_level);
112
113 std::vector<Point> refspace_nodes;
114 FEBase::get_refspace_nodes(elem->type(), refspace_nodes);
115 libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);
116 libmesh_assert_equal_to (elem_soln.size(), n_sf);
117
118 std::fill(nodal_soln.begin(), nodal_soln.end(), 0);
119
120 for (const auto n : make_range(n_nodes))
121 for (const auto i : make_range(n_sf))
122 nodal_soln[n] += elem_soln[i] *
123 FEInterface::shape(fe_type, elem, i, refspace_nodes[n], add_p_level);
124}
125
128
129
130// Every degree of freedom of this basis belongs to the element
131template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
132template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
133template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
134template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
135
136template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_gll_n_dofs(e, o); }
137template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_gll_n_dofs(e, o); }
138template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_gll_n_dofs(e, o); }
139template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_gll_n_dofs(e, o); }
140
141template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
142template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
143template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
144template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
145
146template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
147template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
148template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
149template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
150
151template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
152template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
153template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
154template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
155
156template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_gll_n_dofs(&e, o); }
157template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_gll_n_dofs(&e, o); }
158template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_gll_n_dofs(&e, o); }
159template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_gll_n_dofs(&e, o); }
160
161
166
167// A nodal basis is not hierarchic
168template <> bool FE<0,L2_LAGRANGE_GLL>::is_hierarchic() const { return false; }
169template <> bool FE<1,L2_LAGRANGE_GLL>::is_hierarchic() const { return false; }
170template <> bool FE<2,L2_LAGRANGE_GLL>::is_hierarchic() const { return false; }
171template <> bool FE<3,L2_LAGRANGE_GLL>::is_hierarchic() const { return false; }
172
173// The shape functions are the same on every element of a type
174template <> bool FE<0,L2_LAGRANGE_GLL>::shapes_need_reinit() const { return false; }
175template <> bool FE<1,L2_LAGRANGE_GLL>::shapes_need_reinit() const { return false; }
176template <> bool FE<2,L2_LAGRANGE_GLL>::shapes_need_reinit() const { return false; }
177template <> bool FE<3,L2_LAGRANGE_GLL>::shapes_need_reinit() const { return false; }
178
179// This DISCONTINUOUS basis doesn't need hanging node constraints, so these are empty
180#ifdef LIBMESH_ENABLE_AMR
181template <>
183 DofMap &,
184 const unsigned int,
185 const Elem *)
186{ }
187
188template <>
190 DofMap &,
191 const unsigned int,
192 const Elem *)
193{ }
194#endif // LIBMESH_ENABLE_AMR
195
196
197} // namespace libMesh
The constraint matrix storage format.
Definition dof_map.h:112
This class handles the numbering of degrees of freedom on a mesh.
Definition dof_map.h:181
This is the base class from which all geometric element types are derived.
Definition elem.h:96
virtual unsigned int n_nodes() const =0
virtual ElemType type() const =0
static void get_refspace_nodes(const ElemType t, std::vector< Point > &nodes)
static Real shape(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const Point &p)
static unsigned int n_shape_functions(const unsigned int dim, const FEType &fe_t, const ElemType t)
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition fe_type.h:197
virtual bool is_hierarchic() const override
static unsigned int n_dofs_per_elem(const ElemType t, const Order o)
virtual FEContinuity get_continuity() const override
static void compute_constraints(DofConstraints &constraints, DofMap &dof_map, const unsigned int variable_number, const Elem *elem)
Computes the constraint matrix contributions (for non-conforming adapted meshes) corresponding to var...
static unsigned int n_dofs(const ElemType t, const Order o)
static unsigned int n_dofs_at_node(const ElemType t, const Order o, const unsigned int n)
virtual bool shapes_need_reinit() const override
std::string enum_to_string(const T e)
The libMesh namespace provides an interface to certain functionality in the library.
LIBMESH_FE_NODAL_SOLN(BERNSTEIN, bernstein_nodal_soln)
void l2_lagrange_gll_nodal_soln(const Elem *elem, const Order order, const std::vector< Number > &elem_soln, std::vector< Number > &nodal_soln, const bool add_p_level)
Evaluates the solution at the nodes of elem, for output formats that write nodal values.
ElemType
Defines an enum for geometric element types.
libmesh_assert(ctx)
unsigned int l2_lagrange_gll_n_dofs(const ElemType t, const Order o)
constexpr unsigned int fe_lagrange_gll_max_points_1D
The number of points in the largest Gauss-Lobatto rule that QGaussLobatto tabulates,...
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition int_range.h:176
LIBMESH_FE_SIDE_NODAL_SOLN(HIERARCHIC_VEC)
const dof_id_type n_nodes
Definition tecplot_io.C:67