47#ifndef __HO_DATA_OPERATORS_HPP__
48#define __HO_DATA_OPERATORS_HPP__
75 boost::shared_ptr<MatrixDouble>
jacPtr;
91template <
int FIELD_DIM = 3>
128template <
int DIM = 3,
int DERIVATIVE = 1>
130 using OpSetHOInvJacToScalarBasesImpl::OpSetHOInvJacToScalarBasesImpl;
174 boost::shared_ptr<MatrixDouble> inv_jac_ptr)
177 "Pointer for invJacPtr not allocated");
238template <
int SPACE_DIM>
268 "Pointer for detPtr not allocated");
299 boost::shared_ptr<VectorDouble> det_ptr,
300 boost::shared_ptr<MatrixDouble> jac_ptr)
337 boost::shared_ptr<MatrixDouble> jac_inv_ptr)
345 "Pointer for jacPtr not allocated");
416template <
int FIELD_DIM = 3>
432 boost::shared_ptr<MatrixDouble> tangent1_at_pts,
433 boost::shared_ptr<MatrixDouble> tangent2_at_pts,
434 boost::shared_ptr<MatrixDouble> normals_at_pts,
435 bool add_field =
false)
486 boost::shared_ptr<MatrixDouble> normals_at_gauss_pts =
nullptr)
518 boost::shared_ptr<MatrixDouble> tangent_at_pts =
nullptr)
552 boost::shared_ptr<MatrixDouble> normals_at_pts =
nullptr,
553 boost::shared_ptr<MatrixDouble> tangent1_at_pts =
nullptr,
554 boost::shared_ptr<MatrixDouble> tangent2_at_pts =
nullptr)
558 if (normals_at_pts || tangent1_at_pts || tangent2_at_pts)
559 if (normals_at_pts && tangent1_at_pts && tangent2_at_pts)
561 "All elements in constructor have to set pointer");
587template <
int FIELD_DIM = 3>
599 boost::shared_ptr<MatrixDouble> tangents_at_pts =
nullptr)
622 boost::shared_ptr<VectorDouble> det_jac_ptr,
623 boost::shared_ptr<double> scale_det_ptr =
nullptr);
642template <
int FE_DIM,
int PROBLEM_DIM,
int SPACE_DIM>
struct AddHOOps;
669 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
670 std::vector<FieldSpace> spaces, std::string geom_field_name =
"",
671 boost::shared_ptr<MatrixDouble> jac =
nullptr,
672 boost::shared_ptr<VectorDouble> det =
nullptr,
673 boost::shared_ptr<MatrixDouble> inv_jac =
nullptr);
701 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
702 std::vector<FieldSpace> spaces, std::string geom_field_name =
"",
703 boost::shared_ptr<MatrixDouble> jac =
nullptr,
704 boost::shared_ptr<VectorDouble> det =
nullptr,
705 boost::shared_ptr<MatrixDouble> inv_jac =
nullptr);
729 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
730 std::vector<FieldSpace> spaces, std::string geom_field_name =
"");
755 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
756 std::vector<FieldSpace> space, std::string geom_field_name =
"");
781 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
782 std::vector<FieldSpace> space, std::string geom_field_name =
"");
811 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
812 std::vector<FieldSpace> space, std::string geom_field_name =
"",
813 boost::shared_ptr<MatrixDouble> jac =
nullptr,
814 boost::shared_ptr<VectorDouble> det =
nullptr,
815 boost::shared_ptr<MatrixDouble> inv_jac =
nullptr);
818template <
int FIELD_DIM>
826 if (type == MBVERTEX)
827 getCoordsAtGaussPts().clear();
829 auto t_coords = getFTensor1CoordsAtGaussPts();
830 const auto nb_integration_pts = data.
getN().size1();
831 const auto nb_base_functions = data.
getN().size2();
832 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
835 for (; bb != nb_dofs; ++bb) {
836 t_coords(
i) += t_base * t_dof(
i);
840 for (; bb < nb_base_functions; ++bb)
848template <
int FIELD_DIM>
859 &
m(0, 0), &
m(0, 1), &
m(0, 2));
865 int nb_gauss_pts = data.
getN().size1();
866 auto &tangent1_at_gauss_pts = getTangent1AtGaussPts();
867 auto &tangent2_at_gauss_pts = getTangent2AtGaussPts();
868 tangent1_at_gauss_pts.resize(nb_gauss_pts, 3,
false);
869 tangent2_at_gauss_pts.resize(nb_gauss_pts, 3,
false);
874 tangent1_at_gauss_pts.clear();
875 tangent2_at_gauss_pts.clear();
883 if (2 * data.
getN().size2() != data.
getDiffN().size2()) {
885 "expected two derivative in local element coordinates");
889 "expected that number of dofs is multiplicative of field "
896 for (; nn != nb_dofs; nn++) {
902 "Data inconsistency for base %s",
910 const int nb_base_functions = data.
getN().size2();
913 auto t_t1 = get_ftensor1(tangent1_at_gauss_pts);
914 auto t_t2 = get_ftensor1(tangent2_at_gauss_pts);
915 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
918 for (; bb != nb_dofs /
FIELD_DIM; ++bb) {
920 t_t1(
i) += t_data(
i) * t_diff_base(N0);
921 t_t2(
i) += t_data(
i) * t_diff_base(N1);
926 for (; bb != nb_base_functions; ++bb) {
939 if (moab::CN::Dimension(type) == 2) {
941 auto &normal_at_gauss_pts = getNormalsAtGaussPts();
942 auto &tangent1_at_gauss_pts = getTangent1AtGaussPts();
943 auto &tangent2_at_gauss_pts = getTangent2AtGaussPts();
945 const auto nb_gauss_pts = tangent1_at_gauss_pts.size1();
946 normal_at_gauss_pts.resize(nb_gauss_pts, 3,
false);
948 auto t_normal = get_ftensor1(normal_at_gauss_pts);
949 auto t_t1 = get_ftensor1(tangent1_at_gauss_pts);
950 auto t_t2 = get_ftensor1(tangent2_at_gauss_pts);
951 for (
unsigned int gg = 0; gg != nb_gauss_pts; ++gg) {
965template <
int FIELD_DIM>
973 return *tangentsAtPts;
975 return getTangentAtGaussPts();
978 auto &tangent = get_tangent();
979 int nb_gauss_pts = getGaussPts().size2();
981 if (type == MBVERTEX) {
982 tangent.resize(nb_gauss_pts, 3,
false);
988 const int nb_base_functions = data.
getN().size2();
989 double *diff_base_function = &*data.
getDiffN().data().begin();
990 auto tangent_at_gauss_pts =
991 getFTensor1FromPtr<FIELD_DIM, 3>(&*tangent.data().begin());
997 "Inconsistent number of dofs and field dimension");
999 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1002 for (; bb < size; ++bb) {
1003 tangent_at_gauss_pts(
i) += field_data(
i) * (*diff_base_function);
1005 ++diff_base_function;
1007 for (; bb != nb_base_functions; ++bb) {
1008 ++diff_base_function;
1010 ++tangent_at_gauss_pts;
1028template <
typename E>
1030 bool hcurl,
bool hdiv,
bool l2) {
1031 std::vector<FieldSpace> spaces;
1033 spaces.push_back(
H1);
1035 spaces.push_back(
HCURL);
1037 spaces.push_back(
HDIV);
1039 spaces.push_back(
L2);
1053template <
typename E>
1055 bool hcurl,
bool hdiv) {
1056 std::vector<FieldSpace> spaces;
1058 spaces.push_back(
HCURL);
1060 spaces.push_back(
HDIV);
FieldApproximationBase
approximation base
#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
@ L2
field with C-1 continuity
@ HCURL
field with continuous tangents
@ HDIV
field with continuous normal traction
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
static const char *const ApproximationBaseNames[]
#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
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
default operator for EDGE element
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)
default operator for TRI element
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.
Scale base functions by inverses of measure of element.
boost::shared_ptr< VectorDouble > detJacPtr
FieldApproximationBase fieldBase
boost::shared_ptr< double > scaleDetPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
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.
MatrixDouble diffHdivInvJac
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)