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::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
auto getFTensor1FieldData()
Return FTensor of rank 1, i.e. vector from field data coefficients.
auto getFTensor1DiffN(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.
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)