v0.15.5
Loading...
Searching...
No Matches
HODataOperators.hpp
Go to the documentation of this file.
1/** \file HODataOperators.hpp
2 * \brief High-order geometry operators for finite element computations
3 *
4 * This file provides operators for managing high-order (curved) geometry in
5 * finite element analysis. These operators handle geometric transformations,
6 * coordinate mappings, and basis function modifications required when elements
7 * have curved boundaries or use high-order shape functions.
8 *
9 * ## Main Functionality:
10 *
11 * **Jacobian Calculations**: Compute transformation matrices between reference
12 * and physical coordinates for curved elements (OpCalculateHOJacForVolume,
13 * OpCalculateHOJacForFace, OpGetHOTangentsOnEdge, OpGetHONormalsOnFace)
14 *
15 * **Coordinate Transformations**: Calculate physical coordinates at integration
16 * points using high-order approximations (OpCalculateHOCoords)
17 *
18 * **Basis Function Transformations**: Apply Piola transforms and inverse Jacobian
19 * operations to basis functions for H1, Hdiv, and Hcurl spaces
20 * (OpSetHOContravariantPiolaTransform, OpSetHOCovariantPiolaTransform)
21 *
22 * **Integration Weight Corrections**: Adjust integration weights to account for
23 * geometric distortions in curved elements (OpSetHOWeights, OpSetHOWeightsOnFace)
24 *
25 * **Pipeline Management**: AddHOOps template specializations automatically add
26 * appropriate HO operators to finite element pipelines based on element
27 * dimension and problem type
28 *
29 * ## Usage Pattern:
30 * 1. Use AddHOOps<FE_DIM, PROBLEM_DIM, SPACE_DIM>::add() to automatically
31 * add required HO operators to your finite element pipeline
32 * 2. Individual operators can be used directly for specialized applications
33 * 3. Operators handle both internal computations and external data access
34 * via shared pointers to Jacobian matrices and determinants
35 *
36 * ## Key Benefits:
37 * - Accurate integration on curved domains
38 * - Proper handling of geometric nonlinearity
39 * - Seamless integration with MoFEM pipeline system
40 * - Support for mixed finite element spaces (H1, Hdiv, Hcurl)
41 *
42 * @note Essential for problems involving curved boundaries, contact mechanics,
43 * fluid-structure interaction, and any application requiring geometric
44 * accuracy beyond linear approximation.
45 */
46
47#ifndef __HO_DATA_OPERATORS_HPP__
48#define __HO_DATA_OPERATORS_HPP__
49
50namespace MoFEM {
51
52/**
53 * @brief Calculate Jacobian on Hex or other volume elements which are not simplex
54 *
55 * This structure calculates the Jacobian matrix for high-order volume elements
56 * using geometrical coordinates of the element rather than field data. It's
57 * specifically designed for hexahedral and other non-simplex volume elements.
58 *
59 * @note Use OpCalculateVectorFieldGradient to calculate Jacobian from field data.
60 */
63
64 /**
65 * @brief Constructor for HO Jacobian calculation on volumes
66 *
67 * @param jac_ptr Shared pointer to matrix for storing calculated Jacobian values
68 */
69 OpCalculateHOJacForVolume(boost::shared_ptr<MatrixDouble> jac_ptr);
70
71 MoFEMErrorCode doWork(int side, EntityType type,
73
74private:
75 boost::shared_ptr<MatrixDouble> jacPtr;
76};
77
78/** \deprecated use OpCalculateHOJacForVolume
79 */
81
82/**
83 * @brief Calculate high-order coordinates at Gauss points
84 *
85 * This template structure computes high-order coordinate values at integration
86 * (Gauss) points using field approximations. It supports different field
87 * dimensions and is commonly used in high-order finite element methods.
88 *
89 * @tparam FIELD_DIM Dimension of the coordinate field (default: 3)
90 */
91template <int FIELD_DIM = 3>
93
94 /**
95 * @brief Constructor for HO coordinates calculation
96 *
97 * @param field_name Name of the field containing coordinate information
98 */
101
102 MoFEMErrorCode doWork(int side, EntityType type,
104};
105
106/**
107 * @deprecated This class should be DIM = 3 specialization when default
108 * parameter is removed
109 *
110 */
118
119/**
120 * \brief Set inverse jacobian to base functions
121 *
122 * \deprecated Version with default variant DIM = 3 is deprecated, keep for
123 * back compatibility. Should be removed in future. Use of default variant make
124 * code implicit, what can be source of some hidden error. Explict interface is
125 * better, when user see and control outcome, and is aware of existing variants.
126 *
127 */
128template <int DIM = 3>
130 using OpSetHOInvJacToScalarBasesImpl::OpSetHOInvJacToScalarBasesImpl;
131};
132
133template <>
135 : public OpSetInvJacSpaceForFaceImpl<2, 1> {
136
137 using OpSetInvJacSpaceForFaceImpl<2, 1>::OpSetInvJacSpaceForFaceImpl;
138};
139
140/**
141 * @brief Transform local reference derivatives of shape functions to global derivatives
142 *
143 * This structure transforms derivatives of shape functions from local reference
144 * coordinates to global coordinates when higher-order geometry is used. It's
145 * essential for vector-based finite element spaces requiring coordinate transformations.
146 *
147 * @ingroup mofem_forces_and_sources
148 */
150
151 /**
152 * @brief Constructor for HO inverse Jacobian transformation for vector bases
153 *
154 * @param space Field space specification for the transformation
155 * @param inv_jac_ptr Shared pointer to matrix containing inverse Jacobian data
156 */
158 boost::shared_ptr<MatrixDouble> inv_jac_ptr)
159 : ForcesAndSourcesCore::UserDataOperator(space), invJacPtr(inv_jac_ptr) { if (!invJacPtr)
161 "Pointer for invJacPtr not allocated");
162
163 doVertices = false;
164 if (space == HDIV)
165 doEdges = false;
166 }
167
168
169 MoFEMErrorCode doWork(int side, EntityType type,
171
172private:
173 boost::shared_ptr<MatrixDouble> invJacPtr;
176};
177
178/**
179 * @brief Modify integration weights on face to take into account higher-order geometry
180 *
181 * This structure adjusts integration weights for face elements when higher-order
182 * geometry is present. It accounts for geometric distortions introduced by
183 * curved boundaries and high-order shape functions.
184 *
185 * @ingroup mofem_forces_and_sources_tri_element
186 */
189
190 /**
191 * @brief Default constructor for HO weights on face
192 */
195
196 MoFEMErrorCode doWork(int side, EntityType type,
198};
199
200/**
201 * @brief Modify integration weights on edge to take into account higher-order geometry
202 *
203 * This structure adjusts integration weights for edge elements when higher-order
204 * geometry is present. It accounts for geometric distortions introduced by
205 * curved edges and high-order shape functions along the edge.
206 *
207 * @ingroup mofem_forces_and_sources_tri_element
208 */
211
212 /**
213 * @brief Default constructor for HO weights on edge
214 */
217
218 MoFEMErrorCode doWork(int side, EntityType type,
220};
221
222template <int SPACE_DIM>
224
228
232
233/**
234 * @brief Set integration weights for higher-order elements
235 *
236 * This structure sets integration weights by computing the determinant of the
237 * Jacobian matrix for higher-order elements. It ensures proper integration
238 * when dealing with curved geometries and high-order shape functions.
239 */
241
242 /**
243 * @brief Constructor for HO weights calculation
244 *
245 * @param det_ptr Shared pointer to vector for storing determinant values
246 */
247 OpSetHOWeights(boost::shared_ptr<VectorDouble> det_ptr)
249 detPtr(det_ptr) {
250 if (!detPtr)
252 "Pointer for detPtr not allocated");
253 }
254
255 MoFEMErrorCode doWork(int side, EntityType type,
257
258private:
259 boost::shared_ptr<VectorDouble> detPtr;
260};
261
262/**
263 * @brief Apply contravariant (Piola) transformation to Hdiv space for HO geometry
264 *
265 * This structure applies the contravariant Piola transformation to basis functions
266 * in Hdiv spaces when higher-order geometry is present. This transformation is
267 * essential for preserving the divergence properties of vector fields across
268 * element boundaries in curved geometries.
269 *
270 * @ingroup mofem_forces_and_sources
271 */
274
275 /**
276 * @brief Constructor for contravariant Piola transformation
277 *
278 * @param space Field space specification (typically HDIV)
279 * @param det_ptr Shared pointer to determinant values for transformation
280 * @param jac_ptr Shared pointer to Jacobian matrix for transformation
281 */
283 boost::shared_ptr<VectorDouble> det_ptr,
284 boost::shared_ptr<MatrixDouble> jac_ptr)
286 jacPtr(jac_ptr) {
287 doVertices = false;
288 if (space == HDIV)
289 doEdges = false;
290 }
291
292 MoFEMErrorCode doWork(int side, EntityType type,
294
295private:
296 boost::shared_ptr<VectorDouble> detPtr;
297 boost::shared_ptr<MatrixDouble> jacPtr;
298
301};
302
303/**
304 * @brief Apply covariant (Piola) transformation to Hcurl space for HO geometry
305 *
306 * This structure applies the covariant Piola transformation to basis functions
307 * in Hcurl spaces when higher-order geometry is present. This transformation
308 * preserves the curl properties of vector fields and maintains tangential
309 * continuity across element boundaries in curved geometries.
310 */
313
314 /**
315 * @brief Constructor for covariant Piola transformation
316 *
317 * @param space Field space specification (typically HCURL)
318 * @param jac_inv_ptr Shared pointer to inverse Jacobian matrix for transformation
319 */
321 boost::shared_ptr<MatrixDouble> jac_inv_ptr)
323 jacInvPtr(jac_inv_ptr) {
324 doVertices = false;
325 if (space == HDIV)
326 doEdges = false;
327 if (!jacInvPtr)
329 "Pointer for jacPtr not allocated");
330 }
331
332 MoFEMErrorCode doWork(int side, EntityType type,
334
335private:
336 boost::shared_ptr<MatrixDouble> jacInvPtr;
337
340};
341
342/** \brief Calculate jacobian for face element
343
344 It is assumed that face element is XY plane. Applied
345 only for 2d problems and 2d problems embedded in 3d space
346
347 \note If you push operators for HO normal befor this operator, HO geometry is
348 taken into account when you calculate jacobian.
349
350*/
351template <int DIM> struct OpCalculateHOJacForFaceImpl;
352
353template <>
356
357 OpCalculateHOJacForFaceImpl(boost::shared_ptr<MatrixDouble> jac_ptr);
358
359 MoFEMErrorCode doWork(int side, EntityType type,
361
362protected:
363 boost::shared_ptr<MatrixDouble> jacPtr;
364};
365
366template <>
368
369 using OpCalculateHOJacForFaceImpl<2>::OpCalculateHOJacForFaceImpl;
370
371 MoFEMErrorCode doWork(int side, EntityType type,
373};
374
377
378template <int DIM> struct OpCalculateHOJac;
379
383
384template <> struct OpCalculateHOJac<2> : public OpCalculateHOJacForFaceImpl<2> {
385 using OpCalculateHOJacForFaceImpl<2>::OpCalculateHOJacForFaceImpl;
386};
387
388/**
389 * @brief Calculate normal vectors at Gauss points of face elements
390 *
391 * This template structure computes normal vectors at integration points for
392 * face elements using high-order geometry approximation. It's essential for
393 * boundary conditions, surface integrals, and flux calculations in finite
394 * element methods.
395 *
396 * @tparam FIELD_DIM Dimension of the field for normal calculation (default: 3)
397 *
398 * @ingroup mofem_forces_and_sources
399 */
400template <int FIELD_DIM = 3>
403
405
406 /**
407 * @brief Constructor for HO normal vectors calculation on faces
408 *
409 * @param field_name Field name where normal vectors will be stored
410 * @param add_field If true, add to existing field values; if false, overwrite (default: false)
411 */
412 OpGetHONormalsOnFace(std::string field_name, bool add_field = false)
413 : OP(field_name, OPROW), addField(add_field) {}
414
416 boost::shared_ptr<MatrixDouble> tangent1_at_pts,
417 boost::shared_ptr<MatrixDouble> tangent2_at_pts,
418 boost::shared_ptr<MatrixDouble> normals_at_pts,
419 bool add_field = false)
420 : OP(field_name, OPROW), tangent1AtPts(tangent1_at_pts),
421 tangent2AtPts(tangent2_at_pts), normalsAtPts(normals_at_pts),
422 addField(add_field) {}
423
424 MoFEMErrorCode doWork(int side, EntityType type,
426
427private:
431
435
439
440 boost::shared_ptr<MatrixDouble> tangent1AtPts;
441 boost::shared_ptr<MatrixDouble> tangent2AtPts;
442 boost::shared_ptr<MatrixDouble> normalsAtPts;
443
444 bool addField = false; ///< if true add field values, do not overwrite
445};
446
447/**
448 * @brief Transform Hdiv base fluxes from reference element to physical face in 3D
449 *
450 * This structure applies contravariant Piola transformation to Hdiv basis
451 * functions on 3D face elements. It transforms flux values from reference
452 * coordinates to physical coordinates while preserving divergence properties.
453 *
454 * @note Matrix which keeps normal vectors is assumed to have three columns,
455 * and number of rows should be equal to number of integration points.
456 *
457 * @ingroup mofem_forces_and_sources
458 */
461
462 /**
463 * @brief Constructor for contravariant Piola transformation on 3D faces
464 *
465 * @param space Field space specification (typically HDIV)
466 * @param normals_at_gauss_pts Shared pointer to matrix containing normal vectors at integration points (optional)
467 */
469 const FieldSpace space,
470 boost::shared_ptr<MatrixDouble> normals_at_gauss_pts = nullptr)
472 normalsAtGaussPts(normals_at_gauss_pts) {}
473
474 MoFEMErrorCode doWork(int side, EntityType type,
476
477private:
478 boost::shared_ptr<MatrixDouble> normalsAtGaussPts;
479};
480
481/**
482 * @brief Transform Hcurl base functions from reference element to physical edge in 3D
483 *
484 * This structure applies contravariant Piola transformation to Hcurl basis
485 * functions on 3D edge elements. It transforms curl-conforming basis functions
486 * from reference coordinates to physical coordinates while preserving tangential
487 * continuity across element boundaries.
488 *
489 * @ingroup mofem_forces_and_sources
490 */
493
494 /**
495 * @brief Constructor for contravariant Piola transformation on 3D edges
496 *
497 * @param space Field space specification (default: HCURL)
498 * @param tangent_at_pts Shared pointer to matrix containing tangent vectors at integration points (optional)
499 */
501 const FieldSpace space = HCURL,
502 boost::shared_ptr<MatrixDouble> tangent_at_pts = nullptr)
504 tangentAtGaussPts(tangent_at_pts) {}
505
506 MoFEMErrorCode doWork(int side, EntityType type,
508
509private:
510 boost::shared_ptr<MatrixDouble> tangentAtGaussPts;
511};
512
513/**
514 * @brief Transform Hcurl base functions from reference element to physical face in 3D
515 *
516 * This structure applies covariant Piola transformation to Hcurl basis functions
517 * on 3D face elements. It transforms curl-conforming basis functions from
518 * reference coordinates to physical coordinates using normal and tangent vectors,
519 * preserving the curl properties of the field.
520 *
521 * @ingroup mofem_forces_and_sources
522 */
525
526 /**
527 * @brief Constructor for covariant Piola transformation on 3D faces
528 *
529 * @param space Field space specification (typically HCURL)
530 * @param normals_at_pts Shared pointer to matrix containing normal vectors at integration points (optional)
531 * @param tangent1_at_pts Shared pointer to matrix containing first tangent vectors at integration points (optional)
532 * @param tangent2_at_pts Shared pointer to matrix containing second tangent vectors at integration points (optional)
533 */
535 const FieldSpace space,
536 boost::shared_ptr<MatrixDouble> normals_at_pts = nullptr,
537 boost::shared_ptr<MatrixDouble> tangent1_at_pts = nullptr,
538 boost::shared_ptr<MatrixDouble> tangent2_at_pts = nullptr)
540 normalsAtPts(normals_at_pts), tangent1AtPts(tangent1_at_pts),
541 tangent2AtPts(tangent2_at_pts) {
542 if (normals_at_pts || tangent1_at_pts || tangent2_at_pts)
543 if (normals_at_pts && tangent1_at_pts && tangent2_at_pts)
545 "All elements in constructor have to set pointer");
546 }
547
548 MoFEMErrorCode doWork(int side, EntityType type,
550
551private:
552 boost::shared_ptr<MatrixDouble> normalsAtPts;
553 boost::shared_ptr<MatrixDouble> tangent1AtPts;
554 boost::shared_ptr<MatrixDouble> tangent2AtPts;
555
558};
559
560/**
561 * @brief Calculate tangent vector on edge from HO geometry approximation
562 *
563 * This template structure computes tangent vectors along edges using high-order
564 * geometry approximation. It extracts tangent information at integration points
565 * and stores the results for further processing in finite element calculations.
566 *
567 * @tparam FIELD_DIM Dimension of the field (default: 3)
568 *
569 * @ingroup mofem_forces_and_sources
570 */
571template <int FIELD_DIM = 3>
574
575 /**
576 * @brief Constructor for HO tangents calculation on edges
577 *
578 * @param field_name Name of the field used for tangent calculation
579 * @param tangents_at_pts Shared pointer to matrix for storing calculated tangents (optional)
580 */
582 std::string field_name,
583 boost::shared_ptr<MatrixDouble> tangents_at_pts = nullptr)
585 tangentsAtPts(tangents_at_pts) {}
586
587 MoFEMErrorCode doWork(int side, EntityType type,
589
590private:
591 boost::shared_ptr<MatrixDouble> tangentsAtPts;
592};
593
594/**
595 * @brief Scale base functions by inverses of measure of element
596 *
597 * @tparam OP
598 */
601
603
605 const FieldSpace space, const FieldApproximationBase base,
606 boost::shared_ptr<VectorDouble> det_jac_ptr,
607 boost::shared_ptr<double> scale_det_ptr = nullptr);
608
609 MoFEMErrorCode doWork(int side, EntityType type,
611
612private:
615 boost::shared_ptr<VectorDouble> detJacPtr;
616 boost::shared_ptr<double> scaleDetPtr = nullptr;
617};
618
619/**
620 * @brief Add operators pushing bases from local to physical configuration
621 *
622 * @tparam FE_DIM dimension of element
623 * @tparam PROBLEM_DIM problem dimension
624 * @tparam SPACE_DIM space dimension
625 */
626template <int FE_DIM, int PROBLEM_DIM, int SPACE_DIM> struct AddHOOps;
627
628/**
629 * @brief Specialization for 2D face elements in 2D problems with 2D space
630 *
631 * This specialization adds high-order operators for 2D face elements operating
632 * in 2D problems within 2D coordinate space. Commonly used for planar face
633 * elements in 2D finite element analysis.
634 */
635template <> struct AddHOOps<2, 2, 2> {
636 AddHOOps() = delete;
637
638 /**
639 * @brief Add high-order operators to the pipeline for 2D face elements
640 *
641 * @param pipeline Pipeline to add operators to
642 * @param spaces Vector of field spaces to be handled
643 * @param geom_field_name Name of the geometry field (default: empty string)
644 * @param jac Shared pointer to Jacobian matrix. If provided, values will be set by this function.
645 * If null, Jacobian will be handled internally.
646 * @param det Shared pointer to determinant vector. If provided, values will be set by this function.
647 * If null, determinant will be handled internally.
648 * @param inv_jac Shared pointer to inverse Jacobian matrix. If provided, values will be set by this function.
649 * If null, inverse Jacobian will be handled internally.
650 * @return MoFEMErrorCode Error code indicating success or failure
651 */
652 static MoFEMErrorCode
653 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
654 std::vector<FieldSpace> spaces, std::string geom_field_name = "",
655 boost::shared_ptr<MatrixDouble> jac = nullptr,
656 boost::shared_ptr<VectorDouble> det = nullptr,
657 boost::shared_ptr<MatrixDouble> inv_jac = nullptr);
658};
659
660/**
661 * @brief Specialization for 2D face elements in 2D problems embedded in 3D space
662 *
663 * This specialization adds high-order operators for 2D face elements operating
664 * in 2D problems but embedded within 3D coordinate space. Typically used for
665 * surface elements or membranes in 3D environments.
666 */
667template <> struct AddHOOps<2, 2, 3> {
668 AddHOOps() = delete;
669
670 /**
671 * @brief Add high-order operators to the pipeline for 2D face elements embedded in 3D
672 *
673 * @param pipeline Pipeline to add operators to
674 * @param spaces Vector of field spaces to be handled
675 * @param geom_field_name Name of the geometry field (default: empty string)
676 * @param jac Shared pointer to Jacobian matrix. If provided, values will be set by this function.
677 * If null, Jacobian will be handled internally.
678 * @param det Shared pointer to determinant vector. If provided, values will be set by this function.
679 * If null, determinant will be handled internally.
680 * @param inv_jac Shared pointer to inverse Jacobian matrix. If provided, values will be set by this function.
681 * If null, inverse Jacobian will be handled internally.
682 * @return MoFEMErrorCode Error code indicating success or failure
683 */
684 static MoFEMErrorCode
685 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
686 std::vector<FieldSpace> spaces, std::string geom_field_name = "",
687 boost::shared_ptr<MatrixDouble> jac = nullptr,
688 boost::shared_ptr<VectorDouble> det = nullptr,
689 boost::shared_ptr<MatrixDouble> inv_jac = nullptr);
690};
691
692/**
693 * @brief Specialization for 1D edge elements in 2D problems with 2D space
694 *
695 * This specialization adds high-order operators for 1D edge elements operating
696 * in 2D problems within 2D coordinate space. Used for edge-based computations
697 * such as boundary conditions or line integrals in 2D finite element analysis.
698 */
699template <> struct AddHOOps<1, 2, 2> {
700 AddHOOps() = delete;
701
702 /**
703 * @brief Add high-order operators to the pipeline for 1D edge elements in 2D
704 *
705 * @param pipeline Pipeline to add operators to
706 * @param spaces Vector of field spaces to be handled
707 * @param geom_field_name Name of the geometry field (default: empty string)
708 * @return MoFEMErrorCode Error code indicating success or failure
709 *
710 * @note This specialization handles Jacobian, determinant, and inverse Jacobian internally.
711 */
712 static MoFEMErrorCode
713 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
714 std::vector<FieldSpace> spaces, std::string geom_field_name = "");
715};
716
717/**
718 * @brief Specialization for 1D edge elements in 3D problems with 3D space
719 *
720 * This specialization adds high-order operators for 1D edge elements operating
721 * in 3D problems within 3D coordinate space. Used for edge-based computations
722 * such as line integrals, boundary conditions, or wire-like structures in 3D
723 * finite element analysis.
724 */
725template <> struct AddHOOps<1, 3, 3> {
726 AddHOOps() = delete;
727
728 /**
729 * @brief Add high-order operators to the pipeline for 1D edge elements in 3D
730 *
731 * @param pipeline Pipeline to add operators to
732 * @param space Vector of field spaces to be handled
733 * @param geom_field_name Name of the geometry field (default: empty string)
734 * @return MoFEMErrorCode Error code indicating success or failure
735 *
736 * @note This specialization handles Jacobian, determinant, and inverse Jacobian internally.
737 */
738 static MoFEMErrorCode
739 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
740 std::vector<FieldSpace> space, std::string geom_field_name = "");
741};
742
743/**
744 * @brief Specialization for 2D face elements in 3D problems with 3D space
745 *
746 * This specialization adds high-order operators for 2D face elements operating
747 * in 3D problems within 3D coordinate space. Commonly used for surface elements,
748 * boundary conditions, membranes, or shell structures in 3D finite element
749 * analysis.
750 */
751template <> struct AddHOOps<2, 3, 3> {
752 AddHOOps() = delete;
753
754 /**
755 * @brief Add high-order operators to the pipeline for 2D face elements in 3D
756 *
757 * @param pipeline Pipeline to add operators to
758 * @param space Vector of field spaces to be handled
759 * @param geom_field_name Name of the geometry field (default: empty string)
760 * @return MoFEMErrorCode Error code indicating success or failure
761 *
762 * @note This specialization handles Jacobian, determinant, and inverse Jacobian internally.
763 */
764 static MoFEMErrorCode
765 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
766 std::vector<FieldSpace> space, std::string geom_field_name = "");
767};
768
769/**
770 * @brief Specialization for 3D volume elements in 3D problems with 3D space
771 *
772 * This specialization adds high-order operators for 3D volume elements operating
773 * in 3D problems within 3D coordinate space. This is the most common case for
774 * solid mechanics, heat transfer, and other 3D finite element applications
775 * involving volumetric elements like tetrahedra, hexahedra, and prisms.
776 */
777template <> struct AddHOOps<3, 3, 3> {
778 AddHOOps() = delete;
779
780 /**
781 * @brief Add high-order operators to the pipeline for 3D volume elements
782 *
783 * @param pipeline Pipeline to add operators to
784 * @param space Vector of field spaces to be handled
785 * @param geom_field_name Name of the geometry field (default: empty string)
786 * @param jac Shared pointer to Jacobian matrix. If provided, values will be set by this function.
787 * If null, Jacobian will be handled internally.
788 * @param det Shared pointer to determinant vector. If provided, values will be set by this function.
789 * If null, determinant will be handled internally.
790 * @param inv_jac Shared pointer to inverse Jacobian matrix. If provided, values will be set by this function.
791 * If null, inverse Jacobian will be handled internally.
792 * @return MoFEMErrorCode Error code indicating success or failure
793 */
794 static MoFEMErrorCode
795 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
796 std::vector<FieldSpace> space, std::string geom_field_name = "",
797 boost::shared_ptr<MatrixDouble> jac = nullptr,
798 boost::shared_ptr<VectorDouble> det = nullptr,
799 boost::shared_ptr<MatrixDouble> inv_jac = nullptr);
800};
801
802template <int FIELD_DIM>
808 const auto nb_dofs = data.getFieldData().size() / FIELD_DIM;
809 if (nb_dofs) {
810 if (type == MBVERTEX)
811 getCoordsAtGaussPts().clear();
812 auto t_base = data.getFTensor0N();
813 auto t_coords = getFTensor1CoordsAtGaussPts();
814 const auto nb_integration_pts = data.getN().size1();
815 const auto nb_base_functions = data.getN().size2();
816 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
817 auto t_dof = data.getFTensor1FieldData<FIELD_DIM>();
818 size_t bb = 0;
819 for (; bb != nb_dofs; ++bb) {
820 t_coords(i) += t_base * t_dof(i);
821 ++t_dof;
822 ++t_base;
823 }
824 for (; bb < nb_base_functions; ++bb)
825 ++t_base;
826 ++t_coords;
827 }
828 }
830}
831
832template <int FIELD_DIM>
837
840
841 auto get_ftensor1 = [](MatrixDouble &m) {
843 &m(0, 0), &m(0, 1), &m(0, 2));
844 };
845
846 unsigned int nb_dofs = data.getFieldData().size();
847 if (nb_dofs != 0) {
848
849 int nb_gauss_pts = data.getN().size1();
850 auto &tangent1_at_gauss_pts = getTangent1AtGaussPts();
851 auto &tangent2_at_gauss_pts = getTangent2AtGaussPts();
852 tangent1_at_gauss_pts.resize(nb_gauss_pts, 3, false);
853 tangent2_at_gauss_pts.resize(nb_gauss_pts, 3, false);
854
855 switch (type) {
856 case MBVERTEX: {
857 if (!addField) {
858 tangent1_at_gauss_pts.clear();
859 tangent2_at_gauss_pts.clear();
860 }
861 }
862 case MBEDGE:
863 case MBTRI:
864 case MBQUAD: {
865
866#ifndef NDEBUG
867 if (2 * data.getN().size2() != data.getDiffN().size2()) {
868 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
869 "expected two derivative in local element coordinates");
870 }
871 if (nb_dofs % FIELD_DIM != 0) {
872 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
873 "expected that number of dofs is multiplicative of field "
874 "dimension");
875 }
876#endif
877
878 if (nb_dofs > FIELD_DIM * data.getN().size2()) {
879 unsigned int nn = 0;
880 for (; nn != nb_dofs; nn++) {
881 if (!data.getFieldDofs()[nn]->getActive())
882 break;
883 }
884 if (nn > FIELD_DIM * data.getN().size2()) {
885 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
886 "Data inconsistency for base %s",
888 } else {
889 nb_dofs = nn;
890 if (!nb_dofs)
892 }
893 }
894 const int nb_base_functions = data.getN().size2();
895 auto t_base = data.getFTensor0N();
896 auto t_diff_base = data.getFTensor1DiffN<2>();
897 auto t_t1 = get_ftensor1(tangent1_at_gauss_pts);
898 auto t_t2 = get_ftensor1(tangent2_at_gauss_pts);
899 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
900 auto t_data = data.getFTensor1FieldData<FIELD_DIM>();
901 int bb = 0;
902 for (; bb != nb_dofs / FIELD_DIM; ++bb) {
904 t_t1(i) += t_data(i) * t_diff_base(N0);
905 t_t2(i) += t_data(i) * t_diff_base(N1);
906 ++t_data;
907 ++t_base;
908 ++t_diff_base;
909 }
910 for (; bb != nb_base_functions; ++bb) {
911 ++t_base;
912 ++t_diff_base;
913 }
914 ++t_t1;
915 ++t_t2;
916 }
917 } break;
918 default:
919 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
920 }
921 }
922
923 if (moab::CN::Dimension(type) == 2) {
924
925 auto &normal_at_gauss_pts = getNormalsAtGaussPts();
926 auto &tangent1_at_gauss_pts = getTangent1AtGaussPts();
927 auto &tangent2_at_gauss_pts = getTangent2AtGaussPts();
928
929 const auto nb_gauss_pts = tangent1_at_gauss_pts.size1();
930 normal_at_gauss_pts.resize(nb_gauss_pts, 3, false);
931
932 auto t_normal = get_ftensor1(normal_at_gauss_pts);
933 auto t_t1 = get_ftensor1(tangent1_at_gauss_pts);
934 auto t_t2 = get_ftensor1(tangent2_at_gauss_pts);
935 for (unsigned int gg = 0; gg != nb_gauss_pts; ++gg) {
936 FTensor::Index<'i', 3> i;
937 FTensor::Index<'j', 3> j;
938 FTensor::Index<'k', 3> k;
939 t_normal(j) = FTensor::levi_civita(i, j, k) * t_t1(k) * t_t2(i);
940 ++t_normal;
941 ++t_t1;
942 ++t_t2;
943 }
944 }
945
947}
948
949template <int FIELD_DIM>
954
955 auto get_tangent = [&]() -> MatrixDouble & {
956 if (tangentsAtPts)
957 return *tangentsAtPts;
958 else
959 return getTangentAtGaussPts();
960 };
961
962 auto &tangent = get_tangent();
963 int nb_gauss_pts = getGaussPts().size2();
964
965 if (type == MBVERTEX) {
966 tangent.resize(nb_gauss_pts, 3, false);
967 tangent.clear();
968 }
969
970 int nb_dofs = data.getFieldData().size();
971 if (nb_dofs != 0) {
972 const int nb_base_functions = data.getN().size2();
973 double *diff_base_function = &*data.getDiffN().data().begin();
974 auto tangent_at_gauss_pts =
975 getFTensor1FromPtr<FIELD_DIM, 3>(&*tangent.data().begin());
976
978 int size = nb_dofs / FIELD_DIM;
979 if (nb_dofs % FIELD_DIM) {
980 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
981 "Inconsistent number of dofs and field dimension");
982 }
983 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
984 auto field_data = data.getFTensor1FieldData<FIELD_DIM>();
985 int bb = 0;
986 for (; bb < size; ++bb) {
987 tangent_at_gauss_pts(i) += field_data(i) * (*diff_base_function);
988 ++field_data;
989 ++diff_base_function;
990 }
991 for (; bb != nb_base_functions; ++bb) {
992 ++diff_base_function;
993 }
994 ++tangent_at_gauss_pts;
995 }
996 }
998}
999
1000/**
1001 * @deprecated do not use this function, instead use AddHOOps.
1002 *
1003 * @tparam E
1004 * @param field
1005 * @param e
1006 * @param h1
1007 * @param hcurl
1008 * @param hdiv
1009 * @param l2
1010 * @return MoFEMErrorCode
1011 */
1012template <typename E>
1013MoFEMErrorCode addHOOpsVol(const std::string field, E &e, bool h1,
1014 bool hcurl, bool hdiv, bool l2) {
1015 std::vector<FieldSpace> spaces;
1016 if (h1)
1017 spaces.push_back(H1);
1018 if (hcurl)
1019 spaces.push_back(HCURL);
1020 if (hdiv)
1021 spaces.push_back(HDIV);
1022 if (l2)
1023 spaces.push_back(L2);
1024 return AddHOOps<3, 3, 3>::add(e.getOpPtrVector(), spaces, field);
1025}
1026
1027/**
1028 * @deprecated do not use this function, instead use AddHOOps.
1029 *
1030 * @tparam E
1031 * @param field
1032 * @param e
1033 * @param hcurl
1034 * @param hdiv
1035 * @return MoFEMErrorCode
1036 */
1037template <typename E>
1038MoFEMErrorCode addHOOpsFace3D(const std::string field, E &e,
1039 bool hcurl, bool hdiv) {
1040 std::vector<FieldSpace> spaces;
1041 if (hcurl)
1042 spaces.push_back(HCURL);
1043 if (hdiv)
1044 spaces.push_back(HDIV);
1045 return AddHOOps<2, 3, 3>::add(e.getOpPtrVector(), spaces, field);
1046}
1047
1048}; // namespace MoFEM
1049
1050#endif
constexpr int FIELD_DIM
FieldApproximationBase
approximation base
Definition definitions.h:58
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
FieldSpace
approximation spaces
Definition definitions.h:82
@ L2
field with C-1 continuity
Definition definitions.h:88
@ H1
continuous field
Definition definitions.h:85
@ NOSPACE
Definition definitions.h:83
@ HCURL
field with continuous tangents
Definition definitions.h:86
@ HDIV
field with continuous normal traction
Definition definitions.h:87
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
static const char *const ApproximationBaseNames[]
Definition definitions.h:72
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
constexpr std::enable_if<(Dim0<=2 &&Dim1<=2), Tensor2_Expr< Levi_Civita< T >, T, Dim0, Dim1, i, j > >::type levi_civita(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
levi_civita functions to make for easy adhoc use
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
MoFEMErrorCode addHOOpsFace3D(const std::string field, E &e, bool hcurl, bool hdiv)
MoFEMErrorCode addHOOpsVol(const std::string field, E &e, bool h1, bool hcurl, bool hdiv, bool l2)
constexpr auto field_name
FTensor::Index< 'm', 3 > m
Add operators pushing bases from local to physical configuration.
bool & doVertices
\deprectaed If false skip vertices
bool & doEdges
\deprectaed If false skip edges
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
FieldApproximationBase & getBase()
Get approximation base.
MatrixDouble & getDiffN(const FieldApproximationBase base)
get derivatives of base functions
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorDouble & getFieldData() const
Get DOF values on entity.
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1FieldData()
Return FTensor of rank 1, i.e. vector from field data coefficients.
const VectorDofs & getFieldDofs() const
Get DOF data structures (const version)
MatrixDouble & getNormalsAtGaussPts()
if higher order geometry return normals at Gauss pts.
MatrixDouble & getTangent2AtGaussPts()
if higher order geometry return tangent vector to triangle at Gauss pts.
MatrixDouble & getTangent1AtGaussPts()
if higher order geometry return tangent vector to triangle at Gauss pts.
@ OPROW
operator doWork function is executed on FE rows
@ OPSPACE
operator do Work is execute on space data
structure to get information from mofem into EntitiesFieldData
Calculate high-order coordinates at Gauss points.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateHOCoords(const std::string field_name)
Constructor for HO coordinates calculation.
boost::shared_ptr< MatrixDouble > jacPtr
Calculate jacobian for face element.
Calculate Jacobian on Hex or other volume elements which are not simplex.
boost::shared_ptr< MatrixDouble > jacPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateHOJacForVolume(boost::shared_ptr< MatrixDouble > jac_ptr)
Constructor for HO Jacobian calculation on volumes.
Calculate normal vectors at Gauss points of face elements.
boost::shared_ptr< MatrixDouble > normalsAtPts
MatrixDouble & getTangent1AtGaussPts()
boost::shared_ptr< MatrixDouble > tangent1AtPts
boost::shared_ptr< MatrixDouble > tangent2AtPts
OpGetHONormalsOnFace(std::string field_name, boost::shared_ptr< MatrixDouble > tangent1_at_pts, boost::shared_ptr< MatrixDouble > tangent2_at_pts, boost::shared_ptr< MatrixDouble > normals_at_pts, bool add_field=false)
OpGetHONormalsOnFace(std::string field_name, bool add_field=false)
Constructor for HO normal vectors calculation on faces.
MatrixDouble & getTangent2AtGaussPts()
MatrixDouble & getNormalsAtGaussPts()
bool addField
if true add field values, do not overwrite
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Calculate tangent vector on edge from HO geometry approximation.
boost::shared_ptr< MatrixDouble > tangentsAtPts
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpGetHOTangentsOnEdge(std::string field_name, boost::shared_ptr< MatrixDouble > tangents_at_pts=nullptr)
Constructor for HO tangents calculation on edges.
Transform Hcurl base functions from reference element to physical edge in 3D.
boost::shared_ptr< MatrixDouble > tangentAtGaussPts
OpHOSetContravariantPiolaTransformOnEdge3D(const FieldSpace space=HCURL, boost::shared_ptr< MatrixDouble > tangent_at_pts=nullptr)
Constructor for contravariant Piola transformation on 3D edges.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Transform Hdiv base fluxes from reference element to physical face in 3D.
boost::shared_ptr< MatrixDouble > normalsAtGaussPts
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpHOSetContravariantPiolaTransformOnFace3D(const FieldSpace space, boost::shared_ptr< MatrixDouble > normals_at_gauss_pts=nullptr)
Constructor for contravariant Piola transformation on 3D faces.
Transform Hcurl base functions from reference element to physical face in 3D.
OpHOSetCovariantPiolaTransformOnFace3D(const FieldSpace space, boost::shared_ptr< MatrixDouble > normals_at_pts=nullptr, boost::shared_ptr< MatrixDouble > tangent1_at_pts=nullptr, boost::shared_ptr< MatrixDouble > tangent2_at_pts=nullptr)
Constructor for covariant Piola transformation on 3D faces.
boost::shared_ptr< MatrixDouble > normalsAtPts
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< MatrixDouble > tangent2AtPts
boost::shared_ptr< MatrixDouble > tangent1AtPts
Scale base functions by inverses of measure of element.
boost::shared_ptr< VectorDouble > detJacPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Apply contravariant (Piola) transformation to Hdiv space for HO geometry.
boost::shared_ptr< VectorDouble > detPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< MatrixDouble > jacPtr
OpSetHOContravariantPiolaTransform(const FieldSpace space, boost::shared_ptr< VectorDouble > det_ptr, boost::shared_ptr< MatrixDouble > jac_ptr)
Constructor for contravariant Piola transformation.
Apply covariant (Piola) transformation to Hcurl space for HO geometry.
OpSetHOCovariantPiolaTransform(const FieldSpace space, boost::shared_ptr< MatrixDouble > jac_inv_ptr)
Constructor for covariant Piola transformation.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< MatrixDouble > jacInvPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Set inverse jacobian to base functions.
Transform local reference derivatives of shape functions to global derivatives.
boost::shared_ptr< MatrixDouble > invJacPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpSetHOInvJacVectorBase(const FieldSpace space, boost::shared_ptr< MatrixDouble > inv_jac_ptr)
Constructor for HO inverse Jacobian transformation for vector bases.
Modify integration weights on edge to take into account higher-order geometry.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpSetHOWeightsOnEdge()
Default constructor for HO weights on edge.
Modify integration weights on face to take into account higher-order geometry.
OpSetHOWeightsOnFace()
Default constructor for HO weights on face.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Set integration weights for higher-order elements.
OpSetHOWeights(boost::shared_ptr< VectorDouble > det_ptr)
Constructor for HO weights calculation.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< VectorDouble > detPtr
Transform local reference derivatives of shape functions to global derivatives.
OpSetInvJacToScalarBasesBasic(FieldSpace space, boost::shared_ptr< MatrixDouble > inv_jac_ptr)