66 constexpr bool calculate_diff =
false;
67 constexpr bool debug =
false;
72 "Wrong base, should be USER_BASE");
75 EntitiesFieldData &data = this->cTx->dAta;
78 const int order = data.dataOnEntities[MBTET][0].getOrder();
80 const int nb_gauss_pts = pts.size2();
82 auto check_cache = [
this](
int order,
int nb_gauss_pts) ->
bool {
92 auto &
phi = data.dataOnEntities[MBTET][0].getN(
USER_BASE);
94 phi.resize(nb_gauss_pts, 9 * nb_base_functions,
false);
95 std::fill(
phi.data().begin(),
phi.data().end(), 0.0);
99 if (check_cache(
order, nb_gauss_pts)) {
101 auto &
phi = data.dataOnEntities[MBTET][0].getN(
USER_BASE);
102 phi.resize(mat.size1(), mat.size2(),
false);
104 if constexpr (calculate_diff) {
105 auto &diff_phi = data.dataOnEntities[MBTET][0].getDiffN(
USER_BASE);
107 diff_phi.resize(diff_mat.size1(), diff_mat.size2(),
false);
108 noalias(diff_phi) = diff_mat;
112 shapeFun.resize(nb_gauss_pts, 4,
false);
114 &pts(2, 0), nb_gauss_pts);
116 double diff_shape_fun[12];
121 MatrixDouble &
phi = data.dataOnEntities[MBTET][0].getN(
USER_BASE);
122 phi.resize(nb_gauss_pts, 9 * nb_base_functions,
false);
133 auto imagingray_fd_directive = [&](
auto &diff_phi) {
136 MatrixComplexDouble temp_phi;
137 temp_phi.resize(nb_gauss_pts, 9 * nb_base_functions,
false);
139 MatrixComplexDouble diff_shape_fun;
140 diff_shape_fun.resize(4, 3,
false);
154 MatrixComplexDouble shape_fun;
155 shape_fun.resize(nb_gauss_pts, 4,
false);
156 for (
int dd = 0; dd < 3; ++dd) {
157 constexpr double eps = 1e-16;
159 for (
auto gg = 0; gg < nb_gauss_pts; ++gg) {
160 std::array<std::complex<double>, 3> ksi{pts(0, gg), pts(1, gg),
163 ksi[dd] += std::complex<double>(0,
eps);
165 shape_fun(gg, 0) =
N_MBTET0(ksi[0], ksi[1], ksi[2]);
166 shape_fun(gg, 1) =
N_MBTET1(ksi[0], ksi[1], ksi[2]);
167 shape_fun(gg, 2) =
N_MBTET2(ksi[0], ksi[1], ksi[2]);
168 shape_fun(gg, 3) =
N_MBTET3(ksi[0], ksi[1], ksi[2]);
171 auto t_complex_phi_in =
173 &temp_phi(0, 0), &temp_phi(0, 1), &temp_phi(0, 2),
174 &temp_phi(0, 3), &temp_phi(0, 4), &temp_phi(0, 5),
175 &temp_phi(0, 6), &temp_phi(0, 7), &temp_phi(0, 8)};
177 CHKERR CGG_BubbleBase_MBTET(
order, shape_fun.data().data(),
178 diff_shape_fun.data().data(),
179 t_complex_phi_in, nb_gauss_pts);
181 auto t_complex_phi_out =
183 &temp_phi(0, 0), &temp_phi(0, 1), &temp_phi(0, 2),
184 &temp_phi(0, 3), &temp_phi(0, 4), &temp_phi(0, 5),
185 &temp_phi(0, 6), &temp_phi(0, 7), &temp_phi(0, 8)};
186 auto t_diff_phi = getFTensor3FromPtr<3, 3, 3>(diff_phi.data().data());
187 for (
auto gg = 0; gg < nb_gauss_pts; ++gg) {
188 for (
auto bb = 0; bb << nb_base_functions; ++bb) {
189 t_diff_phi(0, 0, dd) = std::imag(t_complex_phi_out(0, 0)) /
eps;
190 t_diff_phi(0, 1, dd) = std::imag(t_complex_phi_out(0, 1)) /
eps;
191 t_diff_phi(0, 2, dd) = std::imag(t_complex_phi_out(0, 2)) /
eps;
192 t_diff_phi(1, 0, dd) = std::imag(t_complex_phi_out(1, 0)) /
eps;
193 t_diff_phi(1, 1, dd) = std::imag(t_complex_phi_out(1, 1)) /
eps;
194 t_diff_phi(1, 2, dd) = std::imag(t_complex_phi_out(1, 2)) /
eps;
195 t_diff_phi(2, 0, dd) = std::imag(t_complex_phi_out(2, 0)) /
eps;
196 t_diff_phi(2, 1, dd) = std::imag(t_complex_phi_out(2, 1)) /
eps;
197 t_diff_phi(2, 2, dd) = std::imag(t_complex_phi_out(2, 2)) /
eps;
200 <<
"Gauss pt " << gg <<
" direction " << dd
201 <<
" diff_phi: " << t_diff_phi(0, 0, dd) <<
", "
202 << t_diff_phi(0, 1, dd) <<
", " << t_diff_phi(0, 2, dd)
203 <<
"; " << t_diff_phi(1, 0, dd) <<
", "
204 << t_diff_phi(1, 1, dd) <<
", " << t_diff_phi(1, 2, dd)
205 <<
"; " << t_diff_phi(2, 0, dd) <<
", "
206 << t_diff_phi(2, 1, dd) <<
", " << t_diff_phi(2, 2, dd);
215 &
phi(0, 0), &
phi(0, 1), &
phi(0, 2), &
phi(0, 3), &
phi(0, 4),
217 auto t_complex_phi_out =
220 &temp_phi(0, 0), &temp_phi(0, 1), &temp_phi(0, 2),
221 &temp_phi(0, 3), &temp_phi(0, 4), &temp_phi(0, 5),
222 &temp_phi(0, 6), &temp_phi(0, 7), &temp_phi(0, 8)};
224 for (
auto gg = 0; gg < nb_gauss_pts; ++gg) {
228 for (
auto bb = 0; bb << nb_base_functions; ++bb) {
229 t_diff(
i,
j) = t_complex_phi_out(
i,
j) - t_phi(
i,
j);
230 auto nrm2_complex = t_diff(
i,
j) * t_diff(
i,
j);
231 if (std::abs(nrm2_complex) > 1e-12) {
233 <<
"Difference detected at gauss pt " << gg
234 <<
" for direction " << dd
235 <<
" nrm2 = " << std::abs(nrm2_complex);
237 "Difference detected between complex step "
238 "differentiation and real valued differentiation");
253 MatrixDouble &diff_phi = data.dataOnEntities[MBTET][0].getDiffN(
USER_BASE);
254 if constexpr (calculate_diff) {
255 diff_phi.resize(nb_gauss_pts, 27 * nb_base_functions,
false);
256 CHKERR imagingray_fd_directive(diff_phi);
264 if constexpr (calculate_diff) {
265 cachePhiPtr->get<3>().resize(diff_phi.size1(), diff_phi.size2(),
false);