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 :
20 : #ifndef LIBMESH_FE_ABSTRACT_H
21 : #define LIBMESH_FE_ABSTRACT_H
22 :
23 : // Local includes
24 : #include "libmesh/reference_counted_object.h"
25 : #include "libmesh/point.h"
26 : #include "libmesh/vector_value.h"
27 : #include "libmesh/fe_type.h"
28 : #include "libmesh/fe_map.h"
29 : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
30 : #include "libmesh/tensor_value.h"
31 : #endif
32 :
33 : // C++ includes
34 : #include <cstddef>
35 : #include <vector>
36 : #include <memory>
37 :
38 : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
39 : #define virtual_for_inffe virtual
40 : #else
41 : #define virtual_for_inffe
42 : #endif
43 :
44 :
45 : namespace libMesh
46 : {
47 :
48 :
49 : // forward declarations
50 : template <typename T> class DenseMatrix;
51 : template <typename T> class DenseVector;
52 : class BoundaryInfo;
53 : class DofConstraints;
54 : class DofMap;
55 : class Elem;
56 : class MeshBase;
57 : template <typename T> class NumericVector;
58 : class QBase;
59 : enum ElemType : int;
60 :
61 : #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
62 : class NodeConstraints;
63 : #endif
64 :
65 : #ifdef LIBMESH_ENABLE_PERIODIC
66 : class PeriodicBoundaries;
67 : class PointLocatorBase;
68 : #endif
69 :
70 : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
71 : template <unsigned int Dim, FEFamily T_radial, InfMapType T_map>
72 : class InfFE;
73 : #endif
74 :
75 :
76 :
77 : /**
78 : * This class forms the foundation from which generic finite elements
79 : * may be derived. In the current implementation, the templated
80 : * derived class \p FE offers a wide variety of commonly used finite
81 : * element concepts. Check there for details. Use the \p
82 : * FEAbstract::build() method to create an object of any of the
83 : * derived classes.
84 : *
85 : * \note In the present design, the number of virtual members is kept
86 : * to a minimum for performance reasons, although this is not based on
87 : * rigorous profiling.
88 : *
89 : * All calls to static members of the \p FE classes should be
90 : * requested through the \p FEInterface. This interface class
91 : * approximates runtime polymorphism for the templated finite element
92 : * classes. Even internal library classes, like \p DofMap, request
93 : * the number of DOFs through this interface class. This approach
94 : * also enables the co-existence of various element-based schemes.
95 : *
96 : * \author Benjamin S. Kirk
97 : * \date 2002
98 : */
99 1738687 : class FEAbstract : public ReferenceCountedObject<FEAbstract>
100 : {
101 : protected:
102 :
103 : /**
104 : * Constructor. Optionally initializes required data
105 : * structures. Protected so that this base class
106 : * cannot be explicitly instantiated.
107 : */
108 : FEAbstract (const unsigned int dim,
109 : const FEType & fet);
110 :
111 : public:
112 :
113 : /**
114 : * Destructor.
115 : */
116 : virtual ~FEAbstract();
117 :
118 : /**
119 : * Builds a specific finite element type.
120 : *
121 : * \returns A std::unique_ptr<FEAbstract> to the FE object to prevent
122 : * memory leaks.
123 : */
124 : static std::unique_ptr<FEAbstract> build (const unsigned int dim,
125 : const FEType & type);
126 :
127 : /**
128 : * This is at the core of this class. Use this for each
129 : * new element in the mesh. Reinitializes the requested physical
130 : * element-dependent data based on the current element
131 : * \p elem. By default the element data are computed at the quadrature
132 : * points specified by the quadrature rule \p qrule, but any set
133 : * of points on the reference element may be specified in the optional
134 : * argument \p pts.
135 : *
136 : * \note The FE classes decide which data to initialize based on
137 : * which accessor functions such as \p get_phi() or \p get_d2phi()
138 : * have been called, so all such accessors should be called before
139 : * the first \p reinit().
140 : */
141 : virtual void reinit (const Elem * elem,
142 : const std::vector<Point> * const pts = nullptr,
143 : const std::vector<Real> * const weights = nullptr) = 0;
144 :
145 : /**
146 : * This re-computes the dual shape function coefficients using CUSTOMIZED qrule.
147 : * The dual shape coefficients are utilized when calculating dual shape functions.
148 : * This has not been implemented for InfFE
149 : */
150 0 : virtual void reinit_dual_shape_coeffs (const Elem * /*elem*/,
151 : const std::vector<Point> & /*pts*/,
152 : const std::vector<Real> & /*JxW*/)
153 : {
154 0 : libmesh_error_msg("Customized dual shape coefficient calculation has not been implemented for this FE type.");
155 : }
156 :
157 : /**
158 : * This re-computes the dual shape function coefficients using DEFAULT qrule.
159 : * This has not been implemented for InfFE
160 : */
161 0 : virtual void reinit_default_dual_shape_coeffs (const Elem * /*elem*/)
162 : {
163 0 : libmesh_error_msg("Default dual shape coefficient calculation has not been implemented for this FE type.");
164 : }
165 :
166 : /**
167 : * Reinitializes all the physical element-dependent data based on
168 : * the \p side of the element \p elem. The \p tolerance parameter
169 : * is passed to the involved call to \p inverse_map(). By default the
170 : * element data are computed at the quadrature points specified by the
171 : * quadrature rule \p qrule, but any set of points on the reference
172 : * \em side element may be specified in the optional argument \p pts.
173 : */
174 : virtual void reinit (const Elem * elem,
175 : const unsigned int side,
176 : const Real tolerance = TOLERANCE,
177 : const std::vector<Point> * const pts = nullptr,
178 : const std::vector<Real> * const weights = nullptr) = 0;
179 :
180 : /**
181 : * Reinitializes all the physical element-dependent data based on
182 : * the \p edge of the element \p elem. The \p tolerance parameter
183 : * is passed to the involved call to \p inverse_map(). By default the
184 : * element data are computed at the quadrature points specified by the
185 : * quadrature rule \p qrule, but any set of points on the reference
186 : * \em edge element may be specified in the optional argument \p pts.
187 : */
188 : virtual void edge_reinit (const Elem * elem,
189 : const unsigned int edge,
190 : const Real tolerance = TOLERANCE,
191 : const std::vector<Point> * pts = nullptr,
192 : const std::vector<Real> * weights = nullptr) = 0;
193 :
194 : /**
195 : * Computes the reference space quadrature points on the side of
196 : * an element based on the side quadrature points.
197 : */
198 : virtual void side_map (const Elem * elem,
199 : const Elem * side,
200 : const unsigned int s,
201 : const std::vector<Point> & reference_side_points,
202 : std::vector<Point> & reference_points) = 0;
203 :
204 : #ifdef LIBMESH_ENABLE_DEPRECATED
205 : /**
206 : * \returns \p true if the point p is located on the reference element
207 : * for element type t, false otherwise. Since we are doing floating
208 : * point comparisons here the parameter \p eps can be specified to
209 : * indicate a tolerance. For example, \f$ x \le 1 \f$ becomes
210 : * \f$ x \le 1 + \epsilon \f$.
211 : *
212 : * \deprecated This method overload does not support all finite
213 : * element types; e.g. the reference element for an arbitrary
214 : * polygon or polyhedron type may differ from element to element.
215 : * Use \p Elem::on_reference_element() instead.
216 : */
217 : static bool on_reference_element(const Point & p,
218 : const ElemType t,
219 : const Real eps = TOLERANCE);
220 : #endif // LIBMESH_ENABLE_DEPRECATED
221 :
222 : /**
223 : * \returns The reference space coordinates of \p nodes based on the
224 : * element type.
225 : */
226 : static void get_refspace_nodes(const ElemType t,
227 : std::vector<Point> & nodes);
228 :
229 :
230 : #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
231 : /**
232 : * Computes the nodal constraint contributions (for
233 : * non-conforming adapted meshes), using Lagrange geometry
234 : */
235 : static void compute_node_constraints (NodeConstraints & constraints,
236 : const Elem * elem);
237 : #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
238 :
239 : #ifdef LIBMESH_ENABLE_PERIODIC
240 :
241 : #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
242 : /**
243 : * Computes the node position constraint equation contributions (for
244 : * meshes with periodic boundary conditions)
245 : */
246 : static void compute_periodic_node_constraints (NodeConstraints & constraints,
247 : const PeriodicBoundaries & boundaries,
248 : const MeshBase & mesh,
249 : const PointLocatorBase * point_locator,
250 : const Elem * elem);
251 : #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
252 :
253 : #endif // LIBMESH_ENABLE_PERIODIC
254 :
255 : /**
256 : * \returns the dimension of this FE
257 : */
258 376976 : unsigned int get_dim() const
259 4122910 : { return dim; }
260 :
261 : /**
262 : * \returns nothing, but lets the FE know you're explicitly
263 : * prerequesting calculations. This is useful when you only want
264 : * the FE for n_quadrature_points, n_dofs_on_side, or other methods
265 : * that don't require shape function calculations, but you don't
266 : * want libMesh "backwards compatibility" mode to assume you've made
267 : * no prerequests and need to calculate everything.
268 : */
269 3190 : void get_nothing() const
270 1140494 : { calculate_nothing = true; }
271 :
272 : /**
273 : * \returns The \p xyz spatial locations of the quadrature
274 : * points on the element.
275 : *
276 : * It is overwritten by infinite elements since there
277 : * \p FEMap cannot be used to compute \p xyz.
278 : */
279 : virtual_for_inffe
280 2578587 : const std::vector<Point> & get_xyz() const
281 9208048 : { calculate_map = true; return this->_fe_map->get_xyz(); }
282 :
283 :
284 : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
285 : /**
286 : * This function is the variant of \p get_JxW() for \p InfFE.
287 : * Since J diverges there, a respectize decay-function must be
288 : * applied to obtain well-defined quantities.
289 : *
290 : * For FE, it is equivalent to the common \p get_JxW().
291 : */
292 1344 : virtual const std::vector<Real> & get_JxWxdecay_sq () const
293 1344 : { return get_JxW();}
294 : #endif
295 :
296 : /**
297 : * \returns The element Jacobian times the quadrature weight for
298 : * each quadrature point.
299 : *
300 : * For \p InfFE, use \p get_JxWxdecay_sq() instead.
301 : */
302 : virtual_for_inffe
303 12087941 : const std::vector<Real> & get_JxW() const
304 49031076 : { calculate_map = true; return this->_fe_map->get_JxW(); }
305 :
306 : /**
307 : * \returns The element tangents in xi-direction at the quadrature
308 : * points.
309 : */
310 : virtual_for_inffe
311 14 : const std::vector<RealGradient> & get_dxyzdxi() const
312 18 : { calculate_map = true; return this->_fe_map->get_dxyzdxi(); }
313 :
314 : /**
315 : * \returns The element tangents in eta-direction at the quadrature
316 : * points.
317 : */
318 : virtual_for_inffe
319 14 : const std::vector<RealGradient> & get_dxyzdeta() const
320 18 : { calculate_map = true; return this->_fe_map->get_dxyzdeta(); }
321 :
322 : /**
323 : * \returns The element tangents in zeta-direction at the quadrature
324 : * points.
325 : */
326 : virtual_for_inffe
327 0 : const std::vector<RealGradient> & get_dxyzdzeta() const
328 0 : { return _fe_map->get_dxyzdzeta(); }
329 :
330 : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
331 :
332 : /**
333 : * \returns The second partial derivatives in xi.
334 : */
335 : virtual_for_inffe
336 14 : const std::vector<RealGradient> & get_d2xyzdxi2() const
337 18 : { calculate_map = true; return this->_fe_map->get_d2xyzdxi2(); }
338 :
339 : /**
340 : * \returns The second partial derivatives in eta.
341 : */
342 : virtual_for_inffe
343 10 : const std::vector<RealGradient> & get_d2xyzdeta2() const
344 10 : { calculate_map = true; return this->_fe_map->get_d2xyzdeta2(); }
345 :
346 : /**
347 : * \returns The second partial derivatives in zeta.
348 : */
349 : virtual_for_inffe
350 0 : const std::vector<RealGradient> & get_d2xyzdzeta2() const
351 0 : { calculate_map = true; return this->_fe_map->get_d2xyzdzeta2(); }
352 :
353 : /**
354 : * \returns The second partial derivatives in xi-eta.
355 : */
356 : virtual_for_inffe
357 10 : const std::vector<RealGradient> & get_d2xyzdxideta() const
358 10 : { calculate_map = true; return this->_fe_map->get_d2xyzdxideta(); }
359 :
360 : /**
361 : * \returns The second partial derivatives in xi-zeta.
362 : */
363 : virtual_for_inffe
364 0 : const std::vector<RealGradient> & get_d2xyzdxidzeta() const
365 0 : { calculate_map = true; return this->_fe_map->get_d2xyzdxidzeta(); }
366 :
367 : /**
368 : * \returns The second partial derivatives in eta-zeta.
369 : */
370 : virtual_for_inffe
371 0 : const std::vector<RealGradient> & get_d2xyzdetadzeta() const
372 0 : { calculate_map = true; return this->_fe_map->get_d2xyzdetadzeta(); }
373 :
374 : #endif
375 :
376 : /**
377 : * \returns The dxi/dx entry in the transformation
378 : * matrix from physical to local coordinates.
379 : */
380 : virtual_for_inffe
381 2659 : const std::vector<Real> & get_dxidx() const
382 3537 : { calculate_map = true; return this->_fe_map->get_dxidx(); }
383 :
384 : /**
385 : * \returns The dxi/dy entry in the transformation
386 : * matrix from physical to local coordinates.
387 : */
388 : virtual_for_inffe
389 2659 : const std::vector<Real> & get_dxidy() const
390 3537 : { calculate_map = true; return this->_fe_map->get_dxidy(); }
391 :
392 : /**
393 : * \returns The dxi/dz entry in the transformation
394 : * matrix from physical to local coordinates.
395 : */
396 : virtual_for_inffe
397 2659 : const std::vector<Real> & get_dxidz() const
398 3537 : { calculate_map = true; return this->_fe_map->get_dxidz(); }
399 :
400 : /**
401 : * \returns The deta/dx entry in the transformation
402 : * matrix from physical to local coordinates.
403 : */
404 : virtual_for_inffe
405 2659 : const std::vector<Real> & get_detadx() const
406 3537 : { calculate_map = true; return this->_fe_map->get_detadx(); }
407 :
408 : /**
409 : * \returns The deta/dy entry in the transformation
410 : * matrix from physical to local coordinates.
411 : */
412 : virtual_for_inffe
413 2659 : const std::vector<Real> & get_detady() const
414 3537 : { calculate_map = true; return this->_fe_map->get_detady(); }
415 :
416 : /**
417 : * \returns The deta/dz entry in the transformation
418 : * matrix from physical to local coordinates.
419 : */
420 : virtual_for_inffe
421 2659 : const std::vector<Real> & get_detadz() const
422 3537 : { calculate_map = true; return this->_fe_map->get_detadz(); }
423 :
424 : /**
425 : * \returns The dzeta/dx entry in the transformation
426 : * matrix from physical to local coordinates.
427 : */
428 : virtual_for_inffe
429 0 : const std::vector<Real> & get_dzetadx() const
430 0 : { calculate_map = true; return this->_fe_map->get_dzetadx(); }
431 :
432 : /**
433 : * \returns The dzeta/dy entry in the transformation
434 : * matrix from physical to local coordinates.
435 : */
436 : virtual_for_inffe
437 0 : const std::vector<Real> & get_dzetady() const
438 0 : { calculate_map = true; return this->_fe_map->get_dzetady(); }
439 :
440 : /**
441 : * \returns The dzeta/dz entry in the transformation
442 : * matrix from physical to local coordinates.
443 : */
444 : virtual_for_inffe
445 0 : const std::vector<Real> & get_dzetadz() const
446 0 : { calculate_map = true; return this->_fe_map->get_dzetadz(); }
447 :
448 : /**
449 : * \returns The tangent vectors for face integration.
450 : */
451 : virtual_for_inffe
452 2 : const std::vector<std::vector<Point>> & get_tangents() const
453 2 : { calculate_map = true; return this->_fe_map->get_tangents(); }
454 :
455 : /**
456 : * \returns The outward pointing normal vectors for face integration.
457 : */
458 : virtual_for_inffe
459 669158 : const std::vector<Point> & get_normals() const
460 951616 : { calculate_map = true; return this->_fe_map->get_normals(); }
461 :
462 : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
463 : /**
464 : * \returns The curvatures for use in face integration.
465 : */
466 : virtual_for_inffe
467 0 : const std::vector<Real> & get_curvatures() const
468 0 : { calculate_map = true; return this->_fe_map->get_curvatures();}
469 :
470 : #endif
471 :
472 : /**
473 : * Provides the class with the quadrature rule. Implement
474 : * this in derived classes.
475 : */
476 : virtual void attach_quadrature_rule (QBase * q) = 0;
477 :
478 : /**
479 : * \returns The total number of approximation shape functions
480 : * for the current element. Useful during matrix assembly.
481 : * Implement this in derived classes.
482 : */
483 : virtual unsigned int n_shape_functions () const = 0;
484 :
485 : /**
486 : * \returns The total number of quadrature points with which this
487 : * was last reinitialized. Useful during matrix assembly.
488 : */
489 : virtual unsigned int n_quadrature_points () const;
490 :
491 : /**
492 : * \returns The element that the current shape functions have been
493 : * calculated for. Useful in determining when shape functions must
494 : * be recomputed.
495 : */
496 : const Elem * get_elem() const { return _elem; }
497 :
498 : /**
499 : * \returns The element type that the current shape functions
500 : * have been calculated for, or \p INVALID_ELEM if no such element
501 : * exists. Useful in determining when shape functions must be
502 : * recomputed.
503 : *
504 : * This is generally redundant with _elem->type(), but must be
505 : * cached separately for cases (such as internal FE use in
506 : * QComposite) where _elem might be a dangling pointer to a
507 : * temporary.
508 : */
509 132150294 : ElemType get_type() const { return _elem_type; }
510 :
511 : /**
512 : * \returns The p refinement level that the current shape
513 : * functions have been calculated for.
514 : */
515 : unsigned int get_p_level() const { return _p_level; }
516 :
517 : /**
518 : * \returns The FE Type (approximation order and family) of the finite element.
519 : */
520 244546265 : FEType get_fe_type() const { return fe_type; }
521 :
522 : /**
523 : * \returns The approximation order of the finite element.
524 : */
525 3663995 : Order get_order() const
526 47882383 : { return fe_type.order + _p_level; }
527 :
528 : /**
529 : * Sets the *base* FE order of the finite element.
530 : */
531 29590 : void set_fe_order(int new_order) { fe_type.order = new_order; }
532 :
533 : /**
534 : * \returns The continuity level of the finite element.
535 : */
536 : virtual FEContinuity get_continuity() const = 0;
537 :
538 : /**
539 : * \returns \p true if the finite element's higher order shape functions are
540 : * hierarchic
541 : */
542 : virtual bool is_hierarchic() const = 0;
543 :
544 : /**
545 : * \returns The finite element family of this element.
546 : */
547 614477 : FEFamily get_family() const { return fe_type.family; }
548 :
549 : /**
550 : * \returns The mapping object
551 : *
552 : * \note for InfFE, this gives a useless object.
553 : */
554 81695088 : const FEMap & get_fe_map() const { return *_fe_map.get(); }
555 17936 : FEMap & get_fe_map() { return *_fe_map.get(); }
556 :
557 : /**
558 : * Prints the Jacobian times the weight for each quadrature point.
559 : */
560 : void print_JxW(std::ostream & os) const;
561 :
562 : /**
563 : * Prints the value of each shape function at each quadrature point.
564 : * Implement in derived class since this depends on whether the element
565 : * is vector-valued or not.
566 : */
567 : virtual void print_phi(std::ostream & os) const =0;
568 : virtual void print_dual_phi(std::ostream & os) const =0;
569 :
570 : /**
571 : * Prints the value of each shape function's derivative
572 : * at each quadrature point. Implement in derived class since this
573 : * depends on whether the element is vector-valued or not.
574 : */
575 : virtual void print_dphi(std::ostream & os) const =0;
576 : virtual void print_dual_dphi(std::ostream & os) const =0;
577 :
578 : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
579 :
580 : /**
581 : * Prints the value of each shape function's second derivatives
582 : * at each quadrature point. Implement in derived class since this
583 : * depends on whether the element is vector-valued or not.
584 : */
585 : virtual void print_d2phi(std::ostream & os) const =0;
586 : virtual void print_dual_d2phi(std::ostream & os) const =0;
587 :
588 : #endif
589 :
590 : /**
591 : * Prints the spatial location of each quadrature point
592 : * (on the physical element).
593 : */
594 : void print_xyz(std::ostream & os) const;
595 :
596 : /**
597 : * Prints all the relevant information about the current element.
598 : */
599 : void print_info(std::ostream & os) const;
600 :
601 : /**
602 : * Same as above, but allows you to print to a stream.
603 : */
604 : friend std::ostream & operator << (std::ostream & os, const FEAbstract & fe);
605 :
606 : /**
607 : * request phi calculations
608 : */
609 : virtual void request_phi() const = 0;
610 : virtual void request_dual_phi() const = 0;
611 :
612 : /**
613 : * request dphi calculations
614 : */
615 : virtual void request_dphi() const = 0;
616 : virtual void request_dual_dphi() const = 0;
617 :
618 : /**
619 : * set calculate_dual as needed
620 : */
621 : void set_calculate_dual(const bool val){calculate_dual = val; }
622 :
623 : /**
624 : * set calculate_default_dual_coeff as needed
625 : */
626 6348 : void set_calculate_default_dual_coeff(const bool val){calculate_default_dual_coeff = val; }
627 :
628 : /**
629 : * Indicate whether to add p-refinement levels in init/reinit methods
630 : */
631 15297148 : void add_p_level_in_reinit(bool value) { _add_p_level_in_reinit = value; }
632 :
633 : /**
634 : * Whether to add p-refinement levels in init/reinit methods
635 : */
636 4183357 : bool add_p_level_in_reinit() const { return _add_p_level_in_reinit; }
637 :
638 : protected:
639 :
640 : /**
641 : * After having updated the jacobian and the transformation
642 : * from local to global coordinates in \p FEMap::compute_map(),
643 : * the first derivatives of the shape functions are
644 : * transformed to global coordinates, giving \p dphi,
645 : * \p dphidx, \p dphidy, and \p dphidz. This method
646 : * should rarely be re-defined in derived classes, but
647 : * still should be usable for children. Therefore, keep
648 : * it protected. This needs to be implemented in the
649 : * derived class since this function depends on whether
650 : * the shape functions are vector-valued or not.
651 : */
652 : virtual void compute_shape_functions(const Elem *, const std::vector<Point> & ) =0;
653 :
654 : std::unique_ptr<FEMap> _fe_map;
655 :
656 :
657 : /**
658 : * The dimensionality of the object
659 : */
660 : const unsigned int dim;
661 :
662 : /**
663 : * Have calculations with this object already been started?
664 : * Then all get_* functions should already have been called.
665 : */
666 : mutable bool calculations_started;
667 :
668 : /**
669 : * Are we calculating dual basis?
670 : */
671 : mutable bool calculate_dual;
672 :
673 : /**
674 : * Are we calculating the coefficient for the dual basis using the default qrule?
675 : */
676 : mutable bool calculate_default_dual_coeff;
677 :
678 : /**
679 : * Are we potentially deliberately calculating nothing?
680 : */
681 : mutable bool calculate_nothing;
682 :
683 : /**
684 : * Are we calculating mapping functions?
685 : */
686 : mutable bool calculate_map;
687 :
688 : /**
689 : * Should we calculate shape functions?
690 : */
691 : mutable bool calculate_phi;
692 :
693 : /**
694 : * Should we calculate shape function gradients?
695 : */
696 : mutable bool calculate_dphi;
697 :
698 : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
699 : /**
700 : * Should we calculate shape function hessians?
701 : */
702 : mutable bool calculate_d2phi;
703 : #else
704 : // Otherwise several interfaces need to be redone.
705 : const bool calculate_d2phi=false;
706 :
707 : #endif
708 :
709 : /**
710 : * Should we calculate shape function curls?
711 : */
712 : mutable bool calculate_curl_phi;
713 :
714 : /**
715 : * Should we calculate shape function divergences?
716 : */
717 : mutable bool calculate_div_phi;
718 :
719 : /**
720 : * Should we calculate reference shape function gradients?
721 : */
722 : mutable bool calculate_dphiref;
723 :
724 :
725 : /**
726 : * The finite element type for this object.
727 : *
728 : * \note This should be constant for the object.
729 : */
730 : FEType fe_type;
731 :
732 : /**
733 : * The element type the current data structures were set up for.
734 : */
735 : ElemType _elem_type;
736 :
737 : /**
738 : * The element the current data structures were set up for.
739 : */
740 : const Elem * _elem;
741 :
742 : /**
743 : * The element p-refinement level the current data structures are
744 : * set up for. Note that this is different from \p _p_level which
745 : * is the p-refinement level this finite elment object is operating
746 : * at, e.g. how many dofs per elem, etc. On the other hand, this data
747 : * member can indicate things like the order of the quadrature rule.
748 : * We will use this primarily to determine whether cached data is still
749 : * valid
750 : */
751 : unsigned int _elem_p_level;
752 :
753 : /**
754 : * The p refinement level the current data structures are
755 : * set up for.
756 : */
757 : unsigned int _p_level;
758 :
759 : /**
760 : * A pointer to the quadrature rule employed
761 : */
762 : QBase * qrule;
763 :
764 : /**
765 : * A flag indicating if current data structures
766 : * correspond to quadrature rule points
767 : */
768 : bool shapes_on_quadrature;
769 :
770 : /**
771 : * The total number of quadrature points
772 : * for the current configuration
773 : */
774 : unsigned int _n_total_qp;
775 :
776 : /**
777 : * \returns \p true when the shape functions (for
778 : * this \p FEFamily) depend on the particular
779 : * element, and therefore needs to be re-initialized
780 : * for each new element. \p false otherwise.
781 : */
782 : virtual bool shapes_need_reinit() const = 0;
783 :
784 : /**
785 : * Whether to add p-refinement levels in init/reinit methods
786 : */
787 : bool _add_p_level_in_reinit;
788 : };
789 :
790 : } // namespace libMesh
791 :
792 : #endif // LIBMESH_FE_ABSTRACT_H
|