65  constexpr bool calculate_diff = 
false;
 
   66  constexpr bool debug = 
false;
 
   71            "Wrong base, should be USER_BASE");
 
   74  EntitiesFieldData &data = this->cTx->dAta;
 
   77  const int order = data.dataOnEntities[MBTET][0].getOrder();
 
   79  const int nb_gauss_pts = pts.size2();
 
   81  auto check_cache = [
this](
int order, 
int nb_gauss_pts) -> 
bool {
 
   90  if (check_cache(
order, nb_gauss_pts)) {
 
   92    auto &
phi = data.dataOnEntities[MBTET][0].getN(
USER_BASE);
 
   93    phi.resize(mat.size1(), mat.size2(), 
false);
 
   95    if constexpr (calculate_diff) {
 
   96      auto &diff_phi = data.dataOnEntities[MBTET][0].getDiffN(
USER_BASE);
 
   98      diff_phi.resize(diff_mat.size1(), diff_mat.size2(), 
false);
 
   99      noalias(diff_phi) = diff_mat;
 
  103    shapeFun.resize(nb_gauss_pts, 4, 
false);
 
  105                      &pts(2, 0), nb_gauss_pts);
 
  107    double diff_shape_fun[12];
 
  112    MatrixDouble &
phi = data.dataOnEntities[MBTET][0].getN(
USER_BASE);
 
  113    phi.resize(nb_gauss_pts, 9 * nb_base_functions, 
false);
 
  124    auto imagingray_fd_directive = [&](
auto &diff_phi) {
 
  127      MatrixComplexDouble temp_phi;
 
  128      temp_phi.resize(nb_gauss_pts, 9 * nb_base_functions, 
false);
 
  130      MatrixComplexDouble diff_shape_fun;
 
  131      diff_shape_fun.resize(4, 3, 
false);
 
  145      MatrixComplexDouble shape_fun;
 
  146      shape_fun.resize(nb_gauss_pts, 4, 
false);
 
  147      for (
int dd = 0; dd < 3; ++dd) {
 
  148        constexpr double eps = 1e-16;
 
  150        for (
auto gg = 0; gg < nb_gauss_pts; ++gg) {
 
  151          std::array<std::complex<double>, 3> ksi{pts(0, gg), pts(1, gg),
 
  154          ksi[dd] += std::complex<double>(0, 
eps);
 
  156          shape_fun(gg, 0) = 
N_MBTET0(ksi[0], ksi[1], ksi[2]);
 
  157          shape_fun(gg, 1) = 
N_MBTET1(ksi[0], ksi[1], ksi[2]);
 
  158          shape_fun(gg, 2) = 
N_MBTET2(ksi[0], ksi[1], ksi[2]);
 
  159          shape_fun(gg, 3) = 
N_MBTET3(ksi[0], ksi[1], ksi[2]);
 
  162        auto t_complex_phi_in =
 
  164                &temp_phi(0, 0), &temp_phi(0, 1), &temp_phi(0, 2),
 
  165                &temp_phi(0, 3), &temp_phi(0, 4), &temp_phi(0, 5),
 
  166                &temp_phi(0, 6), &temp_phi(0, 7), &temp_phi(0, 8)};
 
  168        CHKERR CGG_BubbleBase_MBTET(
order, shape_fun.data().data(),
 
  169                                    diff_shape_fun.data().data(),
 
  170                                    t_complex_phi_in, nb_gauss_pts);
 
  172        auto t_complex_phi_out =
 
  174                &temp_phi(0, 0), &temp_phi(0, 1), &temp_phi(0, 2),
 
  175                &temp_phi(0, 3), &temp_phi(0, 4), &temp_phi(0, 5),
 
  176                &temp_phi(0, 6), &temp_phi(0, 7), &temp_phi(0, 8)};
 
  177        auto t_diff_phi = getFTensor3FromPtr<3, 3, 3>(diff_phi.data().data());
 
  178        for (
auto gg = 0; gg < nb_gauss_pts; ++gg) {
 
  179          for (
auto bb = 0; bb << nb_base_functions; ++bb) {
 
  180            t_diff_phi(0, 0, dd) = std::imag(t_complex_phi_out(0, 0)) / 
eps;
 
  181            t_diff_phi(0, 1, dd) = std::imag(t_complex_phi_out(0, 1)) / 
eps;
 
  182            t_diff_phi(0, 2, dd) = std::imag(t_complex_phi_out(0, 2)) / 
eps;
 
  183            t_diff_phi(1, 0, dd) = std::imag(t_complex_phi_out(1, 0)) / 
eps;
 
  184            t_diff_phi(1, 1, dd) = std::imag(t_complex_phi_out(1, 1)) / 
eps;
 
  185            t_diff_phi(1, 2, dd) = std::imag(t_complex_phi_out(1, 2)) / 
eps;
 
  186            t_diff_phi(2, 0, dd) = std::imag(t_complex_phi_out(2, 0)) / 
eps;
 
  187            t_diff_phi(2, 1, dd) = std::imag(t_complex_phi_out(2, 1)) / 
eps;
 
  188            t_diff_phi(2, 2, dd) = std::imag(t_complex_phi_out(2, 2)) / 
eps;
 
  191                  << 
"Gauss pt " << gg << 
" direction " << dd
 
  192                  << 
" diff_phi: " << t_diff_phi(0, 0, dd) << 
", " 
  193                  << t_diff_phi(0, 1, dd) << 
", " << t_diff_phi(0, 2, dd)
 
  194                  << 
"; " << t_diff_phi(1, 0, dd) << 
", " 
  195                  << t_diff_phi(1, 1, dd) << 
", " << t_diff_phi(1, 2, dd)
 
  196                  << 
"; " << t_diff_phi(2, 0, dd) << 
", " 
  197                  << t_diff_phi(2, 1, dd) << 
", " << t_diff_phi(2, 2, dd);
 
  206              &
phi(0, 0), &
phi(0, 1), &
phi(0, 2), &
phi(0, 3), &
phi(0, 4),
 
  208          auto t_complex_phi_out =
 
  211                  &temp_phi(0, 0), &temp_phi(0, 1), &temp_phi(0, 2),
 
  212                  &temp_phi(0, 3), &temp_phi(0, 4), &temp_phi(0, 5),
 
  213                  &temp_phi(0, 6), &temp_phi(0, 7), &temp_phi(0, 8)};
 
  215          for (
auto gg = 0; gg < nb_gauss_pts; ++gg) {
 
  219            for (
auto bb = 0; bb << nb_base_functions; ++bb) {
 
  220              t_diff(
i, 
j) = t_complex_phi_out(
i, 
j) - t_phi(
i, 
j);
 
  221              auto nrm2_complex = t_diff(
i, 
j) * t_diff(
i, 
j);
 
  222              if (std::abs(nrm2_complex) > 1e-12) {
 
  224                    << 
"Difference detected at gauss pt " << gg
 
  225                    << 
" for direction " << dd
 
  226                    << 
" nrm2 = " << std::abs(nrm2_complex);
 
  228                        "Difference detected between complex step " 
  229                        "differentiation and real valued differentiation");
 
  244    MatrixDouble &diff_phi = data.dataOnEntities[MBTET][0].getDiffN(
USER_BASE);
 
  245    if constexpr (calculate_diff) {
 
  246      diff_phi.resize(nb_gauss_pts, 27 * nb_base_functions, 
false);
 
  247      CHKERR imagingray_fd_directive(diff_phi);
 
  255      if constexpr (calculate_diff) {
 
  256        cachePhiPtr->get<3>().resize(diff_phi.size1(), diff_phi.size2(), 
false);