Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 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/fe.h"
21 : #include "libmesh/elem.h"
22 : #include "libmesh/enum_to_string.h"
23 :
24 : namespace libMesh
25 : {
26 :
27 : // The 2d Raviart-Thomas shape functions are just the 2d Nedelec (first kind)
28 : // shape functions after a 90-degree counterclockwise rotation.
29 : template <>
30 25185560 : RealGradient FE<2,RAVIART_THOMAS>::shape(const Elem * elem,
31 : const Order order,
32 : const unsigned int i,
33 : const Point & p,
34 : const bool add_p_level)
35 : {
36 25185560 : RealGradient ND1 = FE<2,NEDELEC_ONE>::shape(elem, order, i, p, add_p_level);
37 27282442 : return RealGradient(-ND1(1), ND1(0));
38 : }
39 :
40 : template <>
41 2693592 : RealGradient FE<2,L2_RAVIART_THOMAS>::shape(const Elem * elem,
42 : const Order order,
43 : const unsigned int i,
44 : const Point & p,
45 : const bool add_p_level)
46 : {
47 2693592 : return FE<2,RAVIART_THOMAS>::shape(elem, order, i, p, add_p_level);
48 : }
49 :
50 : template <>
51 0 : RealGradient FE<2,RAVIART_THOMAS>::shape(const ElemType,
52 : const Order,
53 : const unsigned int,
54 : const Point &)
55 : {
56 0 : libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause edge orientation is needed.");
57 : return RealGradient();
58 : }
59 :
60 : template <>
61 0 : RealGradient FE<2,L2_RAVIART_THOMAS>::shape(const ElemType,
62 : const Order,
63 : const unsigned int,
64 : const Point &)
65 : {
66 0 : libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause edge orientation is needed.");
67 : return RealGradient();
68 : }
69 :
70 : template <>
71 0 : RealGradient FE<2,RAVIART_THOMAS>::shape(const FEType fet,
72 : const Elem * elem,
73 : const unsigned int i,
74 : const Point & p,
75 : const bool add_p_level)
76 : {
77 0 : return FE<2,RAVIART_THOMAS>::shape(elem, fet.order, i, p, add_p_level);
78 : }
79 :
80 : template <>
81 0 : RealGradient FE<2,L2_RAVIART_THOMAS>::shape(const FEType fet,
82 : const Elem * elem,
83 : const unsigned int i,
84 : const Point & p,
85 : const bool add_p_level)
86 : {
87 0 : return FE<2,L2_RAVIART_THOMAS>::shape(elem, fet.order, i, p, add_p_level);
88 : }
89 :
90 : template <>
91 34280160 : RealGradient FE<2,RAVIART_THOMAS>::shape_deriv(const Elem * elem,
92 : const Order order,
93 : const unsigned int i,
94 : const unsigned int j,
95 : const Point & p,
96 : const bool add_p_level)
97 : {
98 34280160 : RealGradient ND1 = FE<2,NEDELEC_ONE>::shape_deriv(elem, order, i, j, p, add_p_level);
99 37129472 : return RealGradient(-ND1(1), ND1(0));
100 : }
101 :
102 : template <>
103 2125584 : RealGradient FE<2,L2_RAVIART_THOMAS>::shape_deriv(const Elem * elem,
104 : const Order order,
105 : const unsigned int i,
106 : const unsigned int j,
107 : const Point & p,
108 : const bool add_p_level)
109 : {
110 2125584 : return FE<2,RAVIART_THOMAS>::shape_deriv(elem, order, i, j, p, add_p_level);
111 : }
112 :
113 : template <>
114 0 : RealGradient FE<2,RAVIART_THOMAS>::shape_deriv(const ElemType,
115 : const Order,
116 : const unsigned int,
117 : const unsigned int,
118 : const Point &)
119 : {
120 0 : libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause edge orientation is needed.");
121 : return RealGradient();
122 : }
123 :
124 : template <>
125 0 : RealGradient FE<2,L2_RAVIART_THOMAS>::shape_deriv(const ElemType,
126 : const Order,
127 : const unsigned int,
128 : const unsigned int,
129 : const Point &)
130 : {
131 0 : libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause edge orientation is needed.");
132 : return RealGradient();
133 : }
134 :
135 : template <>
136 0 : RealGradient FE<2,RAVIART_THOMAS>::shape_deriv(const FEType fet,
137 : const Elem * elem,
138 : const unsigned int i,
139 : const unsigned int j,
140 : const Point & p,
141 : const bool add_p_level)
142 : {
143 0 : return FE<2,RAVIART_THOMAS>::shape_deriv(elem, fet.order, i, j, p, add_p_level);
144 : }
145 :
146 : template <>
147 0 : RealGradient FE<2,L2_RAVIART_THOMAS>::shape_deriv(const FEType fet,
148 : const Elem * elem,
149 : const unsigned int i,
150 : const unsigned int j,
151 : const Point & p,
152 : const bool add_p_level)
153 : {
154 0 : return FE<2,L2_RAVIART_THOMAS>::shape_deriv(elem, fet.order, i, j, p, add_p_level);
155 : }
156 :
157 : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
158 :
159 : template <>
160 0 : RealGradient FE<2,RAVIART_THOMAS>::shape_second_deriv(const Elem * elem,
161 : const Order order,
162 : const unsigned int i,
163 : const unsigned int j,
164 : const Point & p,
165 : const bool add_p_level)
166 : {
167 0 : RealGradient ND1 = FE<2,NEDELEC_ONE>::shape_second_deriv(elem, order, i, j, p, add_p_level);
168 0 : return RealGradient(-ND1(1), ND1(0));
169 : }
170 :
171 : template <>
172 0 : RealGradient FE<2,L2_RAVIART_THOMAS>::shape_second_deriv(const Elem * elem,
173 : const Order order,
174 : const unsigned int i,
175 : const unsigned int j,
176 : const Point & p,
177 : const bool add_p_level)
178 : {
179 0 : return FE<2,RAVIART_THOMAS>::shape_second_deriv(elem, order, i, j, p, add_p_level);
180 : }
181 :
182 : template <>
183 0 : RealGradient FE<2,RAVIART_THOMAS>::shape_second_deriv(const ElemType,
184 : const Order,
185 : const unsigned int,
186 : const unsigned int,
187 : const Point &)
188 : {
189 0 : libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause edge orientation is needed.");
190 : return RealGradient();
191 : }
192 :
193 : template <>
194 0 : RealGradient FE<2,L2_RAVIART_THOMAS>::shape_second_deriv(const ElemType,
195 : const Order,
196 : const unsigned int,
197 : const unsigned int,
198 : const Point &)
199 : {
200 0 : libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause edge orientation is needed.");
201 : return RealGradient();
202 : }
203 :
204 : template <>
205 0 : RealGradient FE<2,RAVIART_THOMAS>::shape_second_deriv(const FEType fet,
206 : const Elem * elem,
207 : const unsigned int i,
208 : const unsigned int j,
209 : const Point & p,
210 : const bool add_p_level)
211 : {
212 0 : return FE<2,RAVIART_THOMAS>::shape_second_deriv(elem, fet.order, i, j, p, add_p_level);
213 : }
214 :
215 : template <>
216 0 : RealGradient FE<2,L2_RAVIART_THOMAS>::shape_second_deriv(const FEType fet,
217 : const Elem * elem,
218 : const unsigned int i,
219 : const unsigned int j,
220 : const Point & p,
221 : const bool add_p_level)
222 : {
223 0 : return FE<2,L2_RAVIART_THOMAS>::shape_second_deriv(elem, fet.order, i, j, p, add_p_level);
224 : }
225 :
226 : #endif
227 :
228 : } // namespace libMesh
|