v0.15.0
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
404 /**
405 * @brief Constructor for HO normal vectors calculation on faces
406 *
407 * @param field_name Field name where normal vectors will be stored
408 * @param add_field If true, add to existing field values; if false, overwrite (default: false)
409 */
410 OpGetHONormalsOnFace(std::string field_name, bool add_field = false)
412 addField(add_field) {}
413
414 MoFEMErrorCode doWork(int side, EntityType type,
416private:
417 bool addField = false; ///< if true add field values, do not overwrite
418};
419
420/**
421 * @brief Transform Hdiv base fluxes from reference element to physical face in 3D
422 *
423 * This structure applies contravariant Piola transformation to Hdiv basis
424 * functions on 3D face elements. It transforms flux values from reference
425 * coordinates to physical coordinates while preserving divergence properties.
426 *
427 * @note Matrix which keeps normal vectors is assumed to have three columns,
428 * and number of rows should be equal to number of integration points.
429 *
430 * @ingroup mofem_forces_and_sources
431 */
434
435 /**
436 * @brief Constructor for contravariant Piola transformation on 3D faces
437 *
438 * @param space Field space specification (typically HDIV)
439 * @param normals_at_gauss_pts Shared pointer to matrix containing normal vectors at integration points (optional)
440 */
442 const FieldSpace space,
443 boost::shared_ptr<MatrixDouble> normals_at_gauss_pts = nullptr)
445 normalsAtGaussPts(normals_at_gauss_pts) {}
446
447 MoFEMErrorCode doWork(int side, EntityType type,
449
450private:
451 boost::shared_ptr<MatrixDouble> normalsAtGaussPts;
452};
453
454/**
455 * @brief Transform Hcurl base functions from reference element to physical edge in 3D
456 *
457 * This structure applies contravariant Piola transformation to Hcurl basis
458 * functions on 3D edge elements. It transforms curl-conforming basis functions
459 * from reference coordinates to physical coordinates while preserving tangential
460 * continuity across element boundaries.
461 *
462 * @ingroup mofem_forces_and_sources
463 */
466
467 /**
468 * @brief Constructor for contravariant Piola transformation on 3D edges
469 *
470 * @param space Field space specification (default: HCURL)
471 * @param tangent_at_pts Shared pointer to matrix containing tangent vectors at integration points (optional)
472 */
474 const FieldSpace space = HCURL,
475 boost::shared_ptr<MatrixDouble> tangent_at_pts = nullptr)
477 tangentAtGaussPts(tangent_at_pts) {}
478
479 MoFEMErrorCode doWork(int side, EntityType type,
481
482private:
483 boost::shared_ptr<MatrixDouble> tangentAtGaussPts;
484};
485
486/**
487 * @brief Transform Hcurl base functions from reference element to physical face in 3D
488 *
489 * This structure applies covariant Piola transformation to Hcurl basis functions
490 * on 3D face elements. It transforms curl-conforming basis functions from
491 * reference coordinates to physical coordinates using normal and tangent vectors,
492 * preserving the curl properties of the field.
493 *
494 * @ingroup mofem_forces_and_sources
495 */
498
499 /**
500 * @brief Constructor for covariant Piola transformation on 3D faces
501 *
502 * @param space Field space specification (typically HCURL)
503 * @param normals_at_pts Shared pointer to matrix containing normal vectors at integration points (optional)
504 * @param tangent1_at_pts Shared pointer to matrix containing first tangent vectors at integration points (optional)
505 * @param tangent2_at_pts Shared pointer to matrix containing second tangent vectors at integration points (optional)
506 */
508 const FieldSpace space,
509 boost::shared_ptr<MatrixDouble> normals_at_pts = nullptr,
510 boost::shared_ptr<MatrixDouble> tangent1_at_pts = nullptr,
511 boost::shared_ptr<MatrixDouble> tangent2_at_pts = nullptr)
513 normalsAtPts(normals_at_pts), tangent1AtPts(tangent1_at_pts),
514 tangent2AtPts(tangent2_at_pts) {
515 if (normals_at_pts || tangent1_at_pts || tangent2_at_pts)
516 if (normals_at_pts && tangent1_at_pts && tangent2_at_pts)
518 "All elements in constructor have to set pointer");
519 }
520
521 MoFEMErrorCode doWork(int side, EntityType type,
523
524private:
525 boost::shared_ptr<MatrixDouble> normalsAtPts;
526 boost::shared_ptr<MatrixDouble> tangent1AtPts;
527 boost::shared_ptr<MatrixDouble> tangent2AtPts;
528
531};
532
533/**
534 * @brief Calculate tangent vector on edge from HO geometry approximation
535 *
536 * This template structure computes tangent vectors along edges using high-order
537 * geometry approximation. It extracts tangent information at integration points
538 * and stores the results for further processing in finite element calculations.
539 *
540 * @tparam FIELD_DIM Dimension of the field (default: 3)
541 *
542 * @ingroup mofem_forces_and_sources
543 */
544template <int FIELD_DIM = 3>
547
548 /**
549 * @brief Constructor for HO tangents calculation on edges
550 *
551 * @param field_name Name of the field used for tangent calculation
552 * @param tangents_at_pts Shared pointer to matrix for storing calculated tangents (optional)
553 */
555 std::string field_name,
556 boost::shared_ptr<MatrixDouble> tangents_at_pts = nullptr)
558 tangentsAtPts(tangents_at_pts) {}
559
560 MoFEMErrorCode doWork(int side, EntityType type,
562
563private:
564 boost::shared_ptr<MatrixDouble> tangentsAtPts;
565};
566
567/**
568 * @brief Scale base functions by inverses of measure of element
569 *
570 * @tparam OP
571 */
574
576
578 const FieldSpace space, const FieldApproximationBase base,
579 boost::shared_ptr<VectorDouble> det_jac_ptr,
580 boost::shared_ptr<double> scale_det_ptr = nullptr);
581
582 MoFEMErrorCode doWork(int side, EntityType type,
584
585private:
588 boost::shared_ptr<VectorDouble> detJacPtr;
589 boost::shared_ptr<double> scaleDetPtr = nullptr;
590};
591
592/**
593 * @brief Add operators pushing bases from local to physical configuration
594 *
595 * @tparam FE_DIM dimension of element
596 * @tparam PROBLEM_DIM problem dimension
597 * @tparam SPACE_DIM space dimension
598 */
599template <int FE_DIM, int PROBLEM_DIM, int SPACE_DIM> struct AddHOOps;
600
601/**
602 * @brief Specialization for 2D face elements in 2D problems with 2D space
603 *
604 * This specialization adds high-order operators for 2D face elements operating
605 * in 2D problems within 2D coordinate space. Commonly used for planar face
606 * elements in 2D finite element analysis.
607 */
608template <> struct AddHOOps<2, 2, 2> {
609 AddHOOps() = delete;
610
611 /**
612 * @brief Add high-order operators to the pipeline for 2D face elements
613 *
614 * @param pipeline Pipeline to add operators to
615 * @param spaces Vector of field spaces to be handled
616 * @param geom_field_name Name of the geometry field (default: empty string)
617 * @param jac Shared pointer to Jacobian matrix. If provided, values will be set by this function.
618 * If null, Jacobian will be handled internally.
619 * @param det Shared pointer to determinant vector. If provided, values will be set by this function.
620 * If null, determinant will be handled internally.
621 * @param inv_jac Shared pointer to inverse Jacobian matrix. If provided, values will be set by this function.
622 * If null, inverse Jacobian will be handled internally.
623 * @return MoFEMErrorCode Error code indicating success or failure
624 */
625 static MoFEMErrorCode
626 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
627 std::vector<FieldSpace> spaces, std::string geom_field_name = "",
628 boost::shared_ptr<MatrixDouble> jac = nullptr,
629 boost::shared_ptr<VectorDouble> det = nullptr,
630 boost::shared_ptr<MatrixDouble> inv_jac = nullptr);
631};
632
633/**
634 * @brief Specialization for 2D face elements in 2D problems embedded in 3D space
635 *
636 * This specialization adds high-order operators for 2D face elements operating
637 * in 2D problems but embedded within 3D coordinate space. Typically used for
638 * surface elements or membranes in 3D environments.
639 */
640template <> struct AddHOOps<2, 2, 3> {
641 AddHOOps() = delete;
642
643 /**
644 * @brief Add high-order operators to the pipeline for 2D face elements embedded in 3D
645 *
646 * @param pipeline Pipeline to add operators to
647 * @param spaces Vector of field spaces to be handled
648 * @param geom_field_name Name of the geometry field (default: empty string)
649 * @param jac Shared pointer to Jacobian matrix. If provided, values will be set by this function.
650 * If null, Jacobian will be handled internally.
651 * @param det Shared pointer to determinant vector. If provided, values will be set by this function.
652 * If null, determinant will be handled internally.
653 * @param inv_jac Shared pointer to inverse Jacobian matrix. If provided, values will be set by this function.
654 * If null, inverse Jacobian will be handled internally.
655 * @return MoFEMErrorCode Error code indicating success or failure
656 */
657 static MoFEMErrorCode
658 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
659 std::vector<FieldSpace> spaces, std::string geom_field_name = "",
660 boost::shared_ptr<MatrixDouble> jac = nullptr,
661 boost::shared_ptr<VectorDouble> det = nullptr,
662 boost::shared_ptr<MatrixDouble> inv_jac = nullptr);
663};
664
665/**
666 * @brief Specialization for 1D edge elements in 2D problems with 2D space
667 *
668 * This specialization adds high-order operators for 1D edge elements operating
669 * in 2D problems within 2D coordinate space. Used for edge-based computations
670 * such as boundary conditions or line integrals in 2D finite element analysis.
671 */
672template <> struct AddHOOps<1, 2, 2> {
673 AddHOOps() = delete;
674
675 /**
676 * @brief Add high-order operators to the pipeline for 1D edge elements in 2D
677 *
678 * @param pipeline Pipeline to add operators to
679 * @param spaces Vector of field spaces to be handled
680 * @param geom_field_name Name of the geometry field (default: empty string)
681 * @return MoFEMErrorCode Error code indicating success or failure
682 *
683 * @note This specialization handles Jacobian, determinant, and inverse Jacobian internally.
684 */
685 static MoFEMErrorCode
686 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
687 std::vector<FieldSpace> spaces, std::string geom_field_name = "");
688};
689
690/**
691 * @brief Specialization for 1D edge elements in 3D problems with 3D space
692 *
693 * This specialization adds high-order operators for 1D edge elements operating
694 * in 3D problems within 3D coordinate space. Used for edge-based computations
695 * such as line integrals, boundary conditions, or wire-like structures in 3D
696 * finite element analysis.
697 */
698template <> struct AddHOOps<1, 3, 3> {
699 AddHOOps() = delete;
700
701 /**
702 * @brief Add high-order operators to the pipeline for 1D edge elements in 3D
703 *
704 * @param pipeline Pipeline to add operators to
705 * @param space Vector of field spaces to be handled
706 * @param geom_field_name Name of the geometry field (default: empty string)
707 * @return MoFEMErrorCode Error code indicating success or failure
708 *
709 * @note This specialization handles Jacobian, determinant, and inverse Jacobian internally.
710 */
711 static MoFEMErrorCode
712 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
713 std::vector<FieldSpace> space, std::string geom_field_name = "");
714};
715
716/**
717 * @brief Specialization for 2D face elements in 3D problems with 3D space
718 *
719 * This specialization adds high-order operators for 2D face elements operating
720 * in 3D problems within 3D coordinate space. Commonly used for surface elements,
721 * boundary conditions, membranes, or shell structures in 3D finite element
722 * analysis.
723 */
724template <> struct AddHOOps<2, 3, 3> {
725 AddHOOps() = delete;
726
727 /**
728 * @brief Add high-order operators to the pipeline for 2D face elements in 3D
729 *
730 * @param pipeline Pipeline to add operators to
731 * @param space Vector of field spaces to be handled
732 * @param geom_field_name Name of the geometry field (default: empty string)
733 * @return MoFEMErrorCode Error code indicating success or failure
734 *
735 * @note This specialization handles Jacobian, determinant, and inverse Jacobian internally.
736 */
737 static MoFEMErrorCode
738 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
739 std::vector<FieldSpace> space, std::string geom_field_name = "");
740};
741
742/**
743 * @brief Specialization for 3D volume elements in 3D problems with 3D space
744 *
745 * This specialization adds high-order operators for 3D volume elements operating
746 * in 3D problems within 3D coordinate space. This is the most common case for
747 * solid mechanics, heat transfer, and other 3D finite element applications
748 * involving volumetric elements like tetrahedra, hexahedra, and prisms.
749 */
750template <> struct AddHOOps<3, 3, 3> {
751 AddHOOps() = delete;
752
753 /**
754 * @brief Add high-order operators to the pipeline for 3D volume elements
755 *
756 * @param pipeline Pipeline to add operators to
757 * @param space Vector of field spaces to be handled
758 * @param geom_field_name Name of the geometry field (default: empty string)
759 * @param jac Shared pointer to Jacobian matrix. If provided, values will be set by this function.
760 * If null, Jacobian will be handled internally.
761 * @param det Shared pointer to determinant vector. If provided, values will be set by this function.
762 * If null, determinant will be handled internally.
763 * @param inv_jac Shared pointer to inverse Jacobian matrix. If provided, values will be set by this function.
764 * If null, inverse Jacobian will be handled internally.
765 * @return MoFEMErrorCode Error code indicating success or failure
766 */
767 static MoFEMErrorCode
768 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
769 std::vector<FieldSpace> space, std::string geom_field_name = "",
770 boost::shared_ptr<MatrixDouble> jac = nullptr,
771 boost::shared_ptr<VectorDouble> det = nullptr,
772 boost::shared_ptr<MatrixDouble> inv_jac = nullptr);
773};
774
775template <int FIELD_DIM>
781 const auto nb_dofs = data.getFieldData().size() / FIELD_DIM;
782 if (nb_dofs) {
783 if (type == MBVERTEX)
784 getCoordsAtGaussPts().clear();
785 auto t_base = data.getFTensor0N();
786 auto t_coords = getFTensor1CoordsAtGaussPts();
787 const auto nb_integration_pts = data.getN().size1();
788 const auto nb_base_functions = data.getN().size2();
789 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
790 auto t_dof = data.getFTensor1FieldData<FIELD_DIM>();
791 size_t bb = 0;
792 for (; bb != nb_dofs; ++bb) {
793 t_coords(i) += t_base * t_dof(i);
794 ++t_dof;
795 ++t_base;
796 }
797 for (; bb < nb_base_functions; ++bb)
798 ++t_base;
799 ++t_coords;
800 }
801 }
803}
804
805template <int FIELD_DIM>
810
813
814 auto get_ftensor1 = [](MatrixDouble &m) {
816 &m(0, 0), &m(0, 1), &m(0, 2));
817 };
818
819 unsigned int nb_dofs = data.getFieldData().size();
820 if (nb_dofs != 0) {
821
822 int nb_gauss_pts = data.getN().size1();
823 auto &tangent1_at_gauss_pts = getTangent1AtGaussPts();
824 auto &tangent2_at_gauss_pts = getTangent2AtGaussPts();
825 tangent1_at_gauss_pts.resize(nb_gauss_pts, 3, false);
826 tangent2_at_gauss_pts.resize(nb_gauss_pts, 3, false);
827
828 switch (type) {
829 case MBVERTEX: {
830 if (!addField) {
831 tangent1_at_gauss_pts.clear();
832 tangent2_at_gauss_pts.clear();
833 }
834 }
835 case MBEDGE:
836 case MBTRI:
837 case MBQUAD: {
838
839#ifndef NDEBUG
840 if (2 * data.getN().size2() != data.getDiffN().size2()) {
841 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
842 "expected two derivative in local element coordinates");
843 }
844 if (nb_dofs % FIELD_DIM != 0) {
845 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
846 "expected that number of dofs is multiplicative of field "
847 "dimension");
848 }
849#endif
850
851 if (nb_dofs > FIELD_DIM * data.getN().size2()) {
852 unsigned int nn = 0;
853 for (; nn != nb_dofs; nn++) {
854 if (!data.getFieldDofs()[nn]->getActive())
855 break;
856 }
857 if (nn > FIELD_DIM * data.getN().size2()) {
858 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
859 "Data inconsistency for base %s",
861 } else {
862 nb_dofs = nn;
863 if (!nb_dofs)
865 }
866 }
867 const int nb_base_functions = data.getN().size2();
868 auto t_base = data.getFTensor0N();
869 auto t_diff_base = data.getFTensor1DiffN<2>();
870 auto t_t1 = get_ftensor1(tangent1_at_gauss_pts);
871 auto t_t2 = get_ftensor1(tangent2_at_gauss_pts);
872 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
873 auto t_data = data.getFTensor1FieldData<FIELD_DIM>();
874 int bb = 0;
875 for (; bb != nb_dofs / FIELD_DIM; ++bb) {
877 t_t1(i) += t_data(i) * t_diff_base(N0);
878 t_t2(i) += t_data(i) * t_diff_base(N1);
879 ++t_data;
880 ++t_base;
881 ++t_diff_base;
882 }
883 for (; bb != nb_base_functions; ++bb) {
884 ++t_base;
885 ++t_diff_base;
886 }
887 ++t_t1;
888 ++t_t2;
889 }
890 } break;
891 default:
892 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
893 }
894 }
895
896 if (moab::CN::Dimension(type) == 2) {
897
898 auto &normal_at_gauss_pts = getNormalsAtGaussPts();
899 auto &tangent1_at_gauss_pts = getTangent1AtGaussPts();
900 auto &tangent2_at_gauss_pts = getTangent2AtGaussPts();
901
902 const auto nb_gauss_pts = tangent1_at_gauss_pts.size1();
903 normal_at_gauss_pts.resize(nb_gauss_pts, 3, false);
904
905 auto t_normal = get_ftensor1(normal_at_gauss_pts);
906 auto t_t1 = get_ftensor1(tangent1_at_gauss_pts);
907 auto t_t2 = get_ftensor1(tangent2_at_gauss_pts);
908 for (unsigned int gg = 0; gg != nb_gauss_pts; ++gg) {
909 FTensor::Index<'i', 3> i;
910 FTensor::Index<'j', 3> j;
911 FTensor::Index<'k', 3> k;
912 t_normal(j) = FTensor::levi_civita(i, j, k) * t_t1(k) * t_t2(i);
913 ++t_normal;
914 ++t_t1;
915 ++t_t2;
916 }
917 }
918
920}
921
922template <int FIELD_DIM>
927
928 auto get_tangent = [&]() -> MatrixDouble & {
929 if (tangentsAtPts)
930 return *tangentsAtPts;
931 else
932 return getTangentAtGaussPts();
933 };
934
935 auto &tangent = get_tangent();
936 int nb_gauss_pts = getGaussPts().size2();
937
938 if (type == MBVERTEX) {
939 tangent.resize(nb_gauss_pts, 3, false);
940 tangent.clear();
941 }
942
943 int nb_dofs = data.getFieldData().size();
944 if (nb_dofs != 0) {
945 const int nb_base_functions = data.getN().size2();
946 double *diff_base_function = &*data.getDiffN().data().begin();
947 auto tangent_at_gauss_pts =
948 getFTensor1FromPtr<FIELD_DIM, 3>(&*tangent.data().begin());
949
951 int size = nb_dofs / FIELD_DIM;
952 if (nb_dofs % FIELD_DIM) {
953 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
954 "Inconsistent number of dofs and field dimension");
955 }
956 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
957 auto field_data = data.getFTensor1FieldData<FIELD_DIM>();
958 int bb = 0;
959 for (; bb < size; ++bb) {
960 tangent_at_gauss_pts(i) += field_data(i) * (*diff_base_function);
961 ++field_data;
962 ++diff_base_function;
963 }
964 for (; bb != nb_base_functions; ++bb) {
965 ++diff_base_function;
966 }
967 ++tangent_at_gauss_pts;
968 }
969 }
971}
972
973/**
974 * @deprecated do not use this function, instead use AddHOOps.
975 *
976 * @tparam E
977 * @param field
978 * @param e
979 * @param h1
980 * @param hcurl
981 * @param hdiv
982 * @param l2
983 * @return MoFEMErrorCode
984 */
985template <typename E>
986MoFEMErrorCode addHOOpsVol(const std::string field, E &e, bool h1,
987 bool hcurl, bool hdiv, bool l2) {
988 std::vector<FieldSpace> spaces;
989 if (h1)
990 spaces.push_back(H1);
991 if (hcurl)
992 spaces.push_back(HCURL);
993 if (hdiv)
994 spaces.push_back(HDIV);
995 if (l2)
996 spaces.push_back(L2);
997 return AddHOOps<3, 3, 3>::add(e.getOpPtrVector(), spaces, field);
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 hcurl
1007 * @param hdiv
1008 * @return MoFEMErrorCode
1009 */
1010template <typename E>
1011MoFEMErrorCode addHOOpsFace3D(const std::string field, E &e,
1012 bool hcurl, bool hdiv) {
1013 std::vector<FieldSpace> spaces;
1014 if (hcurl)
1015 spaces.push_back(HCURL);
1016 if (hdiv)
1017 spaces.push_back(HDIV);
1018 return AddHOOps<2, 3, 3>::add(e.getOpPtrVector(), spaces, field);
1019}
1020
1021}; // namespace MoFEM
1022
1023#endif
ForcesAndSourcesCore::UserDataOperator UserDataOperator
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)
@ 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.
OpGetHONormalsOnFace(std::string field_name, bool add_field=false)
Constructor for HO normal vectors calculation on faces.
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)