62                                                                 {
   64 
   65  constexpr bool calculate_diff = false;
   66  constexpr bool debug = 
false;
 
   67 
   68  
   71            "Wrong base, should be USER_BASE");
   72  }
   73  
   74  EntitiesFieldData &data = this->cTx->dAta;
   75  
   76  
   77  const int order = data.dataOnEntities[MBTET][0].getOrder();
 
   78
   79  const int nb_gauss_pts = pts.size2();
   80 
   81  auto check_cache = [
this](
int order, 
int nb_gauss_pts) -> 
bool {
 
   85    } else {
   86      return false;
   87    }
   88  };
   89 
   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;
  100    }
  101  } else {
  102    
  103    shapeFun.resize(nb_gauss_pts, 4, 
false);
 
  105                      &pts(2, 0), nb_gauss_pts);
  106    
  107    double diff_shape_fun[12];
  109 
  111    
  113    phi.resize(nb_gauss_pts, 9 * nb_base_functions, 
false);
 
  114    
  117 
  119 
  122                                nb_gauss_pts);
  123 
  124    auto imagingray_fd_directive = [&](auto &diff_phi) {
  126 
  128      temp_phi.resize(nb_gauss_pts, 9 * nb_base_functions, false);
  129 
  131      diff_shape_fun.resize(4, 3, false);
  144 
  146      shape_fun.resize(nb_gauss_pts, 4, false);
  147      for (
int dd = 0; 
dd < 3; ++
dd) {
 
  148        constexpr double eps = 1e-16;
 
  149 
  150        for (auto gg = 0; gg < nb_gauss_pts; ++gg) {
  151          std::array<std::complex<double>, 3> ksi{pts(0, gg), pts(1, gg),
  152                                                  pts(2, gg)};
  153 
  154          ksi[
dd] += std::complex<double>(0, 
eps);
 
  155 
  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]);
 
  160        }
  161 
  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)};
  167 
  169                                    diff_shape_fun.data().data(),
  170                                    t_complex_phi_in, nb_gauss_pts);
  171 
  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);
  198            }
  199            ++t_complex_phi_out;
  200            ++t_diff_phi;
  201          }
  202        }
  203 
  206              &
phi(0, 0), &
phi(0, 1), &
phi(0, 2), &
phi(0, 3), &
phi(0, 4),
 
  208          auto t_complex_phi_out =
  210                               3>{
  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)};
  214 
  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");
  230              }
  231              ++t_phi;
  232              ++t_complex_phi_out;
  233            }
  234          }
  235        }
  236 
  237      
  238 
  239      }
  240 
  242    };
  243 
  245    if constexpr (calculate_diff) {
  246      diff_phi.resize(nb_gauss_pts, 27 * nb_base_functions, false);
  247      CHKERR imagingray_fd_directive(diff_phi);
 
  248    }
  249 
  255      if constexpr (calculate_diff) {
  256        cachePhiPtr->get<3>().resize(diff_phi.size1(), diff_phi.size2(), 
false);
 
  258      }
  259    }
  260  }
  261 
  263}
#define NBVOLUMETET_CCG_BUBBLE(P)
Bubble function for CGG H div space.
@ USER_BASE
user implemented approximation base
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
MoFEMErrorCode CGG_BubbleBase_MBTET(const int p, const double *N, const double *diffN, FTensor::Tensor2< FTensor::PackPtr< double *, 9 >, 3, 3 > &phi, const int gdim)
Calculate CGGT tonsorial bubble base.
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
UBlasMatrix< std::complex< double > > MatrixComplexDouble
UBlasMatrix< double > MatrixDouble