libMesh
Loading...
Searching...
No Matches
fe_l2_hierarchic.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_macro.h"
26
27namespace libMesh
28{
29
30// ------------------------------------------------------------
31// Hierarchic-specific implementations
32
33// Anonymous namespace for local helper functions
34namespace {
35
36void l2_hierarchic_nodal_soln(const Elem * elem,
37 const Order order,
38 const std::vector<Number> & elem_soln,
39 std::vector<Number> & nodal_soln,
40 const bool add_p_level)
41{
42 const unsigned int n_nodes = elem->n_nodes();
43
44 const ElemType elem_type = elem->type();
45
46 nodal_soln.resize(n_nodes);
47
48 const Order totalorder = order + add_p_level*elem->p_level();
49
50 // FEType object to be passed to various FEInterface functions below.
51 FEType fe_type(order, L2_HIERARCHIC);
52
53 switch (totalorder)
54 {
55 // Constant shape functions
56 case CONSTANT:
57 {
58 libmesh_assert_equal_to (elem_soln.size(), 1);
59
60 std::fill(nodal_soln.begin(), nodal_soln.end(), elem_soln[0]);
61
62 return;
63 }
64
65
66 // For other orders do interpolation at the nodes
67 // explicitly.
68 default:
69 {
70 const unsigned int n_sf =
71 FEInterface::n_shape_functions(fe_type, elem);
72
73 std::vector<Point> refspace_nodes;
74 FEBase::get_refspace_nodes(elem_type,refspace_nodes);
75 libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);
76 libmesh_assert_equal_to (elem_soln.size(), n_sf);
77
78 // Zero before summation
79 std::fill(nodal_soln.begin(), nodal_soln.end(), 0);
80
81 for (unsigned int n=0; n<n_nodes; n++)
82 // u_i = Sum (alpha_i phi_i)
83 for (unsigned int i=0; i<n_sf; i++)
84 nodal_soln[n] += elem_soln[i] *
85 FEInterface::shape(fe_type, elem, i, refspace_nodes[n]);
86
87 return;
88 }
89 }
90} // l2_hierarchic_nodal_soln()
91
92
93
94unsigned int l2_hierarchic_n_dofs(const ElemType t, const Order o)
95{
96 libmesh_assert_greater (o, 0);
97 switch (t)
98 {
99 case NODEELEM:
100 return 1;
101 case EDGE2:
102 case EDGE3:
103 return (o+1);
104 case QUAD4:
105 case QUADSHELL4:
106 case QUAD8:
107 case QUADSHELL8:
108 case QUAD9:
109 case QUADSHELL9:
110 return ((o+1)*(o+1));
111 case HEX8:
112 case HEX20:
113 case HEX27:
114 return ((o+1)*(o+1)*(o+1));
115 case PRISM6:
116 case PRISM15:
117 case PRISM18:
118 case PRISM20:
119 case PRISM21:
120 return ((o+1)*(o+1)*(o+2)/2);
121 case TRI3:
122 case TRI6:
123 case TRI7:
124 return ((o+1)*(o+2)/2);
125 case TET4:
126 case TET10:
127 case TET14:
128 return ((o+1)*(o+2)*(o+3)/6);
129 case INVALID_ELEM:
130 return 0;
131 default:
132 libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for L2_HIERARCHIC FE family!");
133 }
134} // l2_hierarchic_n_dofs()
135
136
137
138unsigned int l2_hierarchic_n_dofs(const Elem * e, const Order o)
139{
141 return l2_hierarchic_n_dofs(e->type(), o);
142}
143
144
145} // anonymous namespace
146
147
148// Instantiate (side_) nodal_soln() function for every dimension
149LIBMESH_FE_NODAL_SOLN(L2_HIERARCHIC, l2_hierarchic_nodal_soln)
151
152
153// Full specialization of n_dofs() function for every dimension
154template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
155template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
156template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
157template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
158
159template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs(const Elem * e, const Order o) { return l2_hierarchic_n_dofs(e, o); }
160template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs(const Elem * e, const Order o) { return l2_hierarchic_n_dofs(e, o); }
161template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs(const Elem * e, const Order o) { return l2_hierarchic_n_dofs(e, o); }
162template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs(const Elem * e, const Order o) { return l2_hierarchic_n_dofs(e, o); }
163
164// Full specialization of n_dofs_at_node() function for every dimension.
165// Discontinuous L2 elements only have interior nodes
166template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
167template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
168template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
169template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
170
171template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
172template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
173template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
174template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
175
176// Full specialization of n_dofs_per_elem() function for every dimension.
177template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
178template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
179template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
180template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
181
182template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_hierarchic_n_dofs(&e, o); }
183template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_hierarchic_n_dofs(&e, o); }
184template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_hierarchic_n_dofs(&e, o); }
185template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_hierarchic_n_dofs(&e, o); }
186
187// L2 Hierarchic FEMs are C^0 continuous
192
193// L2 Hierarchic FEMs are hierarchic (duh!)
194template <> bool FE<0,L2_HIERARCHIC>::is_hierarchic() const { return true; }
195template <> bool FE<1,L2_HIERARCHIC>::is_hierarchic() const { return true; }
196template <> bool FE<2,L2_HIERARCHIC>::is_hierarchic() const { return true; }
197template <> bool FE<3,L2_HIERARCHIC>::is_hierarchic() const { return true; }
198
199#ifdef LIBMESH_ENABLE_AMR
200// compute_constraints() is a NOOP for DISCONTINUOUS FE's
201template <>
203 DofMap &,
204 const unsigned int,
205 const Elem *)
206{ }
207
208template <>
210 DofMap &,
211 const unsigned int,
212 const Elem *)
213{ }
214#endif // #ifdef LIBMESH_ENABLE_AMR
215
216// L2-Hierarchic FEM shapes need reinit
217template <> bool FE<0,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
218template <> bool FE<1,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
219template <> bool FE<2,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
220template <> bool FE<3,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
221
222} // 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
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)
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)
ElemType
Defines an enum for geometric element types.
libmesh_assert(ctx)
LIBMESH_FE_SIDE_NODAL_SOLN(HIERARCHIC_VEC)
const dof_id_type n_nodes
Definition tecplot_io.C:67