116 inline int calculate(
const double *phi_dof,
const double *phi_nodes,
const double *xi_r,
double ma,
double mb,
double jf,
bool isBoundary,
bool scale);
118 inline int calculate(
const double *phi_dof,
const double *phi_nodes,
const double *xi_r,
double ma,
double mb,
bool isBoundary,
bool scale)
120 return calculate(phi_dof, phi_nodes, xi_r, ma, mb, 0.0, isBoundary,
false);
123 inline int calculate(
const double *phi_dof,
const double *phi_nodes,
const double *xi_r,
bool isBoundary)
125 return calculate(phi_dof, phi_nodes, xi_r, 1.0, 1.0, 0.0, isBoundary,
false);
136 if (useIfemBasis && (
edge == -1 ||
corner == -1))
142 else if (useIfemBasis && (
edge == 1 ||
corner == 1))
163 for (
int i = 0; i < nP_ifem; i++)
165 _va_q[i] = _va[
q * nP_ifem + i];
166 _vb_q[i] = _vb[
q * nP_ifem + i];
168 for (
int i = 0; i < nP_ifem; i++)
170 _va_x_q[i] = _va_x[
q * nP_ifem + i];
171 _va_y_q[i] = _va_y[
q * nP_ifem + i];
172 _va_z_q[i] = _va_z[
q * nP_ifem + i];
173 _vb_x_q[i] = _vb_x[
q * nP_ifem + i];
174 _vb_y_q[i] = _vb_y[
q * nP_ifem + i];
175 _vb_z_q[i] = _vb_z[
q * nP_ifem + i];
187 if (useIfemBasis && (
edge == -1 ||
corner == -1))
193 else if (useIfemBasis && (
edge == 1 ||
corner == 1))
201 _H_q = _ImH_ebq[ebq];
202 _ImH_q = _H_ebq[ebq];
208 _ImH_q = _ImH_ebq[ebq];
212 for (
int i = 0; i < nP_ifem; i++)
214 _va_q[i] = _va_ebq[ebq * nP_ifem + i];
215 _vb_q[i] = _vb_ebq[ebq * nP_ifem + i];
217 for (
int i = 0; i < nP_ifem; i++)
219 _va_x_q[i] = _va_x_ebq[ebq * nP_ifem + i];
220 _va_y_q[i] = _va_y_ebq[ebq * nP_ifem + i];
221 _vb_x_q[i] = _vb_x_ebq[ebq * nP_ifem + i];
222 _vb_y_q[i] = _vb_y_ebq[ebq * nP_ifem + i];
226 inline double *
get_H() {
return _H; };
228 inline double *
get_D() {
return _D; };
229 inline double H(
double eps,
double phi) {
return _H_q; };
230 inline double ImH(
double eps,
double phi) {
return _ImH_q; };
231 inline double D(
double eps,
double phi) {
return _D_q; };
232 inline double VA(
int i) {
return _va_q[i]; };
233 inline double VA_x(
int i) {
return _va_x_q[i]; };
234 inline double VA_y(
int i) {
return _va_y_q[i]; };
235 inline double VA_z(
int i) {
return _va_z_q[i]; };
236 inline double VB(
int i) {
return _vb_q[i]; };
237 inline double VB_x(
int i) {
return _vb_x_q[i]; };
238 inline double VB_y(
int i) {
return _vb_y_q[i]; };
239 inline double VB_z(
int i) {
return _vb_z_q[i]; };
242 return level_set_normal;
251 static const unsigned int nN = nSpace + 1;
257 static const unsigned int nDOF_phi = (useIfemBasis && nP_ifem >
nN) ? nP_ifem :
nN;
265 int P2_ifem_case = 0;
270 double _H_q = 0., _ImH_q = 0., _D_q = 0., _va_q[nP_ifem] = {}, _vb_q[nP_ifem] = {},
271 _va_x_q[nP_ifem] = {}, _va_y_q[nP_ifem] = {}, _va_z_q[nP_ifem] = {},
272 _vb_x_q[nP_ifem] = {}, _vb_y_q[nP_ifem] = {}, _vb_z_q[nP_ifem] = {};
278 unsigned int root_node = 0, permutation[
nDOF_phi] = {};
285 double _a1[nP_ifem] = {}, _a2[nP_ifem] = {}, _a3[nP_ifem] = {}, _b1[nP_ifem] = {}, _b2[nP_ifem] = {}, _b3[nP_ifem] = {};
286 double _a4[nP_ifem] = {}, _a5[nP_ifem] = {}, _a6[nP_ifem] = {}, _b4[nP_ifem] = {}, _b5[nP_ifem] = {}, _b6[nP_ifem] = {};
287 double Jac[nSpace * nSpace] = {}, inv_Jac[nSpace * nSpace] = {}, det_Jac = 0.;
288 double level_set_normal[nSpace], X_0[nSpace], phys_nodes_cut[(
nN - 1) * 3], THETA_01, THETA_02, THETA_31, THETA_32, phys_nodes_cut_quad_01[3], phys_nodes_cut_quad_02[3], phys_nodes_cut_quad_31[3], phys_nodes_cut_quad_32[3];
289 static const unsigned int nDOF = ((nSpace - 1) / 2) * (nSpace - 2) * (nP + 1) * (nP + 2) * (nP + 3) / 6 + (nSpace - 1) * (3 - nSpace) * (nP + 1) * (nP + 2) / 2 + (2 - nSpace) * ((3 - nSpace) / 2) * (nP + 1);
290 double Ainv[nDOF * nDOF];
291 double C_H[nDOF] = {}, C_ImH[nDOF] = {}, C_D[nDOF] = {};
292 inline int _calculate_permutation(
const double *phi_dof,
const double *phi_nodes);
293 inline void _calculate_cuts();
294 inline void _calculate_cuts_quad();
295 inline void _calculate_C();
296 inline void _correct_phi(
const double *phi_dof,
const double *phi_nodes);
297 double _H[nQ] = {}, _ImH[nQ] = {}, _D[nQ] = {}, _va[nQ * nP_ifem] = {}, _vb[nQ * nP_ifem] = {};
298 double _H_ebq[nEBQ] = {}, _ImH_ebq[nEBQ] = {}, _D_ebq[nEBQ] = {}, _va_ebq[nEBQ * nP_ifem] = {}, _vb_ebq[nEBQ * nP_ifem] = {};
299 double _va_x[nQ * nP_ifem] = {}, _va_y[nQ * nP_ifem] = {}, _va_z[nQ * nP_ifem] = {}, _vb_x[nQ * nP_ifem] = {}, _vb_y[nQ * nP_ifem] = {}, _vb_z[nQ * nP_ifem] = {};
300 double _va_x_ebq[nEBQ * nP_ifem] = {}, _va_y_ebq[nEBQ * nP_ifem] = {}, _va_z_ebq[nEBQ * nP_ifem] = {}, _vb_x_ebq[nEBQ * nP_ifem] = {}, _vb_y_ebq[nEBQ * nP_ifem] = {}, _vb_z_ebq[nEBQ * nP_ifem] = {};
301 inline void _calculate_basis_coefficients(
const double ma,
const double mb,
const double jf);
302 inline void _calculate_basis(
const double *xi,
double *va,
double *vb);
303 inline void _calculate_basis_gradients(
const double *xi,
double *va_x,
double *va_y,
double *vb_x,
double *vb_y);
306 template <
int nSpace,
int nP_ifem,
int nP,
int nQ,
int nEBQ,
bool useIfemBasis>
307 inline void Simplex<nSpace, nP_ifem, nP, nQ, nEBQ, useIfemBasis>::_calculate_C()
309 double b_H[nDOF], b_ImH[nDOF], b_dH[nDOF * nSpace], b_D[nDOF * nSpace];
313 phi_dof_corrected[permutation[0]],
314 phi_dof_corrected[permutation[1]],
315 phi_dof_corrected[permutation[2]],
316 phi_dof_corrected[permutation[3]],
320 for (
unsigned int i = 0; i < nDOF; i++)
325 for (
unsigned int i = 0; i < nDOF; i++)
330 for (
unsigned int j = 0; j < nDOF; j++)
332 assert(!std::isnan(Ainv[i * nDOF + j]));
333 assert(!std::isnan(b_H[j]));
334 assert(!std::isnan(b_ImH[j]));
335 assert(!std::isnan(b_D[j]));
336 C_H[i] += Ainv[i * nDOF + j] * b_H[j];
337 C_ImH[i] += Ainv[i * nDOF + j] * b_ImH[j];
338 C_D[i] += Ainv[i * nDOF + j] * b_D[j];
348 double Jt_dphi_dx[nSpace];
349 for (
unsigned int I = 0; I < nSpace; I++)
352 for (
unsigned int J = 0; J < nSpace; J++)
353 Jt_dphi_dx[I] += Jac[J * nSpace + I] * level_set_normal[J];
355 for (
unsigned int i = 0; i < nDOF; i++)
360 for (
unsigned int j = 0; j < nDOF; j++)
362 C_H[i] += Ainv[i * nDOF + j] * b_H[j];
363 C_ImH[i] += Ainv[i * nDOF + j] * b_ImH[j];
364 for (
unsigned int I = 0; I < nSpace; I++)
366 if (fabs(Jt_dphi_dx[I]) > 0.0)
367 C_D[i] -= Ainv[i * nDOF + j] * b_dH[j * nSpace + I] / (Jt_dphi_dx[I]);
377 for (
unsigned int i = 0; i < nDOF; i++)
382 template <
int nSpace,
int nP_ifem,
int nP,
int nQ,
int nEBQ,
bool useIfemBasis>
383 inline int Simplex<nSpace, nP_ifem, nP, nQ, nEBQ, useIfemBasis>::_calculate_permutation(
const double *phi_dof,
const double *phi_nodes)
393 int temp = permutation[1];
394 permutation[1] = permutation[2];
395 permutation[2] = temp;
396 temp = permutation[3];
397 permutation[3] = permutation[5];
398 permutation[5] = temp;
399 flip_the_cell =
false;
410 int p_i, pcount = 0, n_i, ncount = 0, z_i, zcount = 0;
417 const double eps = 1.0e-8;
419 for (
unsigned int i = 0; i < nN; i++)
423 if (phi_dof[i] > eps)
429 else if (phi_dof[i] < -eps)
449 else if (ncount == nN)
455 else if (ncount == 1)
457 if (zcount == nN - 1)
462 else if (zcount == 1 && pcount == 1)
469 else if (pcount == 1)
471 if (zcount == nN - 1)
479 else if (nSpace == 3 && pcount == 2 && ncount == 2)
487 assert(zcount < nN - 1);
489 if (pcount && !ncount)
492 assert(pcount == nN - 1);
500 else if (ncount && !pcount)
503 assert(ncount == nN - 1);
506 root_node = useIfemBasis ? z_i : n_i;
512 for (
unsigned int i = 0; i < nDOF_phi; i++)
525 permutation[i] = (root_node + i) % nN;
527 permutation[i] = nN + (root_node + i) % nN;
531 if (phi_dof[permutation[nN - 1]] > 0.0)
533 int tmp = permutation[nN - 1];
534 if (phi_dof[permutation[nN - 2]] < 0.0)
536 permutation[nN - 1] = permutation[nN - 2];
537 permutation[nN - 2] = tmp;
539 else if (phi_dof[permutation[nN - 3]] < 0.0)
541 permutation[nN - 1] = permutation[nN - 3];
542 permutation[nN - 3] = tmp;
547 assert(phi_dof[permutation[0]] < 0.0);
548 assert(phi_dof[permutation[3]] < 0.0);
549 assert(phi_dof[permutation[1]] > 0.0);
550 assert(phi_dof[permutation[2]] > 0.0);
554 for (
unsigned int i = 0; i < nDOF_phi; i++)
556 phi[i] = phi_dof[permutation[i]];
558 for (
unsigned int I = 0; I < 3; I++)
560 nodes[i * 3 + I] = phi_nodes[permutation[i] * 3 + I];
565 double JacTest[nSpace * nSpace];
566 for (
unsigned int I = 0; I < nSpace; I++)
568 for (
unsigned int i = 0; i < nN - 1; i++)
570 Jac[I * nSpace + i] = nodes[(1 + i) * 3 + I] - nodes[I];
571 JacTest[I * nSpace + i] = phi_nodes[(1 + i) * 3 + I] - phi_nodes[I];
581 if (det_Jac < 0.0 && flip_the_cell)
585 double tmp = permutation[2];
586 permutation[2] = permutation[1];
587 permutation[1] = tmp;
591 double tmp = permutation[nN - 1];
592 permutation[nN - 1] = permutation[nN - 2];
593 permutation[nN - 2] = tmp;
595 for (
unsigned int i = 0; i < nDOF_phi; i++)
597 phi[i] = phi_dof[permutation[i]];
598 for (
unsigned int I = 0; I < 3; I++)
600 nodes[i * 3 + I] = phi_nodes[permutation[i] * 3 + I];
603 for (
unsigned int i = 0; i < nN - 1; i++)
604 for (
unsigned int I = 0; I < nSpace; I++)
605 Jac[I * nSpace + i] = nodes[(1 + i) * 3 + I] - nodes[I];
615 template <
int nSpace,
int nP_ifem,
int nP,
int nQ,
int nEBQ,
bool useIfemBasis>
616 inline void Simplex<nSpace, nP_ifem, nP, nQ, nEBQ, useIfemBasis>::_calculate_cuts()
618 const double eps = 1.0e-8;
619 for (
unsigned int i = 0; i < nN - 1; i++)
621 if (useIfemBasis && (corner == 1 || corner == -1))
624 for (
unsigned int I = 0; I < 3; I++)
626 phys_nodes_cut[i * 3 + I] = nodes[I];
629 else if (
phi[i + 1] *
phi[0] < 0.0)
631 X_0[i] = 0.5 - 0.5 * (
phi[i + 1] +
phi[0]) / (
phi[i + 1] -
phi[0]);
632 assert(X_0[i] <= 1.0);
633 assert(X_0[i] >= 0.0);
634 for (
unsigned int I = 0; I < 3; I++)
636 phys_nodes_cut[i * 3 + I] = (1 - X_0[i]) * nodes[I] + X_0[i] * nodes[(1 + i) * 3 + I];
644 if (
phi[i + 1] < eps)
647 for (
unsigned int I = 0; I < 3; I++)
649 phys_nodes_cut[i * 3 + I] = nodes[(1 + i) * 3 + I];
655 for (
unsigned int I = 0; I < 3; I++)
657 phys_nodes_cut[i * 3 + I] = nodes[I];
669 if (nP_ifem == 6 && (X_0[0] > 0.5 && X_0[1] <= 0.5))
672 flip_the_cell =
true;
676 template <
int nSpace,
int nP_ifem,
int nP,
int nQ,
int nEBQ,
bool useIfemBasis>
677 inline void Simplex<nSpace, nP_ifem, nP, nQ, nEBQ, useIfemBasis>::_calculate_cuts_quad()
679 const double eps = 1.0e-8, Imeps = 1.0 - eps;
680 THETA_01 = 0.5 - 0.5 * (
phi[1] +
phi[0]) / (
phi[1] -
phi[0]);
681 THETA_02 = 0.5 - 0.5 * (
phi[2] +
phi[0]) / (
phi[2] -
phi[0]);
682 THETA_31 = 0.5 - 0.5 * (
phi[1] +
phi[3]) / (
phi[1] -
phi[3]);
683 THETA_32 = 0.5 - 0.5 * (
phi[2] +
phi[3]) / (
phi[2] -
phi[3]);
684 if ((THETA_01 < eps || THETA_01 > Imeps) || (THETA_02 < eps || THETA_02 > Imeps) || (THETA_31 < eps || THETA_31 > Imeps) || (THETA_32 < eps || THETA_32 > Imeps))
686 THETA_01 = fmin(Imeps, fmax(eps, 0.5 - 0.5 * (
phi[1] +
phi[0]) / (
phi[1] -
phi[0])));
687 THETA_02 = fmin(Imeps, fmax(eps, 0.5 - 0.5 * (
phi[2] +
phi[0]) / (
phi[2] -
phi[0])));
688 THETA_31 = fmin(Imeps, fmax(eps, 0.5 - 0.5 * (
phi[1] +
phi[3]) / (
phi[1] -
phi[3])));
689 THETA_32 = fmin(Imeps, fmax(eps, 0.5 - 0.5 * (
phi[2] +
phi[3]) / (
phi[2] -
phi[3])));
691 for (
unsigned int I = 0; I < 3; I++)
693 phys_nodes_cut_quad_01[I] = (1 - THETA_01) * nodes[I] + THETA_01 * nodes[1 * 3 + I];
694 phys_nodes_cut_quad_02[I] = (1 - THETA_02) * nodes[I] + THETA_02 * nodes[2 * 3 + I];
695 phys_nodes_cut_quad_31[I] = (1 - THETA_31) * nodes[3 * 3 + I] + THETA_31 * nodes[1 * 3 + I];
696 phys_nodes_cut_quad_32[I] = (1 - THETA_32) * nodes[3 * 3 + I] + THETA_32 * nodes[2 * 3 + I];
700 template <
int nSpace,
int nP_ifem,
int nP,
int nQ,
int nEBQ,
bool useIfemBasis>
701 inline void Simplex<nSpace, nP_ifem, nP, nQ, nEBQ, useIfemBasis>::_correct_phi(
const double *phi_dof,
const double *phi_nodes)
703 memset(cut_barycenter, 0, 3 *
sizeof(
double));
704 const double one_by_nNm1 = 1.0 / (nN - 1.0);
707 for (
unsigned int I = 0; I < nSpace; I++)
708 cut_barycenter[I] += 0.25 * (phys_nodes_cut_quad_01[I] +
709 phys_nodes_cut_quad_02[I] +
710 phys_nodes_cut_quad_31[I] +
711 phys_nodes_cut_quad_32[I]);
715 for (
unsigned int i = 0; i < nN - 1; i++)
717 assert(!std::isnan(phys_nodes_cut[i * 3 + 0]));
718 assert(!std::isnan(phys_nodes_cut[i * 3 + 1]));
719 assert(!std::isnan(phys_nodes_cut[i * 3 + 2]));
720 for (
unsigned int I = 0; I < nSpace; I++)
721 cut_barycenter[I] += phys_nodes_cut[i * 3 + I] * one_by_nNm1;
724 for (
unsigned int i = 0; i < nDOF_phi; i++)
726 phi_dof_corrected[i] = 0.0;
727 for (
unsigned int I = 0; I < nSpace; I++)
729 phi_dof_corrected[i] += level_set_normal[I] * (phi_nodes[i * 3 + I] - cut_barycenter[I]);
732 if (phi_dof_corrected[i] * phi_dof[i] < 0.0)
734 phi_dof_corrected[i] *= -1.0;
739 template <
int nSpace,
int nP_ifem,
int nP,
int nQ,
int nEBQ,
bool useIfemBasis>
740 inline void Simplex<nSpace, nP_ifem, nP, nQ, nEBQ, useIfemBasis>::_calculate_basis_coefficients(
const double ma,
const double mb,
const double jf)
744 double nx = 0.0, ny = 0.0;
747 nx = -level_set_normal[0];
748 ny = -level_set_normal[1];
752 nx = level_set_normal[0];
753 ny = level_set_normal[1];
755 double Jit00 = inv_Jac[0 * nSpace + 0],
756 Jit01 = inv_Jac[1 * nSpace + 0],
757 Jit10 = inv_Jac[0 * nSpace + 1],
758 Jit11 = inv_Jac[1 * nSpace + 1];
761 const double *vall =
nullptr;
773 static const double vall_p1[9] = {
778 for (
int j = 0; j < 3; j++)
780 int i = permutation[j];
781 double v[3] = {0.0, 0.0, 0.0};
782 v[0] = vall[j * 3 + 0];
783 v[1] = vall[j * 3 + 1];
784 v[2] = vall[j * 3 + 2];
789 _a2[i] = -
v[0] +
v[1];
790 _a3[i] = -
v[0] +
v[2];
792 _b2[i] = -
v[0] +
v[1];
793 _b3[i] = -
v[0] +
v[2];
798 const std::array<double, 3> nodal_values = {
v[0],
v[1],
v[2]};
802 1, x0, y0, nx, ny, mb, ma, jf, Jit00, Jit01, Jit10, Jit11, nodal_values);
815 1, x0, y0, nx, ny, ma, mb, jf, Jit00, Jit01, Jit10, Jit11, nodal_values);
830 static const double vall_p2[36] = {
831 1., 0., 0., 0., 0., 0.,
832 0., 1., 0., 0., 0., 0.,
833 0., 0., 1., 0., 0., 0.,
834 0., 0., 0., 1., 0., 0.,
835 0., 0., 0., 0., 1., 0.,
836 0., 0., 0., 0., 0., 1.};
839 for (
int j = 0; j < 6; j++)
841 int i = permutation[j];
842 double v[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
844 v[0] = vall[j * 6 + 0];
845 v[1] = vall[j * 6 + 1];
846 v[2] = vall[j * 6 + 2];
847 v[3] = vall[j * 6 + 3];
848 v[4] = vall[j * 6 + 4];
849 v[5] = vall[j * 6 + 5];
855 _a2[i] = - 3 *
v[0] -
v[1] + 4 *
v[3];
856 _a3[i] = - 3 *
v[0] -
v[2] + 4 *
v[5];
857 _a4[i] = 4 *
v[0] - 4 *
v[3] + 4 *
v[4] - 4 *
v[5];
858 _a5[i] = 2 *
v[0] + 2 *
v[1] - 4 *
v[3];
859 _a6[i] = 2 *
v[0] + 2 *
v[2] - 4 *
v[5];
861 _b2[i] = - 3 *
v[0] -
v[1] + 4 *
v[3];
862 _b3[i] = - 3 *
v[0] -
v[2] + 4 *
v[5];
863 _b4[i] = 4 *
v[0] - 4 *
v[3] + 4 *
v[4] - 4 *
v[5];
864 _b5[i] = 2 *
v[0] + 2 *
v[1] - 4 *
v[3];
865 _b6[i] = 2 *
v[0] + 2 *
v[2] - 4 *
v[5];
871 const std::array<double, 6> nodal_values = {
v[0],
v[1],
v[2],
v[3],
v[4],
v[5]};
873 2, x0, y0, nx, ny, mb, ma, jf, Jit00, Jit01, Jit10, Jit11, nodal_values);
890 const std::array<double, 6> nodal_values = {
v[0],
v[1],
v[2],
v[3],
v[4],
v[5]};
892 2, x0, y0, nx, ny, ma, mb, jf, Jit00, Jit01, Jit10, Jit11, nodal_values);
912 throw std::runtime_error(
"Simplex::_calculate_coefficients not implemented for order > 2");
916 template <
int nSpace,
int nP_ifem,
int nP,
int nQ,
int nEBQ,
bool useIfemBasis>
917 inline void Simplex<nSpace, nP_ifem, nP, nQ, nEBQ, useIfemBasis>::_calculate_basis(
const double *xi,
double *va,
double *vb)
923 for (
int i = 0; i < nP_ifem; i++)
925 va[i] = _a1[i] + _a2[i] * xi[0] + _a3[i] * xi[1];
926 vb[i] = _b1[i] + _b2[i] * xi[0] + _b3[i] * xi[1];
936 for (
int i = 0; i < nP_ifem; i++)
938 va[i] = _a1[i] + _a2[i] * xi[0] + _a3[i] * xi[1] + _a4[i] * xi[0] * xi[1] + _a5[i] * xi[0] * xi[0] + _a6[i] * xi[1] * xi[1];
939 vb[i] = _b1[i] + _b2[i] * xi[0] + _b3[i] * xi[1] + _b4[i] * xi[0] * xi[1] + _b5[i] * xi[0] * xi[0] + _b6[i] * xi[1] * xi[1];
950 throw std::runtime_error(
"Simplex::_calculate_basis not implemented for order > 2");
954 template <
int nSpace,
int nP_ifem,
int nP,
int nQ,
int nEBQ,
bool useIfemBasis>
955 inline void Simplex<nSpace, nP_ifem, nP, nQ, nEBQ, useIfemBasis>::_calculate_basis_gradients(
const double *xi,
double *va_x,
double *va_y,
double *vb_x,
double *vb_y)
962 for (
int i = 0; i < nP_ifem; i++)
964 double grad_va[2] = {0.0, 0.0}, grad_vb[2] = {0.0, 0.0}, grad_va_ref[2] = {0.0, 0.0}, grad_vb_ref[2] = {0.0, 0.0};
967 grad_va_ref[0] = _a2[i];
968 grad_va_ref[1] = _a3[i];
969 grad_vb_ref[0] = _b2[i];
970 grad_vb_ref[1] = _b3[i];
971 for (
int I = 0; I < nSpace; I++)
973 for (
int J = 0; J < nSpace; J++)
976 grad_va[I] += inv_Jac[J * nSpace + I] * grad_va_ref[J];
977 grad_vb[I] += inv_Jac[J * nSpace + I] * grad_vb_ref[J];
988 va_x[i] = grad_va[0];
989 va_y[i] = grad_va[1];
990 vb_x[i] = grad_vb[0];
991 vb_y[i] = grad_vb[1];
1004 for (
int i = 0; i < nP_ifem; i++)
1006 double grad_va[2] = {0.0, 0.0}, grad_vb[2] = {0.0, 0.0}, grad_va_ref[2] = {0.0, 0.0}, grad_vb_ref[2] = {0.0, 0.0};
1009 grad_va_ref[0] = _a2[i] + _a4[i] * xi[1] + 2.0 * _a5[i] * xi[0];
1010 grad_va_ref[1] = _a3[i] + _a4[i] * xi[0] + 2.0 * _a6[i] * xi[1];
1011 grad_vb_ref[0] = _b2[i] + _b4[i] * xi[1] + 2.0 * _b5[i] * xi[0];
1012 grad_vb_ref[1] = _b3[i] + _b4[i] * xi[0] + 2.0 * _b6[i] * xi[1];
1017 for (
int I = 0; I < nSpace; I++)
1019 for (
int J = 0; J < nSpace; J++)
1023 grad_va[I] += inv_Jac[J * nSpace + I] * grad_va_ref[J];
1024 grad_vb[I] += inv_Jac[J * nSpace + I] * grad_vb_ref[J];
1039 va_x[i] = grad_va[0];
1040 va_y[i] = grad_va[1];
1041 vb_x[i] = grad_vb[0];
1042 vb_y[i] = grad_vb[1];
1047 throw std::runtime_error(
"Simplex::_calculate_basis_gradients not implemented for order > 2");
1051 template <
int nSpace,
int nP_ifem,
int nP,
int nQ,
int nEBQ,
bool useIfemBasis>
1052 inline int Simplex<nSpace, nP_ifem, nP, nQ, nEBQ, useIfemBasis>::calculate(
const double *phi_dof,
const double *phi_nodes,
const double *xi_r,
double ma,
double mb,
double jf,
bool isBoundary,
bool scale)
1055 for (
unsigned int i = 0; i <
nDOF_phi; i++)
1057 int icase = _calculate_permutation(phi_dof, phi_nodes);
1060 for (
unsigned int q = 0;
q < nQ;
q++)
1066 for (
unsigned int ebq = 0; ebq < nEBQ; ebq++)
1069 _ImH_ebq[ebq] = 0.0;
1074 else if (icase == -1)
1076 for (
unsigned int q = 0;
q < nQ;
q++)
1082 for (
unsigned int ebq = 0; ebq < nEBQ; ebq++)
1085 _ImH_ebq[ebq] = 1.0;
1090 else if (nSpace == 1 &&
edge == 1)
1101 for (
unsigned int q = 0;
q < nQ;
q++)
1107 for (
unsigned int ebq = 0; ebq < nEBQ; ebq++)
1110 _ImH_ebq[ebq] = 0.0;
1115 else if (nSpace == 1 &&
edge == -1)
1119 for (
unsigned int q = 0;
q < nQ;
q++)
1125 for (
unsigned int ebq = 0; ebq < nEBQ; ebq++)
1128 _ImH_ebq[ebq] = 1.0;
1135 _calculate_cuts_quad();
1137 phys_nodes_cut_quad_02,
1138 phys_nodes_cut_quad_31,
1139 phys_nodes_cut_quad_32,
1147 _correct_phi(phi_dof, phi_nodes);
1150 _calculate_permutation(phi_dof, phi_nodes);
1155 double ma_scale, mb_scale;
1159 double jump_scale = level_set_normal[1],
1160 m_average = 0.5 * (ma + mb),
1161 m_jump = 0.5 * (mb - ma);
1162 mb_scale = m_average + jump_scale * m_jump;
1163 ma_scale = m_average - jump_scale * m_jump;
1179 _calculate_basis_coefficients(ma_scale, mb_scale, jf);
1181 double Jac_0[nSpace * nSpace];
1182 for (
unsigned int i = 0; i <
nN - 1; i++)
1183 for (
unsigned int I = 0; I < nSpace; I++)
1184 Jac_0[I * nSpace + i] = phi_nodes[(1 + i) * 3 + I] - phi_nodes[I];
1188 for (
unsigned int q = 0;
q < nQ;
q++)
1192 double x[nSpace], xi[nSpace];
1194 for (
unsigned int I = 0; I < nSpace; I++)
1196 x[I] = phi_nodes[I];
1197 for (
unsigned int J = 0; J < nSpace; J++)
1199 x[I] += Jac_0[I * nSpace + J] * xi_r[
q * 3 + J];
1203 for (
unsigned int I = 0; I < nSpace; I++)
1206 for (
unsigned int J = 0; J < nSpace; J++)
1208 xi[I] += inv_Jac[I * nSpace + J] * (x[J] - nodes[J]);
1213 else if (nSpace == 2)
1220 _calculate_basis(xi, &_va[
q * nP_ifem], &_vb[
q * nP_ifem]);
1221 _calculate_basis_gradients(xi, &_va_x[
q * nP_ifem], &_va_y[
q * nP_ifem], &_vb_x[
q * nP_ifem], &_vb_y[
q * nP_ifem]);
1224 else if (nSpace == 3)
1231 for (
unsigned int ebq = 0; ebq < nEBQ; ebq++)
1235 double x[nSpace], xi[nSpace];
1237 for (
unsigned int I = 0; I < nSpace; I++)
1239 x[I] = phi_nodes[I];
1240 for (
unsigned int J = 0; J < nSpace; J++)
1242 x[I] += Jac_0[I * nSpace + J] * xi_r[ebq * 3 + J];
1246 for (
unsigned int I = 0; I < nSpace; I++)
1249 for (
unsigned int J = 0; J < nSpace; J++)
1251 xi[I] += inv_Jac[I * nSpace + J] * (x[J] - nodes[J]);
1256 else if (nSpace == 2)
1263 _calculate_basis(xi, &_va_ebq[ebq * nP_ifem], &_vb_ebq[ebq * nP_ifem]);
1264 _calculate_basis_gradients(xi, &_va_x_ebq[ebq * nP_ifem], &_va_y_ebq[ebq * nP_ifem], &_vb_x_ebq[ebq * nP_ifem], &_vb_y_ebq[ebq * nP_ifem]);
1267 else if (nSpace == 3)
1278 for (
unsigned int I = 0; I < nSpace; I++)
1279 level_set_normal[I] *= -1.0;