42#ifndef __USER_DATA_OPERATORS_HPP__
43 #define __USER_DATA_OPERATORS_HPP__
69template <
class T,
class A>
84 boost::shared_ptr<ublas::vector<T, A>> data_ptr,
105 boost::shared_ptr<ublas::vector<T, A>> data_ptr,
112 THROW_MESSAGE(
"Cross-DM field evaluation requires OPROW or OPCOL");
119 boost::shared_ptr<ublas::vector<T, A>> data_ptr,
123 data_vec, zero_type) {}
134 boost::shared_ptr<ublas::vector<T, A>> data_ptr,
135 const EntityType zero_type = MBVERTEX)
151 boost::shared_ptr<ublas::vector<T, A>>
dataPtr;
162template <
class T,
class A>
201 vec.resize(nb_gauss_pts,
false);
228 "Cross-DM field evaluation requires OPROW or OPCOL");
231 for (
size_t i = 0;
i != field_dofs.size(); ++
i) {
233 dofs_by_uid->find(field_dofs[
i]->getLocalUniqueId());
235 (dof_it != dofs_by_uid->end())
236 ? array[(*dof_it)->getPetscLocalDofIdx()]
241 for (
size_t i = 0;
i != local_indices.size(); ++
i)
242 if (local_indices[
i] != -1)
251 const size_t nb_base_functions = data.
getN().size2();
254 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
257 for (; bb != nb_dofs; ++bb) {
258 values_at_gauss_pts += field_data * base_function;
263 for (; bb < nb_base_functions; ++bb)
265 ++values_at_gauss_pts;
288template <PetscData::DataContext CTX>
300 const std::string
field_name, boost::shared_ptr<VectorDouble> data_ptr,
301 const EntityType zero_at_type = MBVERTEX)
317 vec.resize(nb_gauss_pts,
false);
322 const size_t nb_dofs = local_indices.size();
327 auto get_array = [&](
const auto ctx,
auto vec) {
333 <<
"In this case field degrees of freedom are read from vector. "
334 "That usually happens when time solver is used, and acces to "
335 "first or second rates is needed. You probably not set ts_u, "
336 "ts_u_t, or ts_u_tt and associated data structure, i.e. "
337 "data_ctx to CTX_SET_X, CTX_SET_X_T, or CTX_SET_X_TT "
342 CHKERR VecGetArrayRead(vec, &array);
346 auto restore_array = [&](
auto vec) {
347 return VecRestoreArrayRead(vec, &array);
362 "That case is not implemented");
365 std::array<double, MAX_DOFS_ON_ENTITY> dot_dofs_vector;
366 for (
int i = 0;
i != local_indices.size(); ++
i)
367 if (local_indices[
i] != -1)
368 dot_dofs_vector[
i] = array[local_indices[
i]];
370 dot_dofs_vector[
i] = 0;
384 "That case is not implemented");
387 const size_t nb_base_functions = data.
getN().size2();
391 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
393 for (; bb != nb_dofs; ++bb) {
394 values_at_gauss_pts += dot_dofs_vector[bb] * base_function;
399 for (; bb < nb_base_functions; ++bb)
401 ++values_at_gauss_pts;
439template <
int Tensor_Dim,
typename M = MatrixDouble>
452 boost::shared_ptr<M> data_ptr,
453 const EntityType zero_type = MBVERTEX)
476template <
int Tensor_Dim,
typename M>
482 "Not implemented for matrix type = %s and dim = %d",
492template <
int Tensor_Dim>
497 boost::shared_ptr<MatrixDouble> data_ptr,
498 const EntityType zero_type = MBVERTEX,
499 const int max_order = -1)
508 boost::shared_ptr<MatrixDouble> data_ptr,
510 const EntityType zero_type = MBVERTEX,
511 const int max_order = -1)
515 maxOrder(max_order) {
523 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
525 const int max_order = -1)
527 dataPtr(data_ptr), dataVec(data_vec), dataDm(data_dm),
528 zeroType(zero_type), maxOrder(max_order) {
531 THROW_MESSAGE(
"Cross-DM field evaluation requires OPROW or OPCOL");
552template <
int Tensor_Dim>
558 const size_t nb_gauss_pts = getGaussPts().size2();
559 auto &mat = *dataPtr;
562 auto get_values_at_gauss_pts =
565 if (
type == zeroType) {
574 const auto max_size =
578 if (dataVec.use_count()) {
579 dotVector.resize(nb_dofs,
false);
581 CHKERR VecGetArrayRead(dataVec, &array);
586 switch (getOpType()) {
595 "Cross-DM field evaluation requires OPROW or OPCOL");
598 for (
size_t i = 0;
i != field_dofs.size(); ++
i) {
600 dofs_by_uid->find(field_dofs[
i]->getLocalUniqueId());
601 dotVector[
i] = (dof_it != dofs_by_uid->end())
602 ? array[(*dof_it)->getPetscLocalDofIdx()]
607 for (
size_t i = 0;
i != local_indices.size(); ++
i)
608 if (local_indices[
i] != -1)
609 dotVector[
i] = array[local_indices[
i]];
613 CHKERR VecRestoreArrayRead(dataVec, &array);
618 const size_t nb_base_functions = data.
getN().size2();
620 auto t_values_at_gauss_pts = get_values_at_gauss_pts();
622 const size_t size = nb_dofs / Tensor_Dim;
623 if (nb_dofs % Tensor_Dim) {
625 "Nb. of DOFs is inconsistent with Tensor_Dim");
627 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
631 if (field_data.l2() != field_data.l2()) {
632 MOFEM_LOG(
"SELF", Sev::error) <<
"field data: " << field_data;
634 "Wrong number in coefficients");
639 for (; bb !=
size; ++bb) {
643 if (base_function != base_function) {
644 MOFEM_LOG(
"SELF", Sev::error) <<
"base function: " << base_function;
646 "Wrong number number in base functions");
651 if (bb <= max_size) {
652 t_values_at_gauss_pts(
I) += field_data(
I) * base_function;
659 for (; bb < nb_base_functions; ++bb)
661 ++t_values_at_gauss_pts;
665 if (dataVec.use_count()) {
683template <
int Tensor_Dim>
688 Tensor_Dim>::OpCalculateVectorFieldValues_General;
707template <
int Tensor_Dim, CoordinateTypes COORDINATE_SYSTEM = CARTESIAN>
719 const std::string
field_name, boost::shared_ptr<VectorDouble> data_ptr,
720 const EntityType zero_type = MBVERTEX)
733 if constexpr (COORDINATE_SYSTEM ==
POLAR || COORDINATE_SYSTEM ==
SPHERICAL)
735 "%s coordiante not implemented",
741 vec.resize(nb_gauss_pts,
false);
749 const size_t nb_base_functions = data.
getN().size2();
752 const size_t size = nb_dofs / Tensor_Dim;
754 if (nb_dofs % Tensor_Dim) {
756 "Number of dofs should multiple of dimensions");
761 if constexpr (COORDINATE_SYSTEM ==
CARTESIAN) {
763 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
766 for (; bb !=
size; ++bb) {
767 values_at_gauss_pts += field_data(
I) * diff_base_function(
I);
769 ++diff_base_function;
773 for (; bb < nb_base_functions; ++bb)
774 ++diff_base_function;
775 ++values_at_gauss_pts;
785 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
788 for (; bb !=
size; ++bb) {
789 values_at_gauss_pts += field_data(
I) * diff_base_function(
I);
790 values_at_gauss_pts +=
791 base_function * (field_data(0) / t_coords(0));
794 ++diff_base_function;
798 for (; bb < nb_base_functions; ++bb) {
800 ++diff_base_function;
802 ++values_at_gauss_pts;
823template <
int Tensor_Dim, PetscData::DataContext CTX>
828 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
829 const EntityType zero_at_type = MBVERTEX,
bool throw_error =
true)
842 const size_t nb_dofs = local_indices.size();
847 auto get_values_at_gauss_pts =
849 DL>
::size(mat, nb_gauss_pts);
864 auto get_array = [&](
const auto ctx,
auto vec) {
870 <<
"In this case field degrees of freedom are read from vector. "
871 "That usually happens when time solver is used, and access to "
872 "first or second rates is needed. You probably not set ts_u, "
873 "ts_u_t, or ts_u_tt and associated data structure, i.e. "
874 "data_ctx to CTX_SET_X, CTX_SET_DX, CTX_SET_X_T, or "
875 "CTX_SET_X_TT respectively";
879 CHKERR VecGetArrayRead(vec, &array);
883 auto restore_array = [&](
auto vec) {
884 return VecRestoreArrayRead(vec, &array);
902 "That case is not implemented");
906 for (
int i = 0;
i != local_indices.size(); ++
i)
907 if (local_indices[
i] != -1)
927 "That case is not implemented");
930 const size_t nb_base_functions = data.
getN().size2();
932 auto t_values_at_gauss_pts = get_values_at_gauss_pts();
935 const size_t size = nb_dofs / Tensor_Dim;
936 if (nb_dofs % Tensor_Dim) {
939 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
940 auto field_data = getFTensor1FromArray<Tensor_Dim, Tensor_Dim>(
dotVector);
942 for (; bb !=
size; ++bb) {
943 t_values_at_gauss_pts(
I) += field_data(
I) * base_function;
949 for (; bb < nb_base_functions; ++bb)
951 ++t_values_at_gauss_pts;
968template <
int Tensor_Dim>
978template <
int Tensor_Dim>
988template <
int Tensor_Dim>
1002template <
int Tensor_Dim0,
int Tensor_Dim1,
typename M = MatrixDouble>
1008 boost::shared_ptr<M> data_ptr,
1009 const EntityType zero_type = MBVERTEX)
1025template <
int Tensor_Dim0,
int Tensor_Dim1,
typename M>
1031 "Not implemented for matrix type = %s, dim0 = %d and dim1 = %d",
1033 Tensor_Dim0, Tensor_Dim1);
1037template <
int Tensor_Dim0,
int Tensor_Dim1>
1044 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
1053 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
1054 const EntityType zero_type = MBVERTEX)
1060 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
1064 data_vec, zero_type) {}
1076template <
int Tensor_Dim0,
int Tensor_Dim1>
1084 const size_t nb_gauss_pts = data.
getN().size1();
1085 auto get_values_at_gauss_pts =
1087 DL>
::size(mat, nb_gauss_pts);
1088 if (
type == zeroType)
1093 if (dataVec.use_count()) {
1094 dotVector.resize(nb_dofs,
false);
1095 const double *array;
1096 CHKERR VecGetArrayRead(dataVec, &array);
1098 for (
int i = 0;
i != local_indices.size(); ++
i)
1099 if (local_indices[
i] != -1)
1100 dotVector[
i] = array[local_indices[
i]];
1103 CHKERR VecRestoreArrayRead(dataVec, &array);
1108 const size_t nb_base_functions = data.
getN().size2();
1110 auto t_values_at_gauss_pts = get_values_at_gauss_pts();
1113 const size_t size = nb_dofs / (Tensor_Dim0 * Tensor_Dim1);
1114 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1117 for (; bb !=
size; ++bb) {
1118 t_values_at_gauss_pts(
i,
j) += field_data(
i,
j) * base_function;
1122 for (; bb < nb_base_functions; ++bb)
1124 ++t_values_at_gauss_pts;
1127 if (dataVec.use_count()) {
1139template <
int Tensor_Dim0,
int Tensor_Dim1>
1145 Tensor_Dim0, Tensor_Dim1>::OpCalculateTensor2FieldValues_General;
1153template <
int Tensor_Dim0,
int Tensor_Dim1>
1158 boost::shared_ptr<MatrixDouble> data_ptr,
1159 const EntityType zero_at_type = MBVERTEX)
1172 const size_t nb_gauss_pts =
getGaussPts().size2();
1174 auto get_values_at_gauss_pts =
1177 DL>
::size(mat, nb_gauss_pts);
1181 const size_t nb_dofs = local_indices.size();
1184 const double *array;
1186 for (
size_t i = 0;
i != local_indices.size(); ++
i)
1187 if (local_indices[
i] != -1)
1193 const size_t nb_base_functions = data.
getN().size2();
1196 auto t_values_at_gauss_pts = get_values_at_gauss_pts();
1199 const size_t size = nb_dofs / (Tensor_Dim0 * Tensor_Dim1);
1200 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1202 getFTensor2FromPtr<Tensor_Dim0, Tensor_Dim1>(&*
dotVector.begin());
1204 for (; bb !=
size; ++bb) {
1205 t_values_at_gauss_pts(
i,
j) += field_data(
i,
j) * base_function;
1209 for (; bb < nb_base_functions; ++bb)
1211 ++t_values_at_gauss_pts;
1230template <
int Tensor_Dim>
1235 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
1236 const EntityType zero_type = MBEDGE,
const int zero_side = 0)
1245 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
1247 const int zero_side = 0)
1259 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
1261 const int zero_side = 0)
1267 THROW_MESSAGE(
"Cross-DM field evaluation requires OPROW or OPCOL");
1278 auto get_values_at_gauss_pts =
1280 DL>
::size(mat, nb_gauss_pts);
1290 const double *array;
1305 "Cross-DM field evaluation requires OPROW or OPCOL");
1308 for (
int i = 0;
i != field_dofs.size(); ++
i) {
1310 dofs_by_uid->find(field_dofs[
i]->getLocalUniqueId());
1311 dotVector[
i] = (dof_it != dofs_by_uid->end())
1312 ? array[(*dof_it)->getPetscLocalDofIdx()]
1317 for (
int i = 0;
i != local_indices.size(); ++
i)
1318 if (local_indices[
i] != -1)
1327 const int nb_base_functions = data.
getN().size2();
1329 auto t_values_at_gauss_pts = get_values_at_gauss_pts();
1332 const int size = nb_dofs / ((Tensor_Dim * (Tensor_Dim + 1)) / 2);
1333 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1336 for (; bb !=
size; ++bb) {
1337 t_values_at_gauss_pts(
i,
j) += field_data(
i,
j) * base_function;
1341 for (; bb < nb_base_functions; ++bb)
1343 ++t_values_at_gauss_pts;
1369 static const auto t_basis = [] {
1373 t_basis(
i,
j,
A) = 0.;
1374 constexpr double inverse_sqrt_two = 0.70710678118654752440;
1375 constexpr double inverse_sqrt_six = 0.40824829046386301637;
1376 t_basis(0, 0, 0) = inverse_sqrt_two;
1377 t_basis(1, 1, 0) = -inverse_sqrt_two;
1378 t_basis(0, 0, 1) = inverse_sqrt_six;
1379 t_basis(1, 1, 1) = inverse_sqrt_six;
1380 t_basis(2, 2, 1) = -2. * inverse_sqrt_six;
1381 t_basis(0, 1, 2) = inverse_sqrt_two;
1382 t_basis(0, 2, 3) = inverse_sqrt_two;
1383 t_basis(1, 2, 4) = inverse_sqrt_two;
1390 template <
typename T,
int Size>
1393 const double theta = 0.) {
1394 static_assert(Size == 3 || Size == 5,
"Expected three or five coordinates");
1401 t_basis(
i,
j,
A) * t_coordinates(
A) + (theta / 3.) * t_identity(
i,
j);
1406 template <
typename Tensor>
1412 t_coordinates(
A) = t_basis(
i,
j,
A) * t_tensor(
i,
j);
1413 return t_coordinates;
1423template <
int CoordinateSize>
1426 static_assert(CoordinateSize == 3 || CoordinateSize == 5,
1427 "Expected three or five deviator coordinates");
1433 const EntityType zero_type = MBEDGE,
const int zero_side = 0)
1440 const int zero_side = 0,
MatrixPtr coordinates =
nullptr)
1442 data_vec, MBMAXTYPE),
1453 const int zero_side = 0,
MatrixPtr coordinates =
nullptr)
1455 coordinates ? coordinates : boost::make_shared<
MatrixDouble>(),
1456 data_vec, MBMAXTYPE),
1466 const int nb_gauss_pts = this->
getGaussPts().size2();
1470 *this->
dataPtr, nb_gauss_pts);
1475 auto get_coordinates =
1477 *this->
dataPtr, nb_gauss_pts);
1481 auto t_coordinates = get_coordinates();
1482 auto t_tensor = get_tensor();
1484 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1486 t_tensor(
i,
j) = t_deviator(
i,
j);
1510 3>::OpCalculateTensor2SymmetricDeviatorFieldValues_General;
1518 5>::OpCalculateTensor2SymmetricDeviatorFieldValues_General;
1528template <
int Tensor_Dim>
1533 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
1534 const EntityType zero_type = MBEDGE,
const int zero_side = 0)
1547 constexpr auto symm_size = (Tensor_Dim * (Tensor_Dim + 1)) / 2;
1549 auto get_values_at_gauss_pts =
1551 DL>
::size(mat, nb_gauss_pts);
1556 const int nb_dofs = local_indices.size();
1564 <<
"In this case field degrees of freedom are read from vector. "
1565 "That usually happens when time solver is used, and acces to "
1566 "first rates is needed. You probably not set "
1567 "ts_u_t and associated data structure data_ctx to CTX_SET_X_T "
1574 const double *array;
1576 for (
int i = 0;
i != local_indices.size(); ++
i)
1577 if (local_indices[
i] != -1)
1583 const int nb_base_functions = data.
getN().size2();
1586 auto t_values_at_gauss_pts = get_values_at_gauss_pts();
1589 const int size = nb_dofs / symm_size;
1590 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1591 auto field_data = getFTensorDotData<Tensor_Dim>();
1593 for (; bb !=
size; ++bb) {
1594 t_values_at_gauss_pts(
i,
j) += field_data(
i,
j) * base_function;
1598 for (; bb < nb_base_functions; ++bb)
1600 ++t_values_at_gauss_pts;
1613 static_assert(Dim || !Dim,
"not implemented");
1622 &dotVector[0], &dotVector[1], &dotVector[2], &dotVector[3], &dotVector[4],
1631 &dotVector[0], &dotVector[1], &dotVector[2]);
1645template <
int Tensor_Dim,
typename M = MatrixDouble>
1650 Tensor_Dim,
M>::OpCalculateVectorFieldValues_General;
1657template <
int Tensor_Dim>
1662 Tensor_Dim,
MatrixDouble>::OpCalculateVectorFieldValues_General;
1680template <
int Tensor_Dim>
1686 const size_t nb_gauss_pts = this->getGaussPts().size2();
1687 auto &mat = *this->dataPtr;
1689 auto get_gradients_at_pts =
1691 DL>
::size(mat, nb_gauss_pts);
1692 if (
type == this->zeroType) {
1700 const int nb_base_functions = data.
getN().size2();
1702 auto t_gradients_at_pts = get_gradients_at_pts();
1705 if (nb_dofs > nb_base_functions)
1707 "Number of base functions inconsistent with number of DOFs "
1709 nb_dofs, nb_base_functions);
1711 if (data.
getDiffN().size2() != nb_base_functions * Tensor_Dim)
1714 "Number of base functions inconsistent with number of derivatives "
1716 data.
getDiffN().size2(), nb_base_functions);
1718 if (data.
getDiffN().size1() != nb_gauss_pts)
1721 "Number of base functions inconsistent with number of integration "
1723 data.
getDiffN().size1(), nb_gauss_pts);
1728 for (
int gg = 0; gg < nb_gauss_pts; ++gg) {
1731 for (; bb != nb_dofs; ++bb) {
1732 t_gradients_at_pts(
I) += field_data * diff_base_function(
I);
1734 ++diff_base_function;
1737 for (; bb < nb_base_functions; ++bb)
1738 ++diff_base_function;
1739 ++t_gradients_at_pts;
1752template <
int Tensor_Dim>
1756 Tensor_Dim>::OpCalculateScalarFieldGradient_General;
1763template <
int Tensor_Dim>
1768 Tensor_Dim>::OpCalculateVectorFieldValues_General;
1781template <
int Tensor_Dim>
1786 const size_t nb_gauss_pts = this->getGaussPts().size2();
1788 auto &mat = *this->dataPtr;
1789 auto get_hessian_at_gauss_pts =
1791 DL>
::size(mat, nb_gauss_pts);
1792 if (
type == this->zeroType)
1799 const int nb_base_functions = data.
getN().size2();
1801 auto &hessian_base = data.
getN(BaseDerivatives::SecondDerivative);
1803 if (hessian_base.size1() != nb_gauss_pts) {
1805 "Wrong number of integration pts (%ld != %ld)",
1806 static_cast<long>(hessian_base.size1()),
1807 static_cast<long>(nb_gauss_pts));
1809 if (hessian_base.size2() != nb_base_functions * Tensor_Dim * Tensor_Dim) {
1811 "Wrong number of base functions (%ld != %ld)",
1812 static_cast<long>(hessian_base.size2() /
1813 (Tensor_Dim * Tensor_Dim)),
1814 static_cast<long>(nb_base_functions));
1816 if (hessian_base.size2() < nb_dofs * Tensor_Dim * Tensor_Dim) {
1818 "Wrong number of base functions (%ld < %ld)",
1819 static_cast<long>(hessian_base.size2()),
1820 static_cast<long>(nb_dofs * Tensor_Dim * Tensor_Dim));
1824 auto t_diff2_base_function = getFTensor2FromPtr<Tensor_Dim, Tensor_Dim>(
1825 &*hessian_base.data().begin());
1827 auto t_hessian_at_gauss_pts = get_hessian_at_gauss_pts();
1831 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1834 for (; bb != nb_dofs; ++bb) {
1835 t_hessian_at_gauss_pts(
I,
J) +=
1836 field_data * t_diff2_base_function(
I,
J);
1838 ++t_diff2_base_function;
1841 for (; bb < nb_base_functions; ++bb) {
1842 ++t_diff2_base_function;
1845 ++t_hessian_at_gauss_pts;
1869template <
int Tensor_Dim0,
int Tensor_Dim1,
int S,
1876 Tensor_Dim0, Tensor_Dim1,
M>::OpCalculateTensor2FieldValues_General;
1879template <
int Tensor_Dim0,
int Tensor_Dim1,
int S>
1883 Tensor_Dim0, Tensor_Dim1, MatrixDouble> {
1886 Tensor_Dim0, Tensor_Dim1,
MatrixDouble>::OpCalculateTensor2FieldValues_General;
1904template <
int Tensor_Dim0,
int Tensor_Dim1,
int S>
1911 "Data pointer not allocated");
1913 const size_t nb_gauss_pts = this->getGaussPts().size2();
1915 auto &mat = *this->dataPtr;
1916 auto get_gradients_at_pts =
1919 DL>
::size(mat, nb_gauss_pts);
1920 if (
type == this->zeroType)
1928 if (this->dataVec.use_count()) {
1929 this->dotVector.resize(nb_dofs,
false);
1930 const double *array;
1931 CHKERR VecGetArrayRead(this->dataVec, &array);
1933 for (
int i = 0;
i != local_indices.size(); ++
i)
1934 if (local_indices[
i] != -1)
1935 this->dotVector[
i] = array[local_indices[
i]];
1937 this->dotVector[
i] = 0;
1938 CHKERR VecRestoreArrayRead(this->dataVec, &array);
1942 const int nb_base_functions = data.
getN().size2();
1944 auto t_gradients_at_pts = get_gradients_at_pts();
1947 int size = nb_dofs / Tensor_Dim0;
1948 if (nb_dofs % Tensor_Dim0) {
1950 "Data inconsistency");
1952 for (
int gg = 0; gg < nb_gauss_pts; ++gg) {
1953 auto field_data = getFTensor1FromPtr<Tensor_Dim0, S>(
1957 if (field_data.l2() != field_data.l2()) {
1958 MOFEM_LOG(
"SELF", Sev::error) <<
"field data " << field_data;
1960 "Wrong number in coefficients");
1965 for (; bb <
size; ++bb) {
1968 if (diff_base_function.l2() != diff_base_function.l2()) {
1970 <<
"diff_base_function: " << diff_base_function;
1972 "Wrong number number in base functions");
1977 t_gradients_at_pts(
I,
J) += field_data(
I) * diff_base_function(
J);
1979 ++diff_base_function;
1983 for (; bb != nb_base_functions; ++bb)
1984 ++diff_base_function;
1985 ++t_gradients_at_pts;
1988 if (this->dataVec.use_count()) {
2005template <
int Tensor_Dim0,
int Tensor_Dim1,
int S = Tensor_Dim0>
2011 Tensor_Dim0, Tensor_Dim1, S>::OpCalculateVectorFieldGradient_General;
2019template <
int Tensor_Dim0,
int Tensor_Dim1>
2024 boost::shared_ptr<MatrixDouble> data_ptr,
2025 const EntityType zero_at_type = MBVERTEX)
2038 const int nb_dofs = local_indices.size();
2039 const int nb_gauss_pts = this->
getGaussPts().size2();
2043 auto get_gradients_at_pts =
2046 DL>
::size(mat, nb_gauss_pts);
2053 const double *array;
2055 for (
int i = 0;
i != local_indices.size(); ++
i)
2056 if (local_indices[
i] != -1)
2062 const int nb_base_functions = data.
getN().size2();
2064 auto t_gradients_at_pts = get_gradients_at_pts();
2067 int size = nb_dofs / Tensor_Dim0;
2068 if (nb_dofs % Tensor_Dim0) {
2072 for (
int gg = 0; gg < nb_gauss_pts; ++gg) {
2073 auto field_data = getFTensor1FromPtr<Tensor_Dim0>(&*
dotVector.begin());
2075 for (; bb <
size; ++bb) {
2076 t_gradients_at_pts(
I,
J) += field_data(
I) * diff_base_function(
J);
2078 ++diff_base_function;
2082 for (; bb != nb_base_functions; ++bb)
2083 ++diff_base_function;
2084 ++t_gradients_at_pts;
2100template <
int Tensor_Dim0,
int Tensor_Dim1,
typename M = MatrixDouble>
2106 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
2107 const EntityType zero_type = MBVERTEX)
2112template <
int Tensor_Dim0,
int Tensor_Dim1>
2117 Tensor_Dim0, Tensor_Dim1, MatrixDouble> {
2120 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
2121 const EntityType zero_type = MBVERTEX)
2142template <
int Tensor_Dim0,
int Tensor_Dim1>
2149 "Data pointer not allocated");
2151 const size_t nb_gauss_pts = this->getGaussPts().size2();
2152 constexpr size_t msize = (Tensor_Dim0 * (Tensor_Dim0 + 1)) / 2;
2153 auto &mat = *this->dataPtr;
2154 if (
type == this->zeroType) {
2155 mat.resize(msize * Tensor_Dim1, nb_gauss_pts,
false);
2164 const int nb_base_functions = data.
getN().size2();
2166 auto gradients_at_pts =
2172 int size = nb_dofs / msize;
2173 if (nb_dofs % msize) {
2175 "Data inconsistency");
2177 for (
int gg = 0; gg < nb_gauss_pts; ++gg) {
2180 for (; bb <
size; ++bb) {
2181 gradients_at_pts(
I,
J,
K) +=
2182 field_data(
I,
J) * diff_base_function(
K);
2184 ++diff_base_function;
2188 for (; bb != nb_base_functions; ++bb)
2189 ++diff_base_function;
2202template <
int Tensor_Dim0,
int Tensor_Dim1>
2205 Tensor_Dim0, Tensor_Dim1> {
2208 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
2209 const EntityType zero_type = MBVERTEX)
2211 Tensor_Dim0, Tensor_Dim1>(
field_name, data_ptr, zero_type) {}
2214template <
int Tensor_Dim0,
int Tensor_Dim1>
2220 Tensor_Dim0, Tensor_Dim1>::OpCalculateTensor2FieldValues_General;
2238template <
int Tensor_Dim0,
int Tensor_Dim1>
2244 "Data pointer not allocated");
2246 const size_t nb_gauss_pts = this->getGaussPts().size2();
2247 auto &mat = *this->dataPtr;
2251 DL>
::size(mat, nb_gauss_pts);
2252 if (
type == this->zeroType) {
2261 if (this->dataVec.use_count()) {
2262 this->dotVector.resize(nb_dofs,
false);
2263 const double *array;
2264 CHKERR VecGetArrayRead(this->dataVec, &array);
2266 for (
int i = 0;
i != local_indices.size(); ++
i)
2267 if (local_indices[
i] != -1)
2268 this->dotVector[
i] = array[local_indices[
i]];
2270 this->dotVector[
i] = 0;
2271 CHKERR VecRestoreArrayRead(this->dataVec, &array);
2275 const int nb_base_functions = data.
getN().size2();
2277 auto &hessian_base = data.
getN(BaseDerivatives::SecondDerivative);
2279 if (hessian_base.size1() != nb_gauss_pts) {
2281 "Wrong number of integration pts (%ld != %ld)",
2282 static_cast<long>(hessian_base.size1()),
2283 static_cast<long>(nb_gauss_pts));
2285 if (hessian_base.size2() !=
2286 nb_base_functions * Tensor_Dim1 * Tensor_Dim1) {
2288 "Wrong number of base functions (%ld != %ld)",
2289 static_cast<long>(hessian_base.size2() /
2290 (Tensor_Dim1 * Tensor_Dim1)),
2291 static_cast<long>(nb_base_functions));
2293 if (hessian_base.size2() <
2294 (nb_dofs / Tensor_Dim0) * Tensor_Dim1 * Tensor_Dim1) {
2296 "Wrong number of base functions (%ld < %ld)",
2297 static_cast<long>(hessian_base.size2()),
2298 static_cast<long>((nb_dofs / Tensor_Dim0) * Tensor_Dim1 *
2303 auto t_diff2_base_function = getFTensor2FromPtr<Tensor_Dim1, Tensor_Dim1>(
2304 &*hessian_base.data().begin());
2306 auto t_hessian_at_gauss_pts = get_hessian_at_gauss_pts();
2312 int size = nb_dofs / Tensor_Dim0;
2314 if (nb_dofs % Tensor_Dim0) {
2316 "Data inconsistency");
2320 for (
int gg = 0; gg < nb_gauss_pts; ++gg) {
2323 for (; bb <
size; ++bb) {
2324 t_hessian_at_gauss_pts(
I,
J,
K) +=
2325 field_data(
I) * t_diff2_base_function(
J,
K);
2327 ++t_diff2_base_function;
2331 for (; bb != nb_base_functions; ++bb)
2332 ++t_diff2_base_function;
2333 ++t_hessian_at_gauss_pts;
2336 if (this->dataVec.use_count()) {
2358template <
int DIM_01,
int DIM_23,
int S = 0>
2370 boost::shared_ptr<MatrixDouble> in_mat,
2371 boost::shared_ptr<MatrixDouble> out_mat,
2372 boost::shared_ptr<MatrixDouble> d_mat)
2385 boost::shared_ptr<MatrixDouble> out_mat,
2386 boost::shared_ptr<MatrixDouble> d_mat)
2399 const size_t nb_gauss_pts =
getGaussPts().size2();
2403 DL>::get(*
dMat, nb_gauss_pts);
2404 auto get_in_at_pts =
2406 DL>::get(*
inMat, nb_gauss_pts);
2407 auto get_out_at_pts =
2410 auto t_D_at_pts = get_D_at_pts();
2411 auto t_in_at_pts = get_in_at_pts();
2412 auto t_out_at_pts = get_out_at_pts();
2413 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
2414 t_out_at_pts(
i,
j) = t_D_at_pts(
i,
j,
k,
l) * t_in_at_pts(
k,
l);
2430 boost::shared_ptr<MatrixDouble>
dMat;
2453 boost::shared_ptr<MatrixDouble> in_mat,
2454 boost::shared_ptr<MatrixDouble> out_mat)
2471 boost::shared_ptr<MatrixDouble> out_mat)
2482 const size_t nb_gauss_pts =
getGaussPts().size2();
2484 auto get_in_at_pts =
2486 *
inMat, nb_gauss_pts);
2487 auto t_in_at_pts = get_in_at_pts();
2488 auto get_out_at_pts =
2491 auto t_out_at_pts = get_out_at_pts();
2492 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
2493 t_out_at_pts(
i,
j) = (t_in_at_pts(
i,
j) || t_in_at_pts(
j,
i)) / 2;
2524 boost::shared_ptr<MatrixDouble> in_mat,
2525 boost::shared_ptr<MatrixDouble> out_mat)
2544 boost::shared_ptr<MatrixDouble> in_mat,
2545 boost::shared_ptr<MatrixDouble> out_mat)
2559 noalias(*
outMat) = (*scalePtr) * (*inMat);
2578template <
int Base_Dim,
int Field_Dim,
typename M = MatrixDouble>
2584template <
int Field_Dim>
2589 boost::shared_ptr<MatrixDouble> data_ptr,
2591 const EntityType zero_type = MBEDGE,
2592 const int zero_side = 0)
2595 dataPtr(data_ptr), dataVec(data_vec), zeroType(zero_type),
2596 zeroSide(zero_side) {
2602 boost::shared_ptr<MatrixDouble> data_ptr,
2603 const EntityType zero_type = MBEDGE,
2604 const int zero_side = 0)
2626template <
int Field_Dim>
2631 const size_t nb_integration_points = this->getGaussPts().size2();
2632 auto &mat = *dataPtr;
2634 auto get_data_at_pts =
2636 DL>
::size(mat, nb_integration_points);
2637 if (
type == zeroType && side == zeroSide) {
2644 if (dataVec.use_count()) {
2645 dotVector.resize(nb_dofs,
false);
2646 const double *array;
2647 CHKERR VecGetArrayRead(dataVec, &array);
2649 for (
int i = 0;
i != local_indices.size(); ++
i)
2650 if (local_indices[
i] != -1)
2651 dotVector[
i] = array[local_indices[
i]];
2654 CHKERR VecRestoreArrayRead(dataVec, &array);
2658 const size_t nb_base_functions = data.
getN().size2() / 3;
2661 auto t_data_at_pts = get_data_at_pts();
2662 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
2665 for (; bb != nb_dofs; ++bb) {
2666 t_data_at_pts(
i) += t_n_hdiv(
i) * t_dof;
2670 for (; bb != nb_base_functions; ++bb)
2675 if (dataVec.use_count()) {
2685template <
int Base_Dim,
int Field_Dim = Base_Dim>
2689 Base_Dim, Field_Dim>::OpCalculateHVecVectorField_General;
2695template <
int Base_Dim,
int Field_Dim = Base_Dim>
2698template <
int Field_Dim>
2703 boost::shared_ptr<MatrixDouble> data_ptr,
2704 const EntityType zero_type = MBEDGE,
2705 const int zero_side = 0)
2708 dataPtr(data_ptr), zeroType(zero_type), zeroSide(zero_side) {
2729template <
int Field_Dim>
2734 const size_t nb_integration_points = this->getGaussPts().size2();
2735 auto &mat = *dataPtr;
2737 auto get_data_at_pts =
2739 DL>
::size(mat, nb_integration_points);
2740 if (
type == zeroType && side == zeroSide) {
2745 const size_t nb_dofs = local_indices.size();
2748 std::array<double, MAX_DOFS_ON_ENTITY> dot_dofs_vector;
2749 const double *array;
2750 CHKERR VecGetArrayRead(getFEMethod()->ts_u_t, &array);
2751 for (
size_t i = 0;
i != nb_dofs; ++
i)
2752 if (local_indices[
i] != -1)
2753 dot_dofs_vector[
i] = array[local_indices[
i]];
2755 dot_dofs_vector[
i] = 0;
2756 CHKERR VecRestoreArrayRead(getFEMethod()->ts_u_t, &array);
2758 const size_t nb_base_functions = data.
getN().size2() / 3;
2761 auto t_data_at_pts = get_data_at_pts();
2762 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
2764 for (; bb != nb_dofs; ++bb) {
2765 t_data_at_pts(
i) += t_n_hdiv(
i) * dot_dofs_vector[bb];
2768 for (; bb != nb_base_functions; ++bb)
2784template <
int BASE_DIM,
int SPACE_DIM>
2789 boost::shared_ptr<VectorDouble> data_ptr,
2790 const EntityType zero_type = MBEDGE,
2791 const int zero_side = 0)
2802 const size_t nb_integration_points =
getGaussPts().size2();
2804 dataPtr->resize(nb_integration_points,
false);
2810 const size_t nb_base_functions = data.
getN().size2() /
BASE_DIM;
2815 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
2818 for (; bb != nb_dofs; ++bb) {
2819 t_data += t_dof * t_n_diff_hdiv(
j,
j);
2823 for (; bb != nb_base_functions; ++bb)
2843template <
int BASE_DIM,
int SPACE_DIM>
2848 boost::shared_ptr<MatrixDouble> data_ptr,
2849 const EntityType zero_type = MBEDGE,
2850 const int zero_side = 0)
2861 const size_t nb_integration_points =
getGaussPts().size2();
2863 auto get_data_at_pts =
2872 const size_t nb_base_functions = data.
getN().size2() /
BASE_DIM;
2876 auto t_data_at_pts = get_data_at_pts();
2877 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
2880 for (; bb != nb_dofs; ++bb) {
2881 t_data_at_pts(
i,
j) += t_dof * t_base_diff(
i,
j);
2885 for (; bb != nb_base_functions; ++bb)
2906template <
int BASE_DIM,
int FIELD_DIM,
int SPACE_DIM>
2919 boost::shared_ptr<MatrixDouble> data_ptr,
2920 const EntityType zero_type = MBEDGE,
2921 const int zero_side = 0)
2924 dataPtr(data_ptr), zeroType(zero_type), zeroSide(zero_side) {
2933 const size_t nb_integration_points = getGaussPts().size2();
2935 auto get_data_at_pts =
2937 DL>
::size(*dataPtr, nb_integration_points);
2938 if (
type == zeroType && side == zeroSide) {
2946 "Data inconsistency, nb_dofs %% COEFF_DIM != 0, that is %ld %% %d "
2956 const size_t nb_base_functions = data.
getN().size2() / 3;
2962 auto t_data_at_pts = get_data_at_pts();
2963 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
2966 for (; bb != nb_dofs; ++bb) {
2967 t_data_at_pts(
k,
i,
j) += t_base_diff(
i,
j) * t_dof(
k);
2971 for (; bb != nb_base_functions; ++bb)
2989 boost::shared_ptr<MatrixDouble> data_ptr,
2990 const EntityType zero_type = MBEDGE,
2991 const int zero_side = 0)
2994 dataPtr(data_ptr), zeroType(zero_type), zeroSide(zero_side) {
3003 const size_t nb_integration_points = getGaussPts().size2();
3005 auto get_data_at_pts =
3007 DL>
::size(*dataPtr, nb_integration_points);
3008 if (
type == zeroType && side == zeroSide) {
3016 const size_t nb_base_functions = data.
getN().size2() / 9;
3019 if (data.
getDiffN().size1() != nb_integration_points) {
3021 "Wrong number of integration pts (%ld != %ld)",
3022 static_cast<long>(data.
getDiffN().size1()),
3023 static_cast<long>(nb_integration_points));
3025 if (data.
getDiffN().size2() != nb_base_functions * 27) {
3027 "Wrong number of base functions (%ld != %ld)",
3028 static_cast<long>(data.
getDiffN().size2() / 27),
3029 static_cast<long>(nb_base_functions));
3031 if (nb_base_functions < nb_dofs) {
3033 "Wrong number of base functions (%ld < %ld)",
3034 static_cast<long>(nb_base_functions),
3035 static_cast<long>(nb_dofs));
3044 auto t_data_at_pts = get_data_at_pts();
3045 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
3048 for (; bb != nb_dofs; ++bb) {
3049 t_data_at_pts(
k,
i,
j) += t_base_diff(
k,
i,
j) * t_dof;
3053 for (; bb != nb_base_functions; ++bb)
3074template <
int BASE_DIM,
int SPACE_DIM>
3079 boost::shared_ptr<MatrixDouble> data_ptr,
3080 const EntityType zero_type = MBEDGE,
3081 const int zero_side = 0)
3092 const size_t nb_integration_points =
getGaussPts().size2();
3104 const int nb_base_functions = data.
getN().size2() /
BASE_DIM;
3107 auto &hessian_base = data.
getN(BaseDerivatives::SecondDerivative);
3108 if (hessian_base.size1() != nb_integration_points) {
3110 "Wrong number of integration pts (%ld != %ld)",
3111 static_cast<long>(hessian_base.size1()),
3112 static_cast<long>(nb_integration_points));
3114 if (hessian_base.size2() !=
3117 "Wrong number of base functions (%ld != %ld)",
3118 static_cast<long>(hessian_base.size2() /
3120 static_cast<long>(nb_base_functions));
3124 "Wrong number of base functions (%ld < %ld)",
3125 static_cast<long>(hessian_base.size2()),
3136 auto t_data_at_pts = get_data_at_pts();
3137 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
3140 for (; bb != nb_dofs; ++bb) {
3141 t_data_at_pts(
i,
j,
k) += t_dof * t_base_diff2(
i,
j,
k);
3146 for (; bb != nb_base_functions; ++bb)
3165template <
int Tensor_Dim1,
int Tensor_Dim2>
3170 boost::shared_ptr<VectorDouble> data_ptr,
3171 const EntityType zero_type = MBEDGE,
3172 const int zero_side = 0)
3183 const size_t nb_integration_points =
getGaussPts().size2();
3185 dataPtr->resize(nb_integration_points,
false);
3190 const int nb_dofs = local_indices.size();
3193 std::array<double, MAX_DOFS_ON_ENTITY> dot_dofs_vector;
3194 const double *array;
3196 for (
size_t i = 0;
i != local_indices.size(); ++
i)
3197 if (local_indices[
i] != -1)
3198 dot_dofs_vector[
i] = array[local_indices[
i]];
3200 dot_dofs_vector[
i] = 0;
3203 const size_t nb_base_functions = data.
getN().size2() / Tensor_Dim1;
3207 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
3209 for (; bb != nb_dofs; ++bb) {
3211 for (
auto ii = 0; ii != Tensor_Dim2; ++ii)
3212 div += t_n_diff_hdiv(ii, ii);
3213 t_data += dot_dofs_vector[bb] * div;
3216 for (; bb != nb_base_functions; ++bb)
3252 boost::shared_ptr<MatrixDouble> data_ptr,
3253 const EntityType zero_type = MBEDGE,
3254 const int zero_side = 0);
3276 boost::shared_ptr<MatrixDouble> data_ptr,
3277 const EntityType zero_type = MBVERTEX,
3278 const int zero_side = 0);
3301 boost::shared_ptr<MatrixDouble> data_ptr,
3302 const EntityType zero_type = MBVERTEX,
3303 const int zero_side = 0);
3321template <
int Tensor_Dim0,
int Tensor_Dim1>
3326 boost::shared_ptr<MatrixDouble> data_ptr,
3327 boost::shared_ptr<double> scale_ptr,
3329 const EntityType zero_type = MBEDGE,
3330 const int zero_side = 0)
3340 boost::shared_ptr<MatrixDouble> data_ptr,
3341 const EntityType zero_type = MBEDGE,
3342 const int zero_side = 0)
3350 const size_t nb_integration_points =
getGaussPts().size2();
3352 auto get_data_at_pts =
3363 const double *array;
3366 for (
int i = 0;
i != local_indices.size(); ++
i)
3367 if (local_indices[
i] != -1)
3376 const size_t nb_base_functions = data.
getN().size2() / 3;
3380 auto t_data_at_pts = get_data_at_pts();
3381 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
3384 for (; bb != nb_dofs / Tensor_Dim0; ++bb) {
3385 t_data_at_pts(
i,
j) += (
scale * t_dof(
i)) * t_n_hvec(
j);
3389 for (; bb < nb_base_functions; ++bb)
3417template <
int Tensor_Dim0,
int Tensor_Dim1, PetscData::DataContext CTX>
3422 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
3423 const EntityType zero_type = MBEDGE,
const int zero_side = 0)
3435 const size_t nb_integration_points =
getGaussPts().size2();
3437 auto get_data_at_pts =
3445 const size_t nb_dofs = local_indices.size();
3449 const double *array;
3451 auto get_array = [&](
const auto ctx,
auto vec) {
3457 <<
"In this case field degrees of freedom are read from vector. "
3458 "That usually happens when time solver is used, and access to "
3459 "first or second rates is needed. You probably not set ts_u, "
3460 "ts_u_t, or ts_u_tt and associated data structure, i.e. "
3461 "data_ctx to CTX_SET_X, CTX_SET_DX, CTX_SET_X_T, or "
3462 "CTX_SET_X_TT respectively";
3466 CHKERR VecGetArrayRead(vec, &array);
3470 auto restore_array = [&](
auto vec) {
3471 return VecRestoreArrayRead(vec, &array);
3489 "That case is not implemented");
3492 dotVector.resize(local_indices.size(),
false);
3493 for (
int i = 0;
i != local_indices.size(); ++
i)
3494 if (local_indices[
i] != -1)
3514 "That case is not implemented");
3517 const size_t nb_base_functions = data.
getN().size2() / 3;
3521 auto t_data_at_pts = get_data_at_pts();
3522 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
3523 auto t_dof = getFTensor1FromArray<Tensor_Dim0, Tensor_Dim0>(
dotVector);
3525 for (; bb != nb_dofs / Tensor_Dim0; ++bb) {
3526 t_data_at_pts(
i,
j) += t_dof(
i) * t_n_hvec(
j);
3530 for (; bb < nb_base_functions; ++bb)
3546template <
int Tensor_Dim0,
int Tensor_Dim1>
3559template <
int Tensor_Dim0,
int Tensor_Dim1, PetscData::DataContext CTX>
3564 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
3565 const EntityType zero_type = MBEDGE,
const int zero_side = 0,
3566 bool throw_error =
true)
3579 const size_t nb_integration_points =
getGaussPts().size2();
3581 auto get_data_at_pts =
3589 const size_t nb_dofs = local_indices.size();
3599 const double *array;
3601 auto get_array = [&](
const auto ctx,
auto vec) {
3607 <<
"In this case field degrees of freedom are read from vector. "
3608 "That usually happens when time solver is used, and access to "
3609 "first or second rates is needed. You probably not set ts_u, "
3610 "ts_u_t, or ts_u_tt and associated data structure, i.e. "
3611 "data_ctx to CTX_SET_X, CTX_SET_DX, CTX_SET_X_T, or "
3612 "CTX_SET_X_TT respectively";
3616 CHKERR VecGetArrayRead(vec, &array);
3620 auto restore_array = [&](
auto vec) {
3621 return VecRestoreArrayRead(vec, &array);
3639 "That case is not implemented");
3642 dotVector.resize(local_indices.size(),
false);
3643 for (
int i = 0;
i != local_indices.size(); ++
i)
3644 if (local_indices[
i] != -1)
3664 "That case is not implemented");
3667 const size_t nb_base_functions =
3668 data.
getN().size2() / (Tensor_Dim0 * Tensor_Dim1);
3671 auto t_n_hten = data.
getFTensor2N<Tensor_Dim0, Tensor_Dim1>();
3672 auto t_data_at_pts = get_data_at_pts();
3673 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
3676 for (; bb != nb_dofs; ++bb) {
3677 t_data_at_pts(
i,
j) += t_dof * t_n_hten(
i,
j);
3681 for (; bb < nb_base_functions; ++bb)
3697template <
int Tensor_Dim0,
int Tensor_Dim1>
3707template <
int Tensor_Dim0,
int Tensor_Dim1>
3714 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
3716 boost::shared_ptr<Range> broken_range_ptr =
nullptr,
3717 boost::shared_ptr<double> scale_ptr =
nullptr,
3718 const EntityType zero_type = MBEDGE,
const int zero_side = 0)
3746template <
int Tensor_Dim0,
int Tensor_Dim1>
3751 const size_t nb_integration_points = OP::getGaussPts().size2();
3753 auto get_data_at_pts =
3756 DL>
::size(*dataPtr, nb_integration_points);
3757 if (
type == zeroType)
3763 if (dataVec.use_count()) {
3764 dotVector.resize(nb_dofs,
false);
3765 const double *array;
3766 CHKERR VecGetArrayRead(dataVec, &array);
3768 for (
int i = 0;
i != local_indices.size(); ++
i)
3769 if (local_indices[
i] != -1)
3770 dotVector[
i] = array[local_indices[
i]];
3773 CHKERR VecRestoreArrayRead(dataVec, &array);
3784 auto get_get_side_face_dofs = [&]() {
3785 auto fe_type = OP::getFEType();
3789 std::vector<int> side_face_dofs;
3790 side_face_dofs.reserve(data.
getIndices().size() / Tensor_Dim0);
3794 auto it = side_dof_map.get<1>().begin();
3795 it != side_dof_map.get<1>().end(); ++it
3798 if ((Tensor_Dim0 * it->dof) >= data.
getIndices().size()) {
3801 if (it->type == brokenType) {
3802 if (brokenRangePtr) {
3803 auto ent = OP::getSideEntity(it->side, brokenType);
3804 if (brokenRangePtr->find(ent) != brokenRangePtr->end()) {
3805 side_face_dofs.push_back(it->dof);
3808 side_face_dofs.push_back(it->dof);
3813 return side_face_dofs;
3816 auto side_face_dofs = get_get_side_face_dofs();
3820 auto t_data_at_pts = get_data_at_pts();
3821 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
3822 for (
auto b : side_face_dofs) {
3824 auto t_dof = getFTensor1FromPtr<Tensor_Dim0>(data.
getFieldData().data() +
3826 t_data_at_pts(
i,
j) += t_dof(
i) * t_row_base(
j);
3830 *dataPtr *= (scalePtr) ? *scalePtr : 1.0;
3832 if (dataVec.use_count()) {
3846template <
int Tensor_Dim0,
int Tensor_Dim1>
3851 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
3852 boost::shared_ptr<double> scale_ptr,
3854 const EntityType zero_type = MBEDGE,
const int zero_side = 0)
3864 boost::shared_ptr<MatrixDouble> data_ptr,
3865 const EntityType zero_type = MBEDGE,
3866 const int zero_side = 0)
3874 const size_t nb_integration_points =
getGaussPts().size2();
3876 auto get_data_at_pts =
3888 const double *array;
3891 for (
int i = 0;
i != local_indices.size(); ++
i)
3892 if (local_indices[
i] != -1)
3901 const size_t nb_base_functions =
3902 data.
getN().size2() / (Tensor_Dim0 * Tensor_Dim1);
3905 auto t_n_hten = data.
getFTensor2N<Tensor_Dim0, Tensor_Dim1>();
3906 auto t_data_at_pts = get_data_at_pts();
3907 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
3910 for (; bb != nb_dofs; ++bb) {
3911 t_data_at_pts(
i,
j) += (
scale * t_dof) * t_n_hten(
i,
j);
3915 for (; bb < nb_base_functions; ++bb)
3943template <
int Tensor_Dim0,
int Tensor_Dim1,
3949 boost::shared_ptr<MatrixDouble> data_ptr,
3951 const EntityType zero_type = MBEDGE,
3952 const int zero_side = 0)
3962 boost::shared_ptr<MatrixDouble> data_ptr,
3963 const EntityType zero_type = MBEDGE,
3964 const int zero_side = 0)
3971 const size_t nb_integration_points =
getGaussPts().size2();
3974 auto get_data_at_pts =
3976 DL>
::size(mat, nb_integration_points);
3985 const double *array;
3988 for (
int i = 0;
i != local_indices.size(); ++
i)
3989 if (local_indices[
i] != -1)
3997 const size_t nb_base_functions = data.
getN().size2() / 3;
4001 auto t_data_at_pts = get_data_at_pts();
4004 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
4007 for (; bb != nb_dofs / Tensor_Dim0; ++bb) {
4008 double div = t_n_diff_hvec(
j,
j);
4009 t_data_at_pts(
i) += t_dof(
i) * div;
4011 t_data_at_pts(
i) += t_base(0) * (t_dof(
i) / t_coords(0));
4017 for (; bb < nb_base_functions; ++bb) {
4050template <
int Tensor_Dim0,
int Tensor_Dim1,
4058 const std::string
field_name, boost::shared_ptr<MatrixDouble> data_ptr,
4060 boost::shared_ptr<Range> broken_range_ptr =
nullptr,
4061 boost::shared_ptr<double> scale_ptr =
nullptr,
4062 const EntityType zero_type = MBEDGE)
4074 const size_t nb_integration_points =
getGaussPts().size2();
4077 auto get_data_at_pts =
4079 DL>
::size(mat, nb_integration_points);
4089 const double *array;
4092 for (
int i = 0;
i != local_indices.size(); ++
i)
4093 if (local_indices[
i] != -1)
4108 auto get_get_side_face_dofs = [&]() {
4113 std::vector<int> side_face_dofs;
4114 side_face_dofs.reserve(data.
getIndices().size() / Tensor_Dim0);
4118 auto it = side_dof_map.get<1>().begin();
4119 it != side_dof_map.get<1>().end(); ++it
4122 if ((Tensor_Dim0 * it->dof) >= data.
getIndices().size()) {
4129 side_face_dofs.push_back(it->dof);
4132 side_face_dofs.push_back(it->dof);
4137 return side_face_dofs;
4140 auto side_face_dofs = get_get_side_face_dofs();
4144 auto t_data_at_pts = get_data_at_pts();
4146 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
4147 for (
auto b : side_face_dofs) {
4148 auto t_dof = getFTensor1FromPtr<Tensor_Dim0>(
4152 double div = t_diff_base(
j,
j);
4153 t_data_at_pts(
i) += t_dof(
i) * div;
4155 t_data_at_pts(
i) += t_base(0) * (t_dof(
i) / t_coords(0));
4186template <
int Tensor_Dim,
typename OpBase>
4190 boost::shared_ptr<MatrixDouble> data_ptr,
4191 boost::shared_ptr<double> scale_ptr,
4192 const EntityType zero_type = MBEDGE,
4193 const int zero_side = 0)
4201 boost::shared_ptr<MatrixDouble> data_ptr,
4202 const EntityType zero_type = MBEDGE,
4203 const int zero_side = 0)
4210 const size_t nb_integration_points = OpBase::getGaussPts().size2();
4213 auto get_data_at_pts =
4215 DL>
::size(mat, nb_integration_points);
4222 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
4223 const size_t nb_base_functions = data.
getN().size2() / 3;
4225 auto t_data_at_pts = get_data_at_pts();
4226 for (
size_t gg = 0; gg != nb_integration_points; ++gg) {
4228 t_normalized_normal(
j) = t_normal(
j);
4232 for (; bb != nb_dofs / Tensor_Dim; ++bb) {
4234 (scale_val * t_dof(
i)) * (t_base(
j) * t_normalized_normal(
j));
4238 for (; bb < nb_base_functions; ++bb) {
4281 boost::shared_ptr<MatrixDouble> inv_jac_ptr);
4294 template <
int D1,
int D2,
int J1,
int J2>
4298 static_assert(D2 == J2,
"Dimension of jacobian and dimension of <out> "
4299 "directive does not match");
4301 size_t nb_functions = diff_n.size2() / D1;
4303 size_t nb_gauss_pts = diff_n.size1();
4308 "Wrong number of Gauss Pts");
4309 if (diff_n.size2() % D1)
4311 "Number of directives of base functions and D1 dimension does "
4315 diffNinvJac.resize(diff_n.size1(), D2 * nb_functions,
false);
4319 auto t_diff_n = getFTensor1FromPtr<D2>(&*
diffNinvJac.data().begin());
4320 auto t_diff_n_ref = getFTensor1FromPtr<D1>(&*diff_n.data().begin());
4322 auto get_inv_jac_at_pts =
4325 auto t_inv_jac_at_pts = get_inv_jac_at_pts();
4326 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg, ++t_inv_jac_at_pts) {
4327 for (
size_t dd = 0; dd != nb_functions; ++dd) {
4328 t_diff_n(
i) = t_inv_jac_at_pts(
k,
i) * t_diff_n_ref(
k);
4373template <
int DERIVARIVE = 1>
4380template <
int DERIVARIVE = 1>
4387template <
int DERIVARIVE = 1>
4391 boost::shared_ptr<MatrixDouble> inv_jac_ptr)
4395template <
int DERIVARIVE = 1>
4399 boost::shared_ptr<MatrixDouble> inv_jac_ptr)
4417 invJacPtr(inv_jac_ptr) {}
4471 boost::shared_ptr<MatrixDouble> inv_jac_ptr);
4508 boost::shared_ptr<MatrixDouble> jac_ptr)
4525 2>::OpSetContravariantPiolaTransformOnFace2DImpl;
4724 template <
typename T>
4726 boost::shared_ptr<T> det_ptr,
4727 boost::shared_ptr<MatrixDouble> out_ptr)
4737 std::variant<boost::shared_ptr<VectorDouble>, boost::shared_ptr<MatrixDouble>>
4749 "Pointer for inPtr matrix not allocated");
4751 if (!std::holds_alternative<boost::shared_ptr<VectorDouble>>(detPtrVariant) &&
4752 !std::holds_alternative<boost::shared_ptr<MatrixDouble>>(detPtrVariant)) {
4754 "detPtrVariant must hold either VectorDouble or MatrixDouble");
4757 const auto nb_integration_pts = inPtr->size1();
4760 const auto nb_rows = inPtr->size2();
4761 if (nb_rows != DIM * DIM)
4763 "Wrong number of matrix coefficients");
4768 using T = std::decay_t<
decltype(ptr)>;
4770 if constexpr (std::is_same_v<T, boost::shared_ptr<VectorDouble>>) {
4771 ptr->resize(nb_integration_pts,
false);
4772 }
else if constexpr (std::is_same_v<T, boost::shared_ptr<MatrixDouble>>) {
4773 ptr->resize(nb_integration_pts, 1,
false);
4779 auto get_in_at_pts =
4781 *inPtr, nb_integration_pts);
4785 auto t_in_at_pts = get_in_at_pts();
4786 auto det_it = std::visit(
4787 [](
auto p) -> std::vector<double>::iterator {
4788 return p->data().begin();
4791 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
4800 auto get_out_at_pts =
4802 *outPtr, nb_integration_pts);
4803 auto t_in_at_pts = get_in_at_pts();
4804 auto t_out_at_pts = get_out_at_pts();
4805 auto det_it = std::visit(
4806 [](
auto p) -> std::vector<double>::iterator {
4807 return p->data().begin();
4810 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
4845 boost::shared_ptr<VectorDouble> out_ptr)
4866 "Pointer for inPtr matrix not allocated");
4868 const auto nb_integration_pts = inPtr->size1();
4872 auto get_in_at_pts =
4874 *inPtr, nb_integration_pts);
4875 outPtr->resize(nb_integration_pts,
false);
4876 auto t_in_at_pts = get_in_at_pts();
4879 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
4880 t_out = t_in_at_pts(
i,
i);
4902 boost::shared_ptr<VectorDouble> out_ptr)
4923 "Pointer for inPtr matrix not allocated");
4925 const auto nb_integration_pts = inPtr->size1();
4928 outPtr->resize(nb_integration_pts,
false);
4930 auto get_in_at_pts =
4932 DL>::get(*inPtr, nb_integration_pts);
4933 auto t_in_at_pts = get_in_at_pts();
4936 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
4937 t_out = t_in_at_pts(
i,
i);
#define FTENSOR_INDEXES(DIM,...)
Kronecker Delta class symmetric.
Tensor1< T, Tensor_Dim > normalize()
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
static const char *const CoordinateTypesNames[]
Coordinate system names.
#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
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
CoordinateTypes
Coodinate system.
#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.
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
NumeredDofEntity_multiIndex::index< Unique_mi_tag >::type NumeredDofEntityByUId
Numbered DoF multi-index by UId.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'J', DIM1 > J
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
VecAllocator< double > DoubleAllocator
implementation of Data Operators for Forces and Sources
decltype(GetFTensor2SymmetricFromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2SymmetricFromMatType
static auto getFTensor3DgFromMat(M &data)
Get symmetric tensor rank 3 on the first two indices from form data matrix.
static MoFEMErrorCode invertTensor(FTensor::Tensor2< T1, DIM, DIM > &t, T2 &det, FTensor::Tensor2< T3, DIM, DIM > &inv_t)
static auto determinantTensor(FTensor::Tensor2< T, DIM, DIM > &t)
Calculate the determinant of a tensor of rank DIM.
OpCalculateScalarFieldValuesFromPetscVecImpl< PetscData::CTX_SET_X_T > OpCalculateScalarFieldValuesDot
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
decltype(GetFTensor3FromMatImpl< Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor3FromMatType
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
constexpr IntegrationType I
constexpr auto field_name
multi_index_container< DofsSideMapData, indexed_by< ordered_non_unique< tag< TypeSide_mi_tag >, composite_key< DofsSideMapData, member< DofsSideMapData, EntityType, &DofsSideMapData::type >, member< DofsSideMapData, int, &DofsSideMapData::side > > >, ordered_unique< tag< EntDofIdx_mi_tag >, member< DofsSideMapData, int, &DofsSideMapData::dof > > > > DofsSideMap
Map entity stype and side to element/entity dof index.
std::array< bool, MBMAXTYPE > doEntities
If true operator is executed for entity.
virtual MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
Operator for bi-linear form, usually to calculate values on left hand side.
default operator for EDGE element
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.
auto getFTensor2SymmetricFieldData()
Return symmetric FTensor rank 2, i.e. matrix from field data coefficients.
auto getFTensor2FieldData()
Return FTensor rank 2, i.e. matrix from field data coefficients.
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
MatrixDouble & getDiffN(const FieldApproximationBase base)
get derivatives of base functions
const VectorFieldEntities & getFieldEntities() const
Get field entities (const version)
auto getFTensor1FieldData()
Return FTensor of rank 1, i.e. vector from field data coefficients.
auto getFTensor2N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
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.
FTensor::Tensor3< FTensor::PackPtr< double *, Tensor_Dim0 *Tensor_Dim1 *Tensor_Dim2 >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 > getFTensor3Diff2N(FieldApproximationBase base)
Get second derivatives of base functions for Hvec space.
const VectorInt & getLocalIndices() const
Get local indices of degrees of freedom on entity.
auto getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0FieldData()
Return scalar files as a FTensor of rank 0.
const VectorDofs & getFieldDofs() const
Get DOF data structures (const version)
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
FTensor::Tensor3< FTensor::PackPtr< double *, Tensor_Dim0 *Tensor_Dim1 *Tensor_Dim2 >, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2 > getFTensor3DiffN(FieldApproximationBase base)
Get derivatives of base functions for tonsorial Hdiv space.
default operator for TRI element
default operator for Flat Prism element
default operator for Flat Prism element
FlatPrism finite element.
EntityType getFEType() const
Get dimension of finite element.
auto getFTensor1CoordsAtGaussPts()
Get coordinates at integration points assuming linear geometry.
EntityHandle getSideEntity(const int side_number, const EntityType type)
Get the side entity.
int getOpType() const
Get operator types.
OpType
Controls loop over entities on element.
@ OPCOL
operator doWork function is executed on FE columns
@ OPROW
operator doWork function is executed on FE rows
@ OPSPACE
operator do Work is execute on space data
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
structure to get information from mofem into EntitiesFieldData
Calculate divergence of tonsorial field using vectorial base.
boost::shared_ptr< double > scalePtr
boost::shared_ptr< Range > brokenRangePtr
SmartPetscObj< Vec > dataVec
OpCalculateBrokenHVecTensorDivergence(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, EntityType broken_type, boost::shared_ptr< Range > broken_range_ptr=nullptr, boost::shared_ptr< double > scale_ptr=nullptr, const EntityType zero_type=MBEDGE)
boost::shared_ptr< MatrixDouble > dataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
const EntityHandle zeroType
Get tensor field for H-div approximation.
boost::shared_ptr< MatrixDouble > dataPtr
boost::shared_ptr< Range > brokenRangePtr
boost::shared_ptr< double > scalePtr
OpCalculateBrokenHVecTensorField(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, EntityType broken_type, boost::shared_ptr< Range > broken_range_ptr=nullptr, boost::shared_ptr< double > scale_ptr=nullptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Calculate values of vector field at integration points.
const EntityHandle zeroType
SmartPetscObj< Vec > dataVec
Calculate divergence of vector field at integration points.
boost::shared_ptr< VectorDouble > dataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateDivergenceVectorFieldValues(const std::string field_name, boost::shared_ptr< VectorDouble > data_ptr, const EntityType zero_type=MBVERTEX)
Constructor for vector field divergence calculation operator.
const EntityHandle zeroType
Approximate tensor field values for a given PETSc vector on a tensor basis.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateHTensorTensorFieldFromPetscVecImpl(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0, bool throw_error=true)
boost::shared_ptr< MatrixDouble > dataPtr
const EntityHandle zeroType
Calculate tenor field using tensor base, i.e. Hdiv/Hcurl.
VectorDouble dotVector
Keeps temporary values of time derivatives.
OpCalculateHTensorTensorField(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, boost::shared_ptr< double > scale_ptr, SmartPetscObj< Vec > data_vec=SmartPetscObj< Vec >(), const EntityType zero_type=MBEDGE, const int zero_side=0)
SmartPetscObj< Vec > dataVec
boost::shared_ptr< MatrixDouble > dataPtr
const EntityHandle zeroType
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateHTensorTensorField(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
boost::shared_ptr< double > scalePtr
Calculate divergence of tonsorial field using vectorial base.
boost::shared_ptr< MatrixDouble > dataPtr
SmartPetscObj< Vec > dataVec
VectorDouble dotVector
Keeps temporary values of time derivatives.
const EntityHandle zeroType
OpCalculateHVecTensorDivergence(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBEDGE, const int zero_side=0)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateHVecTensorDivergence(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
Approximate Hdiv/Hcurl tensor field values for a given PETSc vector.
boost::shared_ptr< MatrixDouble > dataPtr
OpCalculateHVecTensorFieldFromPetscVecImpl(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
const EntityHandle zeroType
Calculate tenor field using vectorial base, i.e. Hdiv/Hcurl.
OpCalculateHVecTensorField(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, boost::shared_ptr< double > scale_ptr, SmartPetscObj< Vec > data_vec=SmartPetscObj< Vec >(), const EntityType zero_type=MBEDGE, const int zero_side=0)
const EntityHandle zeroType
boost::shared_ptr< MatrixDouble > dataPtr
OpCalculateHVecTensorField(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
SmartPetscObj< Vec > dataVec
VectorDouble dotVector
Keeps temporary values of time derivatives.
boost::shared_ptr< double > scalePtr
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 > dataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
const EntityHandle zeroType
OpCalculateHVecTensorGradient(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
const EntityHandle zeroType
OpCalculateHVecTensorGradient(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
boost::shared_ptr< MatrixDouble > dataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Calculate gradient of tensor field.
Calculate trace of vector (Hdiv/Hcurl) space.
const EntityHandle zeroType
boost::shared_ptr< MatrixDouble > dataPtr
boost::shared_ptr< double > scalePtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
OpCalculateHVecTensorTrace(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
FTensor::Index< 'j', Tensor_Dim > j
FTensor::Index< 'i', Tensor_Dim > i
OpCalculateHVecTensorTrace(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, boost::shared_ptr< double > scale_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
const EntityHandle zeroType
boost::shared_ptr< MatrixDouble > dataPtr
OpCalculateHVecVectorFieldDot(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
Get vector field for H-div approximation.
OpCalculateHVecVectorField_General(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
SmartPetscObj< Vec > dataVec
OpCalculateHVecVectorField_General(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBEDGE, const int zero_side=0)
const EntityHandle zeroType
boost::shared_ptr< MatrixDouble > dataPtr
Get vector field for H-div approximation.
Get vector field for H-div approximation.
Calculate gradient of vector field.
boost::shared_ptr< MatrixDouble > dataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
const EntityHandle zeroType
OpCalculateHVecVectorGradient(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
Calculate gradient of vector field.
boost::shared_ptr< MatrixDouble > dataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
const EntityHandle zeroType
OpCalculateHVecVectorHessian(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
boost::shared_ptr< MatrixDouble > dataPtr
const EntityHandle zeroType
const EntityHandle zeroType
boost::shared_ptr< MatrixDouble > dataPtr
boost::shared_ptr< MatrixDouble > dataPtr
const EntityHandle zeroType
Calculate curl of vector field.
Calculate divergence of vector field dot.
boost::shared_ptr< VectorDouble > dataPtr
OpCalculateHdivVectorDivergenceDot(const std::string field_name, boost::shared_ptr< VectorDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
const EntityHandle zeroType
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Calculate divergence of vector field.
boost::shared_ptr< VectorDouble > dataPtr
OpCalculateHdivVectorDivergence(const std::string field_name, boost::shared_ptr< VectorDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
const EntityHandle zeroType
Calculate inverse of jacobian for face element.
OpCalculateInvJacForFatPrism(MatrixDouble &inv_jac)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateInvJacForFatPrism(boost::shared_ptr< MatrixDouble > inv_jac_ptr)
const boost::shared_ptr< MatrixDouble > invJacPtr
Calculate inverse of jacobian for face element.
OpCalculateInvJacForFlatPrism(MatrixDouble &inv_jac_f3)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Evaluate field gradient values for scalar field, i.e. gradient is tensor rank 1 (vector)
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Evaluate field gradient values for scalar field, i.e. gradient is tensor rank 1 (vector),...
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
calculate gradient values of scalar field at integration points
Calculate scalar field values from PETSc vector at integration points.
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 > dataPtr
OpCalculateScalarFieldValuesFromPetscVecImpl(const std::string field_name, boost::shared_ptr< VectorDouble > data_ptr, const EntityType zero_at_type=MBVERTEX)
Constructor for PETSc vector-based scalar field calculation.
const EntityHandle zeroAtType
Scalar field values at integration points.
OpCalculateScalarFieldValues_General(const std::string field_name, boost::shared_ptr< ublas::vector< T, A > > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBVERTEX)
OpCalculateScalarFieldValues_General(SmartPetscObj< DM > data_dm, const ForcesAndSourcesCore::UserDataOperator::OpType op_type, const std::string field_name, boost::shared_ptr< ublas::vector< T, A > > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBVERTEX)
Constructor with PETSc vector support for a different problem layout.
SmartPetscObj< DM > dataDm
boost::shared_ptr< ublas::vector< T, A > > dataPtr
OpCalculateScalarFieldValues_General(const ForcesAndSourcesCore::UserDataOperator::OpType op_type, const std::string field_name, boost::shared_ptr< ublas::vector< T, A > > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBVERTEX)
Constructor with PETSc vector support.
SmartPetscObj< Vec > dataVec
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
calculate values of scalar field at integration points
const EntityHandle zeroType
OpCalculateScalarFieldValues_General(const std::string field_name, boost::shared_ptr< ublas::vector< T, A > > data_ptr, const EntityType zero_type=MBVERTEX)
Constructor for scalar field values calculation operator.
Specialization for double precision scalar field values calculation.
MoFEMErrorCode doWork(int, EntityType type, EntitiesFieldData::EntData &data)
calculate values of scalar field at integration points
Get time direvarive values at integration pts for tensor field rank 2, i.e. matrix field.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateTensor2FieldValuesDot(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_at_type=MBVERTEX)
EntityType zeroAtType
Zero values at Gauss point at this type.
VectorDouble dotVector
Keeps temporary values of time derivatives.
boost::shared_ptr< MatrixDouble > dataPtr
Data computed into this matrix.
const EntityHandle zeroType
OpCalculateTensor2FieldValues_General(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBVERTEX)
OpCalculateTensor2FieldValues_General(ForcesAndSourcesCore::UserDataOperator::OpType op_type, const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBVERTEX)
SmartPetscObj< Vec > dataVec
OpCalculateTensor2FieldValues_General(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBVERTEX)
boost::shared_ptr< MatrixDouble > dataPtr
Calculate field values for tenor field rank 2.
const EntityHandle zeroType
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< M > dataPtr
OpCalculateTensor2FieldValues_General(const std::string field_name, boost::shared_ptr< M > data_ptr, const EntityType zero_type=MBVERTEX)
Get values at integration pts for tensor field rank 2, i.e. matrix field.
OpCalculateTensor2SymmetricDeviatorFieldValues_General(const std::string field_name, MatrixPtr data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
OpCalculateTensor2SymmetricDeviatorFieldValues_General(SmartPetscObj< DM > data_dm, const ForcesAndSourcesCore::UserDataOperator::OpType op_type, const std::string field_name, MatrixPtr data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBEDGE, const int zero_side=0, MatrixPtr coordinates=nullptr)
OpCalculateTensor2SymmetricDeviatorFieldValues_General(const std::string field_name, MatrixPtr data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBEDGE, const int zero_side=0, MatrixPtr coordinates=nullptr)
const EntityHandle zeroType
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data) override
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< MatrixDouble > MatrixPtr
OpCalculateTensor2SymmetricFieldGradient_General(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBVERTEX)
Evaluate field gradient values for symmetric 2nd order tensor field, i.e. gradient is tensor rank 3.
OpCalculateTensor2SymmetricFieldGradient_General(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBVERTEX)
Get field gradients at integration pts for symmetric tensorial field rank 2.
OpCalculateTensor2SymmetricFieldGradient(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBVERTEX)
Calculate symmetric tensor field rates ant integratio pts.
const EntityHandle zeroType
boost::shared_ptr< MatrixDouble > dataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateTensor2SymmetricFieldValuesDot(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
Calculate symmetric tensor field values at integration pts.
SmartPetscObj< DM > dataDm
OpCalculateTensor2SymmetricFieldValues(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBEDGE, const int zero_side=0)
OpCalculateTensor2SymmetricFieldValues(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBEDGE, const int zero_side=0)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
SmartPetscObj< Vec > dataVec
OpCalculateTensor2SymmetricFieldValues(SmartPetscObj< DM > data_dm, const ForcesAndSourcesCore::UserDataOperator::OpType op_type, const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBEDGE, const int zero_side=0)
boost::shared_ptr< MatrixDouble > dataPtr
const EntityHandle zeroType
Operator for calculating the trace of matrices at integration points.
boost::shared_ptr< MatrixDouble > inPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
FTensor::Index< 'i', DIM > i
boost::shared_ptr< VectorDouble > outPtr
OpCalculateTraceFromMat(boost::shared_ptr< MatrixDouble > in_ptr, boost::shared_ptr< VectorDouble > out_ptr)
Constructor for matrix trace calculation operator.
Calculates the trace of an input matrix.
FTensor::Index< 'i', DIM > i
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 > outPtr
boost::shared_ptr< MatrixDouble > inPtr
OpCalculateTraceFromSymmMat(boost::shared_ptr< MatrixDouble > in_ptr, boost::shared_ptr< VectorDouble > out_ptr)
Get field gradients time derivative at integration pts for scalar field rank 0, i....
boost::shared_ptr< MatrixDouble > dataPtr
Data computed into this matrix.
OpCalculateVectorFieldGradientDot(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_at_type=MBVERTEX)
EntityType zeroAtType
Zero values at Gauss point at this type.
VectorDouble dotVector
Keeps temporary values of time derivatives.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Evaluate field gradient values for vector field, i.e. gradient is tensor rank 2.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
calculate values of vector field at integration points
Approximate field values for given petsc vector.
boost::shared_ptr< MatrixDouble > dataPtr
OpCalculateVectorFieldValuesFromPetscVecImpl(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_at_type=MBVERTEX, bool throw_error=true)
const EntityHandle zeroAtType
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateVectorFieldValues_General(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBVERTEX, const int max_order=-1)
OpCalculateVectorFieldValues_General(const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, const EntityType zero_type=MBVERTEX, const int max_order=-1)
SmartPetscObj< DM > dataDm
const EntityHandle zeroType
SmartPetscObj< Vec > dataVec
boost::shared_ptr< MatrixDouble > dataPtr
OpCalculateVectorFieldValues_General(SmartPetscObj< DM > data_dm, const ForcesAndSourcesCore::UserDataOperator::OpType op_type, const std::string field_name, boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, const EntityType zero_type=MBVERTEX, const int max_order=-1)
Calculate field values for tensor field rank 1, i.e. vector field.
OpCalculateVectorFieldValues_General(const std::string field_name, boost::shared_ptr< M > data_ptr, const EntityType zero_type=MBVERTEX)
Constructor for vector field values calculation operator.
boost::shared_ptr< M > dataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
calculate values of vector field at integration points
const EntityHandle zeroType
Specialization for MatrixDouble vector field values calculation.
Operator for inverting matrices at integration points.
OpInvertMatrix(boost::shared_ptr< MatrixDouble > in_ptr, boost::shared_ptr< T > det_ptr, boost::shared_ptr< MatrixDouble > out_ptr)
Constructor for matrix inversion operator.
boost::shared_ptr< MatrixDouble > outPtr
boost::shared_ptr< MatrixDouble > inPtr
std::variant< boost::shared_ptr< VectorDouble >, boost::shared_ptr< MatrixDouble > > detPtrVariant
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Make Hdiv space from Hcurl space in 2d.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Operator for fat prism element updating integration weights in the volume.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpMultiplyDeterminantOfJacobianAndWeightsForFatPrisms()
Operator for scaling matrix values by a scalar factor.
boost::shared_ptr< MatrixDouble > outMat
DEPRECATED OpScaleMatrix(const std::string field_name, const double scale, boost::shared_ptr< MatrixDouble > in_mat, boost::shared_ptr< MatrixDouble > out_mat)
boost::shared_ptr< double > scalePtr
OpScaleMatrix(boost::shared_ptr< double > scale_ptr, boost::shared_ptr< MatrixDouble > in_mat, boost::shared_ptr< MatrixDouble > out_mat)
Constructor for matrix scaling operator.
boost::shared_ptr< MatrixDouble > inMat
MoFEMErrorCode doWork(int, EntityType, EntData &)
Operator for linear form, usually to calculate values on right hand side.
OpSetInvJacH1ForFaceEmbeddedIn3DSpace(boost::shared_ptr< MatrixDouble > inv_jac_ptr)
OpSetInvJacH1ForFace(boost::shared_ptr< MatrixDouble > inv_jac_ptr)
Transform local reference derivatives of shape functions to global derivatives.
const boost::shared_ptr< MatrixDouble > invJacPtr
OpSetInvJacH1ForFatPrism(MatrixDouble &inv_jac)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpSetInvJacH1ForFatPrism(boost::shared_ptr< MatrixDouble > inv_jac_ptr)
Transform local reference derivatives of shape functions to global derivatives.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpSetInvJacH1ForFlatPrism(MatrixDouble &inv_jac_f3)
boost::shared_ptr< MatrixDouble > invJacPtr
MatrixDouble diffHcurlInvJac
OpSetInvJacHcurlFaceImpl(boost::shared_ptr< MatrixDouble > inv_jac_ptr)
Transform local reference derivatives of shape function to global derivatives for face.
OpSetInvJacL2ForFaceEmbeddedIn3DSpace(boost::shared_ptr< MatrixDouble > inv_jac_ptr)
OpSetInvJacL2ForFace(boost::shared_ptr< MatrixDouble > inv_jac_ptr)
Transform local reference derivatives of shape functions to global derivatives.
MoFEMErrorCode applyTransform(MatrixDouble &diff_n)
Apply transformation to the input matrix.
OpSetInvJacToScalarBasesBasic(FieldSpace space, boost::shared_ptr< MatrixDouble > inv_jac_ptr)
boost::shared_ptr< MatrixDouble > invJacPtr
Operator for symmetrizing tensor fields.
FTensor::Index< 'i', DIM > i
boost::shared_ptr< MatrixDouble > outMat
OpSymmetrizeTensor(boost::shared_ptr< MatrixDouble > in_mat, boost::shared_ptr< MatrixDouble > out_mat)
Constructor for tensor symmetrization operator.
MoFEMErrorCode doWork(int, EntityType, EntData &)
Operator for linear form, usually to calculate values on right hand side.
FTensor::Index< 'j', DIM > j
DEPRECATED OpSymmetrizeTensor(const std::string field_name, boost::shared_ptr< MatrixDouble > in_mat, boost::shared_ptr< MatrixDouble > out_mat)
boost::shared_ptr< MatrixDouble > inMat
FTensor::Index< 'i', DIM_01 > i
FTensor::Index< 'k', DIM_23 > k
boost::shared_ptr< MatrixDouble > dMat
OpTensorTimesSymmetricTensor(boost::shared_ptr< MatrixDouble > in_mat, boost::shared_ptr< MatrixDouble > out_mat, boost::shared_ptr< MatrixDouble > d_mat)
FTensor::Index< 'j', DIM_01 > j
boost::shared_ptr< MatrixDouble > inMat
MoFEMErrorCode doWork(int, EntityType, EntData &)
Operator for linear form, usually to calculate values on right hand side.
FTensor::Index< 'l', DIM_23 > l
DEPRECATED OpTensorTimesSymmetricTensor(const std::string field_name, boost::shared_ptr< MatrixDouble > in_mat, boost::shared_ptr< MatrixDouble > out_mat, boost::shared_ptr< MatrixDouble > d_mat)
boost::shared_ptr< MatrixDouble > outMat
static constexpr Switches CtxSetX
Solution vector switch.
static constexpr Switches CtxSetX_TT
Second time derivative switch.
std::bitset< 8 > Switches
Bitset type for context switches.
static constexpr Switches CtxSetX_T
First time derivative switch.
@ CTX_SET_X_T
Time derivative X_t is set.
@ CTX_SET_DX
Solution increment DX is set.
@ CTX_SET_X
Solution vector X is set.
@ CTX_SET_X_TT
Second time derivative X_tt is set.
keeps basic data about problem
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredRowDofsPtr
store DOFs on rows for this problem
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredColDofsPtr
store DOFs on columns for this problem
intrusive_ptr for managing petsc objects
static FTensor::Tensor2_symmetric< double, 3 > getTensor(const FTensor::Tensor1< T, Size > &t_coordinates, const double theta=0.)
Reconstruct D + theta*I/3; input may be an owning tensor or a view.
static FTensor::Tensor1< double, 5 > getCoordinates(const Tensor &t_tensor)
Project a full or symmetric tensor onto the five orthonormal columns.
static const FTensor::Dg< double, 3, 5 > & getBasis()
Basis columns (11-22)/sqrt(2), (11+22-2*33)/sqrt(6), 12, 13, 23.