10 boost::shared_ptr<MatrixDouble> jac_ptr)
14 for (
auto t = MBEDGE;
t != MBMAXTYPE; ++
t)
26 const auto nb_base_functions = data.
getN(
NOBASE).size2();
27 if (nb_base_functions) {
34 if (nb_gauss_pts != data.
getDiffN().size1())
36 "Inconsistent number base functions and gauss points");
37 if (nb_base_functions != data.
getDiffN().size2() / 3)
39 "Inconsistent number of base functions");
40 if (coords.size() != 3 * nb_base_functions)
42 "Number of vertex coordinates and base functions is inconsistent "
44 coords.size() / 3, nb_base_functions);
47 jacPtr->resize(9, nb_gauss_pts,
false);
49 auto t_jac = getFTensor2FromMat<3, 3>(*
jacPtr);
56 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
58 &coords[0], &coords[1], &coords[2]);
59 for (
size_t bb = 0; bb != nb_base_functions; ++bb) {
60 t_jac(
i,
j) += t_coords(
i) * (t_vol_inv_jac(
k,
j) * t_diff_base(
k));
79 return applyTransform<3, 3, 3, 3>(diff_n);
90 CHKERR transform_base(*(
m.second));
95 CHKERR transform_base(*ptr);
119 data.
getDiffN(base).size2(),
false);
121 unsigned int nb_gauss_pts = data.
getDiffN(base).size1();
122 unsigned int nb_base_functions = data.
getDiffN(base).size2() / 9;
123 if (nb_base_functions == 0)
129 t_inv_diff_n_ptr, &t_inv_diff_n_ptr[
HVEC0_1],
134 auto t_inv_jac = getFTensor2FromMat<3, 3>(*
invJacPtr);
135 for (
unsigned int gg = 0; gg != nb_gauss_pts; ++gg) {
136 for (
unsigned int bb = 0; bb != nb_base_functions; ++bb) {
137 t_inv_diff_n(
i,
j) = t_inv_jac(
k,
j) * t_diff_n(
i,
k);
162 for (
size_t gg = 0; gg != nb_int_pts; ++gg) {
163 t_w *= sqrt(t_normal(
i) * t_normal(
i)) /
a;
169 "Number of rows in getNormalsAtGaussPts should be equal to "
170 "number of integration points, but is not, i.e. %ld != %ld",
187 for (
size_t gg = 0; gg != nb_int_pts; ++gg) {
188 t_w *= sqrt(t_tangent(
i) * t_tangent(
i)) /
a;
194 "Number of rows in getTangentAtGaussPts should be equal to "
195 "number of integration points, but is not, i.e. %ld != %ld",
206 const auto nb_integration_pts =
detPtr->size();
211 "Inconsistent number of data points");
216 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
237 "Pointer for detPtr not allocated");
240 "Pointer for jacPtr not allocated");
248 auto nb_base_functions =
250 auto nb_diff_base_functions =
254 if (nb_diff_base_functions) {
255 if (nb_diff_base_functions != nb_base_functions)
257 "Wrong number base functions %ld != %ld",
258 nb_diff_base_functions, nb_base_functions);
259 if (data.
getDiffN(base).size1() != nb_gauss_pts)
261 "Wrong number integration points");
265 if (nb_gauss_pts && nb_base_functions) {
267 piolaN.resize(nb_gauss_pts, data.
getN(base).size2(),
false);
270 double *t_transformed_n_ptr = &*
piolaN.data().begin();
273 &t_transformed_n_ptr[
HVEC1], &t_transformed_n_ptr[
HVEC2]);
276 auto t_jac = getFTensor2FromMat<3, 3>(*
jacPtr);
278 for (
unsigned int gg = 0; gg != nb_gauss_pts; ++gg) {
279 for (
unsigned int bb = 0; bb != nb_base_functions; ++bb) {
280 const double a = 1. / t_det;
281 t_transformed_n(
i) =
a * (t_jac(
i,
k) * t_n(
k));
292 if (nb_gauss_pts && nb_diff_base_functions) {
297 double *t_transformed_diff_n_ptr = &*
piolaDiffN.data().begin();
299 t_transformed_diff_n(t_transformed_diff_n_ptr,
300 &t_transformed_diff_n_ptr[
HVEC0_1],
301 &t_transformed_diff_n_ptr[
HVEC0_2],
302 &t_transformed_diff_n_ptr[
HVEC1_0],
303 &t_transformed_diff_n_ptr[
HVEC1_1],
304 &t_transformed_diff_n_ptr[
HVEC1_2],
305 &t_transformed_diff_n_ptr[
HVEC2_0],
306 &t_transformed_diff_n_ptr[
HVEC2_1],
307 &t_transformed_diff_n_ptr[
HVEC2_2]);
310 for (
unsigned int gg = 0; gg != nb_gauss_pts; ++gg) {
311 for (
unsigned int bb = 0; bb != nb_diff_base_functions; ++bb) {
312 const double a = 1. / t_det;
313 t_transformed_diff_n(
i,
k) =
a * t_diff_n(
i,
k);
315 ++t_transformed_diff_n;
340 unsigned int nb_gauss_pts = data.
getN(base).size1();
341 unsigned int nb_base_functions = data.
getN(base).size2() / 3;
342 piolaN.resize(nb_gauss_pts, data.
getN(base).size2(),
false);
346 double *t_transformed_n_ptr = &*
piolaN.data().begin();
349 &t_transformed_n_ptr[
HVEC1], &t_transformed_n_ptr[
HVEC2]);
351 double *t_transformed_diff_n_ptr = &*
piolaDiffN.data().begin();
353 t_transformed_diff_n_ptr, &t_transformed_diff_n_ptr[
HVEC0_1],
354 &t_transformed_diff_n_ptr[
HVEC0_2], &t_transformed_diff_n_ptr[
HVEC1_0],
355 &t_transformed_diff_n_ptr[
HVEC1_1], &t_transformed_diff_n_ptr[
HVEC1_2],
356 &t_transformed_diff_n_ptr[
HVEC2_0], &t_transformed_diff_n_ptr[
HVEC2_1],
357 &t_transformed_diff_n_ptr[
HVEC2_2]);
359 auto t_inv_jac = getFTensor2FromMat<3, 3>(*
jacInvPtr);
361 for (
unsigned int gg = 0; gg != nb_gauss_pts; ++gg) {
362 for (
unsigned int bb = 0; bb != nb_base_functions; ++bb) {
363 t_transformed_n(
i) = t_inv_jac(
k,
i) * t_n(
k);
364 t_transformed_diff_n(
i,
k) = t_inv_jac(
j,
i) * t_diff_n(
j,
k);
368 ++t_transformed_diff_n;
381 boost::shared_ptr<MatrixDouble> jac_ptr)
391 const auto nb_gauss_pts = getGaussPts().size2();
393 jacPtr->resize(4, nb_gauss_pts,
false);
394 auto t_jac = getFTensor2FromMat<2, 2>(*jacPtr);
399 auto t_t1 = getFTensor1Tangent1AtGaussPts();
400 auto t_t2 = getFTensor1Tangent2AtGaussPts();
404 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
405 t_jac(
i, N0) = t_t1(
i);
406 t_jac(
i, N1) = t_t2(
i);
424 size_t nb_gauss_pts = getGaussPts().size2();
425 jacPtr->resize(9, nb_gauss_pts,
false);
427 auto t_t1 = getFTensor1Tangent1AtGaussPts();
428 auto t_t2 = getFTensor1Tangent2AtGaussPts();
429 auto t_normal = getFTensor1NormalsAtGaussPts();
435 auto t_jac = getFTensor2FromMat<3, 3>(*jacPtr);
436 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg, ++t_jac) {
438 t_jac(
i, N0) = t_t1(
i);
439 t_jac(
i, N1) = t_t2(
i);
441 const double l = sqrt(t_normal(
j) * t_normal(
j));
443 t_jac(
i, N2) = t_normal(
i) /
l;
458 if (moab::CN::Dimension(type) != 2)
461 auto get_normals_ptr = [&]() {
468 auto apply_transform_nonlinear_geometry = [&](
auto base,
auto nb_gauss_pts,
469 auto nb_base_functions) {
472 auto ptr = get_normals_ptr();
474 &ptr[0], &ptr[1], &ptr[2]);
477 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
478 const auto l2 = t_normal(
i) * t_normal(
i);
479 for (
int bb = 0; bb != nb_base_functions; ++bb) {
480 const auto v = t_base(0);
481 t_base(
i) = (
v / l2) * t_normal(
i);
492 const auto &base_functions = data.
getN(base);
493 const auto nb_gauss_pts = base_functions.size1();
497 const auto nb_base_functions = base_functions.size2() / 3;
498 CHKERR apply_transform_nonlinear_geometry(base, nb_gauss_pts,
510 const auto type_dim = moab::CN::Dimension(type);
511 if (type_dim != 1 && type_dim != 2)
524 &ptr_t1[0], &ptr_t2[0], &ptr_n[0],
526 &ptr_t1[1], &ptr_t2[1], &ptr_n[1],
528 &ptr_t1[2], &ptr_t2[2], &ptr_n[2]);
534 &ptr_t1[0], &ptr_t2[0], &ptr_n[0],
536 &ptr_t1[1], &ptr_t2[1], &ptr_n[1],
538 &ptr_t1[2], &ptr_t2[2], &ptr_n[2]);
546 auto &baseN = data.
getN(base);
547 auto &diffBaseN = data.
getDiffN(base);
549 int nb_dofs = baseN.size2() / 3;
550 int nb_gauss_pts = baseN.size1();
552 piolaN.resize(baseN.size1(), baseN.size2());
553 diffPiolaN.resize(diffBaseN.size1(), diffBaseN.size2());
555 if (nb_dofs > 0 && nb_gauss_pts > 0) {
564 t_transformed_diff_h_curl(
575 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
578 for (
int ll = 0; ll != nb_dofs; ll++) {
579 t_transformed_h_curl(
i) = t_inv_m(
j,
i) * t_h_curl(
j);
580 t_transformed_diff_h_curl(
i,
k) = t_inv_m(
j,
i) * t_diff_h_curl(
j,
k);
582 ++t_transformed_h_curl;
584 ++t_transformed_diff_h_curl;
591 if (cc != nb_gauss_pts * nb_dofs)
616 "Wrong number of integration points %ld!=%ld",
619 auto get_base_at_pts = [&](
auto base) {
626 auto get_tangent_ptr = [&]() {
634 auto get_tangent_at_pts = [&]() {
635 auto ptr = get_tangent_ptr();
637 &ptr[0], &ptr[1], &ptr[2]);
641 auto calculate_squared_edge_length = [&]() {
642 std::vector<double> l1;
644 l1.resize(nb_gauss_pts);
645 auto t_m_at_pts = get_tangent_at_pts();
646 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
647 l1[gg] = t_m_at_pts(
i) * t_m_at_pts(
i);
654 auto l1 = calculate_squared_edge_length();
659 const auto nb_dofs = data.
getN(base).size2() / 3;
661 if (nb_gauss_pts && nb_dofs) {
662 auto t_h_curl = get_base_at_pts(base);
664 auto t_m_at_pts = get_tangent_at_pts();
665 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
666 const double l0 = l1[gg];
667 for (
int ll = 0; ll != nb_dofs; ++ll) {
668 const double val = t_h_curl(0);
669 const double a = val / l0;
670 t_h_curl(
i) = t_m_at_pts(
i) *
a;
678 if (cc != nb_gauss_pts * nb_dofs)
689 boost::shared_ptr<VectorDouble> det_jac_ptr,
690 boost::shared_ptr<double> scale_det_ptr)
691 :
OP(space), fieldSpace(space), fieldBase(base), detJacPtr(det_jac_ptr),
692 scaleDetPtr(scale_det_ptr) {
703 double scale_det = 1.0;
707 auto scale = [&](
auto base) {
709 auto &base_fun = data.
getN(base);
710 if (base_fun.size2()) {
713 const auto nb_int_pts = base_fun.size1();
715 if (nb_int_pts != det_vec.size())
717 "Number of integration pts in detJacPtr does not mush "
718 "number of integration pts in base function");
720 for (
auto gg = 0; gg != nb_int_pts; ++gg) {
721 auto row = ublas::matrix_row<MatrixDouble>(base_fun, gg);
722 row *= scale_det / det_vec[gg];
725 auto &diff_base_fun = data.
getDiffN(base);
726 if (diff_base_fun.size2()) {
727 for (
auto gg = 0; gg != nb_int_pts; ++gg) {
728 auto row = ublas::matrix_row<MatrixDouble>(diff_base_fun, gg);
729 row *= scale_det / det_vec[gg];
771 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
772 std::vector<FieldSpace> spaces, std::string geom_field_name,
773 boost::shared_ptr<MatrixDouble> jac_ptr,
774 boost::shared_ptr<VectorDouble> det_ptr,
775 boost::shared_ptr<MatrixDouble> inv_jac_ptr) {
779 jac_ptr = boost::make_shared<MatrixDouble>();
781 det_ptr = boost::make_shared<VectorDouble>();
783 inv_jac_ptr = boost::make_shared<MatrixDouble>();
785 if (geom_field_name.empty()) {
800 for (
auto s : spaces) {
827 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
828 std::vector<FieldSpace> spaces, std::string geom_field_name,
829 boost::shared_ptr<MatrixDouble> jac_ptr,
830 boost::shared_ptr<VectorDouble> det_ptr,
831 boost::shared_ptr<MatrixDouble> inv_jac_ptr) {
835 jac_ptr = boost::make_shared<MatrixDouble>();
837 det_ptr = boost::make_shared<VectorDouble>();
839 inv_jac_ptr = boost::make_shared<MatrixDouble>();
841 if (geom_field_name.empty()) {
853 for (
auto s : spaces) {
883 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
884 std::vector<FieldSpace> spaces, std::string geom_field_name) {
887 if (geom_field_name.empty()) {
895 for (
auto s : spaces) {
915 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
916 std::vector<FieldSpace> spaces, std::string geom_field_name) {
919 if (geom_field_name.empty()) {
927 for (
auto s : spaces) {
942 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
943 std::vector<FieldSpace> spaces, std::string geom_field_name) {
946 if (geom_field_name.empty()) {
953 for (
auto s : spaces) {
976 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
977 std::vector<FieldSpace> spaces, std::string geom_field_name,
978 boost::shared_ptr<MatrixDouble> jac, boost::shared_ptr<VectorDouble> det,
979 boost::shared_ptr<MatrixDouble> inv_jac) {
983 jac = boost::make_shared<MatrixDouble>();
985 det = boost::make_shared<VectorDouble>();
987 inv_jac = boost::make_shared<MatrixDouble>();
989 if (geom_field_name.empty()) {
1003 for (
auto s : spaces) {
ForcesAndSourcesCore::UserDataOperator UserDataOperator
static MoFEMErrorCode get_jac(EntitiesFieldData::EntData &col_data, int gg, MatrixDouble &jac_stress, MatrixDouble &jac)
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. 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
static const char *const FieldSpaceNames[]
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
OpSetInvJacHcurlFaceImpl< 2 > OpSetInvJacHcurlFace
OpSetContravariantPiolaTransformOnFace2DImpl< 3 > OpSetContravariantPiolaTransformOnFace2DEmbeddedIn3DSpace
OpSetInvJacHcurlFaceImpl< 3 > OpSetInvJacHcurlFaceEmbeddedIn3DSpace
MoFEMErrorCode invertTensor3by3(ublas::matrix< T, L, A > &jac_data, ublas::vector< T, A > &det_data, ublas::matrix< T, L, A > &inv_jac_data)
Calculate inverse of tensor rank 2 at integration points.
OpSetCovariantPiolaTransformOnFace2DImpl< 2 > OpSetCovariantPiolaTransformOnFace2D
OpSetContravariantPiolaTransformOnFace2DImpl< 2 > OpSetContravariantPiolaTransformOnFace2D
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
OpCalculateHOJacForFaceImpl< 3 > OpCalculateHOJacForFaceEmbeddedIn3DSpace
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
constexpr double t
plate stiffness
FTensor::Index< 'm', 3 > m
Add operators pushing bases from local to physical configuration.
std::array< bool, MBMAXTYPE > doEntities
If true operator is executed for entity.
MatrixDouble & getTangentAtGaussPts()
get tangent vector to edge curve at integration points
FTensor::Tensor1< FTensor::PackPtr< double *, 3 >, DIM > getFTensor1TangentAtGaussPts()
Get tangent vector at integration points.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor2< FTensor::PackPtr< double *, Tensor_Dim0 *Tensor_Dim1 >, Tensor_Dim0, Tensor_Dim1 > getFTensor2DiffN(FieldApproximationBase base)
Get derivatives of base functions for Hdiv space.
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
virtual std::array< boost::shared_ptr< MatrixDouble >, MaxBernsteinBezierOrder > & getBBDiffNByOrderArray()
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....
virtual std::map< std::string, boost::shared_ptr< MatrixDouble > > & getBBDiffNMap()
get hash map of derivatives base function for BB base, key is a field name
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
virtual boost::shared_ptr< MatrixDouble > & getDiffNSharedPtr(const FieldApproximationBase base)
virtual boost::shared_ptr< MatrixDouble > & getNSharedPtr(const FieldApproximationBase base, const BaseDerivatives direvatie)
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.
auto getFTensor1NormalsAtGaussPts()
get normal at integration points
MatrixDouble & getTangent1AtGaussPts()
if higher order geometry return tangent vector to triangle at Gauss pts.
auto getFTensor0IntegrationWeight()
Get integration weights.
double getMeasure() const
get measure of element
boost::shared_ptr< const NumeredEntFiniteElement > getNumeredEntFiniteElementPtr() const
Return raw pointer to NumeredEntFiniteElement.
int getFEDim() const
Get dimension of finite element.
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
Calculate HO coordinates at gauss points.
Calculate jacobian for face element.
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)
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Calculate normals at Gauss points of triangle element.
Calculate tangent vector on edge form HO geometry approximation.
Make Hdiv space from Hcurl space in 2d.
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.
OpScaleBaseBySpaceInverseOfMeasure(const FieldSpace space, const FieldApproximationBase base, boost::shared_ptr< VectorDouble > det_jac_ptr, boost::shared_ptr< double > scale_det_ptr=nullptr)
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 function to global derivatives if higher order geometr...
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.
MatrixDouble diffHdivInvJac
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Modify integration weights on face to take in 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.
Set inverse jacobian to base functions.
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
VectorDouble & getCoords()
nodal coordinates
FTensor::Tensor2< double *, 3, 3 > & getInvJac()
get element inverse Jacobian
Volume finite element base.