18#ifdef MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC
19#pragma GCC diagnostic push
20#pragma GCC diagnostic ignored "-Wunused-function"
23#ifndef GSLIB_RELEASE_VERSION
24#define GSLIB_RELEASE_VERSION 10007
26#ifdef MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC
27#pragma GCC diagnostic pop
34#if GSLIB_RELEASE_VERSION >= 10009
35#define CODE_INTERNAL 0
37#define CODE_NOT_FOUND 2
41struct findptsElementPoint_t
43 double x[
DIM], r[
DIM], oldr[
DIM], dist2, dist2p, tr;
47struct findptsElementGEdge_t
49 double *x[
DIM], *dxdn[2];
52struct findptsElementGPT_t
67struct findptsLocalHashData_t
78static MFEM_HOST_DEVICE
inline void lag_eval_first_der(
double *p0,
double x,
79 int i,
const double *z,
83 double u0 = 1, u1 = 0;
84 for (
int j = 0; j < pN; ++j)
88 double d_j = 2 * (x - z[j]);
93 p0[i] = lCoeff[i] * u0;
94 p0[pN+i] = 2.0 * lCoeff[i] * u1;
99static MFEM_HOST_DEVICE
inline void lag_eval_second_der(
double *p0,
double x,
100 int i,
const double *z,
101 const double *lCoeff,
104 double u0 = 1, u1 = 0, u2 = 0;
105 for (
int j = 0; j < pN; ++j)
109 double d_j = 2 * (x - z[j]);
115 p0[i] = lCoeff[i] * u0;
116 p0[pN+i] = 2.0 * lCoeff[i] * u1;
117 p0[2*pN+i] = 8.0 * lCoeff[i] * u2;
121static MFEM_HOST_DEVICE
inline double AABB_test(
const obbox_t *
const b,
125 for (
int d = 0; d < 2; ++d)
127 double b_d = (x[d] -
b->x[d].min) * (
b->x[d].max - x[d]);
128 test = test < 0 ? test : b_d;
134static MFEM_HOST_DEVICE
inline double bbox_test(
const obbox_t *
const b,
137 const double bxyz = AABB_test(
b, x);
145 for (
int d = 0; d < 2; ++d)
147 dxyz[d] = x[d] -
b->c0[d];
150 for (
int d = 0; d < 2; ++d)
153 for (
int e = 0; e < 2; ++e)
155 rst +=
b->A[d * 2 + e] * dxyz[e];
157 double brst = (rst + 1) * (1 - rst);
158 test = test < 0 ? test : brst;
165static MFEM_HOST_DEVICE
inline int hash_index(
const findptsLocalHashData_t *
p,
168 const int n =
p->hash_n;
170 for (
int d = 2 - 1; d >= 0; --d)
173 int i = (int)floor((x[d] -
p->bnd[d].min) *
p->fac[d]);
174 sum += i < 0 ? 0 : (n - 1 < i ? n - 1 : i);
180static MFEM_HOST_DEVICE
inline void lin_solve_2(
double x[2],
const double A[4],
183 const double idet = 1/(A[0]*A[3] - A[1]*A[2]);
184 x[0] = idet*(A[3]*y[0] - A[1]*y[1]);
185 x[1] = idet*(A[0]*y[1] - A[2]*y[0]);
189static MFEM_HOST_DEVICE
inline double l2norm2(
const double x[2])
191 return x[0] * x[0] + x[1] * x[1];
202#define CONVERGED_FLAG (1u<<4)
203#define FLAG_MASK 0x1fu
206static MFEM_HOST_DEVICE
inline int num_constrained(
const int flags)
208 const int y = flags | flags >> 1;
209 return (y&1u) + (y>>2 & 1u);
213static MFEM_HOST_DEVICE
inline int plus_1_mod_2(
const int x)
218static MFEM_HOST_DEVICE
inline int which_bit(
const int x)
220 const int y = x & 7u;
221 return (y-(y>>2)) | ((x-1)&4u);
225static MFEM_HOST_DEVICE
inline int edge_index(
const int x)
227 return which_bit(x)-1;
231static MFEM_HOST_DEVICE
inline int point_index(
const int x)
233 return ((x>>1)&1u) | ((x>>2)&2u);
238static MFEM_HOST_DEVICE
inline findptsElementGEdge_t
239get_edge(
const double *elx[2],
const double *wtend,
int ei,
241 int &side_init,
int j,
int pN)
243 findptsElementGEdge_t edge;
244 const int jidx = ei >= 2 ? j : ei*(pN-1);
245 const int kidx = ei >= 2 ? (ei-2)*(pN-1) : j;
249 const double *wt1 = wtend + (ei%2==0 ? 0 : 1)* pN * 3 + pN;
251 for (
int d = 0; d < 2; ++d)
253 edge.x[d] = workspace + d * pN;
254 edge.dxdn[d] = workspace + (2 + d) * pN;
257 if (side_init != (1u << ei))
259#define ELX(d, j, k) elx[d][j + k * pN]
260 for (
int d = 0; d < 2; ++d)
263 edge.x[d][j] = ELX(d, jidx, kidx);
267 for (
int k = 0; k < pN; ++k)
271 sums_k += wt1[k] * ELX(d, j, k);
275 sums_k += wt1[k] * ELX(d, k, j);
278 edge.dxdn[d][j] = sums_k;
289static MFEM_HOST_DEVICE
inline findptsElementGPT_t get_pt(
const double *elx[2],
293 findptsElementGPT_t pt;
295#define ELX(d, j, k) elx[d][j + k * pN]
297 int r_g_wt_offset = pi % 2 == 0 ? 0 : 1;
298 int s_g_wt_offset = pi < 2 ? 0 : 1;
299 int jidx = pi % 2 == 0 ? 0 : pN-1;
300 int kidx = pi < 2 ? 0 : pN-1;
302 pt.x[0] = ELX(0, jidx, kidx);
303 pt.x[1] = ELX(1, jidx, kidx);
309 for (
int j = 0; j < pN; ++j)
312 pt.jac[0] += wtend[3 * r_g_wt_offset * pN + pN + j] * ELX(0, j, kidx);
315 pt.jac[2] += wtend[3 * r_g_wt_offset * pN + pN + j] * ELX(1, j, kidx);
318 pt.jac[1] += wtend[3 * s_g_wt_offset * pN + pN + j] * ELX(0, kidx, j);
321 pt.jac[3] += wtend[3 * s_g_wt_offset * pN + pN + j] * ELX(1, kidx, j);
328 for (
int j = 0; j < pN; ++j)
331 pt.hes[0] += wtend[3 * r_g_wt_offset * pN + 2*pN + j] * ELX(0, j, kidx);
334 pt.hes[2] += wtend[3 * r_g_wt_offset * pN + 2*pN + j] * ELX(1, j, kidx);
337 pt.hes[1] += wtend[3 * s_g_wt_offset * pN + 2*pN + j] * ELX(0, kidx, j);
340 pt.hes[3] += wtend[3 * s_g_wt_offset * pN + 2*pN + j] * ELX(1, kidx, j);
350static MFEM_HOST_DEVICE
bool reject_prior_step_q(findptsElementPoint_t *res,
351 const double resid[2],
352 const findptsElementPoint_t *
p,
355 const double dist2 = l2norm2(resid);
356 const double decr =
p->dist2 - dist2;
357 const double pred =
p->dist2p;
358 for (
int d = 0; d < 2; ++d)
361 res->oldr[d] =
p->r[d];
364 if (decr >= 0.01 * pred)
366 if (decr >= 0.9 * pred)
384 double v0 = fabs(
p->r[0] -
p->oldr[0]);
385 double v1 = fabs(
p->r[1] -
p->oldr[1]);
386 res->tr = (v0 > v1 ? v0 : v1)/4;
387 res->dist2 =
p->dist2;
388 for (
int d = 0; d < 2; ++d)
390 res->r[d] =
p->oldr[d];
392 res->flags =
p->flags >> 5;
393 res->dist2p = -HUGE_VAL;
394 if (pred < dist2 * tol)
396 res->flags |= CONVERGED_FLAG;
404static MFEM_HOST_DEVICE
void newton_area(findptsElementPoint_t *
const res,
406 const double resid[2],
407 const findptsElementPoint_t *
const p,
410 const double tr =
p->tr;
411 double bnd[4] = {-1, 1, -1, 1};
415 r0[0] =
p->r[0], r0[1] =
p->r[1];
418 for (d = 0; d < 2; ++d)
422 bnd[2 * d] = r0[d] - tr, mask ^= 1u << (2 * d);
426 bnd[2 * d + 1] = r0[d] + tr, mask ^= 2u << (2 * d);
431 lin_solve_2(dr, jac, resid);
434 for (d = 0; d < 2; ++d)
436 double nr = r0[d] + dr[d];
437 if ((nr - bnd[2 * d]) * (bnd[2 * d + 1] - nr) >= 0)
443 double f = (bnd[2 * d] - r0[d]) / dr[d];
446 fac =
f, flags = 1u << (2 * d);
451 double f = (bnd[2 * d + 1] - r0[d]) / dr[d];
454 fac =
f, flags = 2u << (2 * d);
461 goto newton_area_fin;
464 for (d = 0; d < 2; ++d)
471 const int ei = edge_index(flags);
472 const int dn = ei>>1, de = plus_1_mod_2(dn);
475 double ress[2], y, JtJ, drc;
476 ress[0] = resid[0] - (jac[0] * dr[0] + jac[1] * dr[1]);
477 ress[1] = resid[1] - (jac[2] * dr[0] + jac[3] * dr[1]);
479 y = jac[de] * ress[0] + jac[2+de] * ress[1];
481 JtJ = jac[de] * jac[de] + jac[2+de] * jac[2+de];
484 const double rz = r0[de] + dr[de], lb = bnd[2*de], ub = bnd[2*de+1];
485 const double nr = r0[de]+(dr[de]+drc);
486 if ((nr-lb) * (ub-nr) < 0)
490 double f = (lb-rz)/drc;
494 new_flags = 1u<<(2*de);
499 double f = (ub-rz)/drc;
503 new_flags = 2u<<(2*de);
509 dr[de] += facc * drc;
511 goto newton_area_relax;
517 const int old_flags = flags;
518 double ress[2], y[2];
520 ress[0] = resid[0] - (jac[0] * dr[0] + jac[1] * dr[1]);
521 ress[1] = resid[1] - (jac[2] * dr[0] + jac[3] * dr[1]);
523 y[0] = jac[0] * ress[0] + jac[2] * ress[1];
524 y[1] = jac[1] * ress[0] + jac[3] * ress[1];
525 for (
int dd = 0; dd < 2; ++dd)
527 int f = flags >> (2 * dd) & 3u;
530 dr[dd] = bnd[2 * dd + (
f - 1)] - r0[dd];
531 if (dr[dd] * y[dd] < 0)
533 flags &= ~(3u << (2 * dd));
537 if (flags == old_flags)
539 goto newton_area_fin;
541 switch (num_constrained(flags))
544 goto newton_area_edge;
550 if (fabs(dr[0]) + fabs(dr[1]) < tol)
552 flags |= CONVERGED_FLAG;
555 const double res0 = resid[0] - (jac[0] * dr[0] + jac[1] * dr[1]);
556 const double res1 = resid[1] - (jac[2] * dr[0] + jac[3] * dr[1]);
557 res->dist2p = resid[0] * resid[0] + resid[1] * resid[1] -
558 (res0 * res0 + res1 * res1);
560 for (
int dd = 0; dd < 2; ++dd)
562 int f = flags >> (2 * dd) & 3u;
563 res->r[dd] =
f == 0 ? r0[dd] + dr[dd] : (
f == 1 ? -1 : 1);
565 res->flags = flags | (
p->flags << 5);
569static MFEM_HOST_DEVICE
inline void newton_edge(findptsElementPoint_t *
const
573 const double resid[2],
577 const findptsElementPoint_t *
const p,
580 const double tr =
p->tr;
582 const double A = jac[de] * jac[de] + jac[2 + de] * jac[2 + de] - rhes;
584 const double y = jac[de] * resid[0] + jac[2 + de] * resid[1];
586 const double oldr =
p->r[de];
587 double dr, nr, tdr, tnr;
589 int new_flags = 0, tnew_flags = 0;
591#define EVAL(dr) (dr * A - 2 * y) * dr
596 dr = y / A, nr = oldr + dr;
597 if (fabs(dr) < tr && fabs(nr) < 1)
600 goto newton_edge_fin;
604 if ((nr = oldr - tr) > -1)
610 nr = -1, dr = -1 - oldr, new_flags = flags | 1u << (2 * de);
614 if ((tnr = oldr + tr) < 1)
620 tnr = 1, tdr = 1 - oldr, tnew_flags = flags | 2u << (2 * de);
626 nr = tnr, dr = tdr, v = tv, new_flags = tnew_flags;
633 new_flags |= CONVERGED_FLAG;
638 res->flags = flags | new_flags | (
p->flags << 5);
642static MFEM_HOST_DEVICE
void seed_j(
const double *elx[2],
653 for (
int k = 0; k < pN; ++k)
656 const int jk = j + k * pN;
658 for (
int d = 0; d < 2; ++d)
660 dx[d] = x[d] - elx[d][jk];
662 const double dist2_jkl = l2norm2(dx);
663 if (dist2[j] > dist2_jkl)
665 dist2[j] = dist2_jkl;
674static MFEM_HOST_DEVICE
double tensor_ig2_j(
double *g_partials,
685 for (
int k = 0; k < pN; ++k)
687 uJs +=
u[j + k * pN] * Js[k];
688 uDs +=
u[j + k * pN] * Ds[k];
691 g_partials[0] = uJs * Dr[j];
692 g_partials[1] = uDs * Jr[j];
696template<
int T_D1D = 0>
697static void FindPointsLocal2D_Kernel(
const int npt,
700 const int point_pos_ordering,
701 const double *xElemCoord,
704 const double *boxinfo,
706 const double *hashMin,
707 const double *hashFac,
708 unsigned int *hashOffset,
709 unsigned int *
const code_base,
710 unsigned int *
const el_base,
711 double *
const r_base,
712 double *
const dist2_base,
714 const double *lagcoeff,
717#define MAX_CONST(a, b) (((a) > (b)) ? (a) : (b))
718 const int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
719 const int D1D = T_D1D ? T_D1D : pN;
720 const int p_NE = D1D*D1D;
721 const int p_NEL = nel*p_NE;
722 MFEM_VERIFY(MD1 <= DofQuadLimits::MAX_D1D,
723 "Increase Max allowable polynomial order.");
724 MFEM_VERIFY(D1D != 0,
"Polynomial order not specified.");
725 const int nThreads = D1D*
DIM;
730 constexpr int size1 = 10*MD1 + 6;
731 constexpr int size2 = MD1*4;
732 constexpr int size3 = MD1*MD1*MD1*
DIM;
734 MFEM_SHARED
double r_workspace[size1];
735 MFEM_SHARED findptsElementPoint_t el_pts[2];
737 MFEM_SHARED
double constraint_workspace[size2];
738 MFEM_SHARED
int edge_init;
740 MFEM_SHARED
double elem_coords[MD1 <= 6 ? size3 : 1];
742 double *r_workspace_ptr;
743 findptsElementPoint_t *fpt, *tmp;
744 MFEM_FOREACH_THREAD(j,x,nThreads)
746 r_workspace_ptr = r_workspace;
752 int id_x = point_pos_ordering == 0 ? i : i*
DIM;
753 int id_y = point_pos_ordering == 0 ? i+npt : i*
DIM+1;
754 double x_i[2] = {x[id_x], x[id_y]};
756 unsigned int *code_i = code_base + i;
757 unsigned int *el_i = el_base + i;
758 double *r_i = r_base +
DIM * i;
759 double *dist2_i = dist2_base + i;
762 *code_i = CODE_NOT_FOUND;
766 findptsLocalHashData_t hash;
767 for (
int d = 0; d <
DIM; ++d)
769 hash.bnd[d].min = hashMin[d];
770 hash.fac[d] = hashFac[d];
772 hash.hash_n = hash_n;
773 hash.offset = hashOffset;
774 const int hi = hash_index(&hash, x_i);
775 const unsigned int *elp = hash.offset+hash.offset[hi],
776 *
const ele = hash.offset+hash.offset[hi+1];
778 for (; elp != ele; ++elp)
781 const unsigned int el = *elp;
785 int n_box_ents = 3*
DIM + DIM2;
787 for (
int idx = 0; idx <
DIM; ++idx)
789 box.c0[idx] = boxinfo[n_box_ents*el + idx];
790 box.x[idx].min = boxinfo[n_box_ents*el +
DIM + idx];
791 box.x[idx].max = boxinfo[n_box_ents*el + 2*
DIM + idx];
794 for (
int idx = 0; idx < DIM2; ++idx)
796 box.A[idx] = boxinfo[n_box_ents*el + 3*
DIM + idx];
799 if (bbox_test(&box, x_i) < 0) {
continue; }
806 MFEM_FOREACH_THREAD(j,x,nThreads)
808 const int qp = j % D1D;
809 const int d = j / D1D;
810 for (
int k = 0; k < D1D; ++k)
812 const int jk = qp + k * D1D;
813 elem_coords[jk + d*p_NE] =
814 xElemCoord[jk + el*p_NE + d*p_NEL];
820 const double *elx[
DIM];
821 for (
int d = 0; d <
DIM; d++)
823 elx[d] = MD1<= 6 ? &elem_coords[d*p_NE] :
824 xElemCoord + d*p_NEL + el * p_NE;
829 MFEM_FOREACH_THREAD(j,x,1)
831 fpt->dist2 = HUGE_VAL;
836 MFEM_FOREACH_THREAD(j,x,
DIM)
844 double *dist2_temp = r_workspace_ptr;
846 for (
int d = 0; d <
DIM; ++d)
848 r_temp[d] = dist2_temp + (1 + d) * D1D;
851 MFEM_FOREACH_THREAD(j,x,D1D)
853 seed_j(elx, x_i, gll1D, dist2_temp, r_temp, j, D1D);
857 MFEM_FOREACH_THREAD(j,x,1)
859 fpt->dist2 = HUGE_VAL;
860 for (
int jj = 0; jj < D1D; ++jj)
862 if (dist2_temp[jj] < fpt->dist2)
864 fpt->dist2 = dist2_temp[jj];
865 for (
int d = 0; d <
DIM; ++d)
867 fpt->r[d] = r_temp[d][jj];
875 MFEM_FOREACH_THREAD(j,x,1)
877 tmp->dist2 = HUGE_VAL;
882 MFEM_FOREACH_THREAD(j,x,
DIM)
884 tmp->x[j] = fpt->x[j];
885 tmp->r[j] = fpt->r[j];
889 for (
int step = 0; step < 50; step++)
891 switch (num_constrained(tmp->flags & FLAG_MASK))
895 double *wtr = r_workspace_ptr;
896 double *resid = wtr + 4 * D1D;
897 double *jac = resid + 2;
898 double *resid_temp = jac + 4;
899 double *jac_temp = resid_temp + 2 * D1D;
901 MFEM_FOREACH_THREAD(j,x,nThreads)
903 const int qp = j % D1D;
904 const int d = j / D1D;
905 lag_eval_first_der(wtr + 2*d*D1D, tmp->r[d], qp,
906 gll1D, lagcoeff, D1D);
910 MFEM_FOREACH_THREAD(j,x,nThreads)
912 const int qp = j % D1D;
913 const int d = j / D1D;
914 double *idx = jac_temp+2*d+4*qp;
915 resid_temp[d+qp*2] = tensor_ig2_j(idx, wtr,
924 MFEM_FOREACH_THREAD(l,x,2)
926 resid[l] = tmp->x[l];
927 for (
int j = 0; j < D1D; ++j)
929 resid[l] -= resid_temp[l + j * 2];
932 MFEM_FOREACH_THREAD(l,x,4)
935 for (
int j = 0; j < D1D; ++j)
937 jac[l] += jac_temp[l + j * 4];
942 MFEM_FOREACH_THREAD(l,x,1)
944 if (!reject_prior_step_q(fpt, resid, tmp, tol))
946 newton_area(fpt, jac, resid, tmp, tol);
954 const int ei = edge_index(tmp->flags & FLAG_MASK);
955 const int dn = ei>>1, de = plus_1_mod_2(dn);
957 double *wt = r_workspace_ptr;
958 double *resid = wt + 3 * D1D;
959 double *jac = resid + 2;
960 double *hess = jac + 2 * 2;
961 findptsElementGEdge_t edge;
963 MFEM_FOREACH_THREAD(j,x,D1D)
965 edge = get_edge(elx, wtend, ei,
966 constraint_workspace,
973 MFEM_FOREACH_THREAD(j,x,D1D)
975 if (j == 0) { edge_init = 1u << ei; }
976 lag_eval_second_der(wt, tmp->r[de], j, gll1D,
981 MFEM_FOREACH_THREAD(d,x,
DIM)
983 resid[d] = tmp->x[d];
987 for (
int k = 0; k < D1D; ++k)
989 resid[d] -= wt[k]*edge.x[d][k];
990 jac[2*d] += wt[k]*edge.dxdn[d][k];
991 jac[2*d+1] += wt[k+D1D]*edge.x[d][k];
992 hess[d] += wt[k+2*D1D]*edge.x[d][k];
1000 MFEM_FOREACH_THREAD(j,x,1)
1004 double temp1 = jac[1],
1011 hess[2] = resid[0]*hess[0] + resid[1]*hess[1];
1015 MFEM_FOREACH_THREAD(l,x,1)
1018 if (!reject_prior_step_q(fpt, resid, tmp, tol))
1023 double steep = resid[0] * jac[ dn]
1024 + resid[1] * jac[2+dn];
1026 if (steep * tmp->r[dn] < 0)
1028 newton_area(fpt, jac, resid, tmp, tol);
1032 newton_edge(fpt, jac, hess[2], resid, de,
1033 dn, tmp->flags & FLAG_MASK,
1043 MFEM_FOREACH_THREAD(j,x,1)
1047 const int pi = point_index(tmp->flags & FLAG_MASK);
1048 const findptsElementGPT_t gpt =
1049 get_pt(elx, wtend, pi, D1D);
1051 const double *
const pt_x = gpt.x;
1052 const double *
const jac = gpt.jac;
1053 const double *
const hes = gpt.hes;
1056 for (
int d = 0; d <
DIM; ++d)
1058 resid[d] = fpt->x[d] - pt_x[d];
1060 steep[0] = jac[0]*resid[0] + jac[2]*resid[1];
1061 steep[1] = jac[1]*resid[0] + jac[3]*resid[1];
1063 sr[0] = steep[0]*tmp->r[0];
1064 sr[1] = steep[1]*tmp->r[1];
1066 if (!reject_prior_step_q(fpt, resid, tmp, tol))
1072 newton_area(fpt, jac, resid, tmp, tol);
1078 const double rh = resid[0]*hes[de]+
1080 newton_edge(fpt, jac, rh, resid, de, dn,
1091 const double rh = resid[0]*hes[de]+
1093 newton_edge(fpt, jac, rh, resid, de, dn,
1101 fpt->r[0] = tmp->r[0];
1102 fpt->r[1] = tmp->r[1];
1104 fpt->flags = tmp->flags | CONVERGED_FLAG;
1112 if (fpt->flags & CONVERGED_FLAG)
1117 MFEM_FOREACH_THREAD(j,x,1)
1125 bool converged_internal = (fpt->flags&FLAG_MASK)==CONVERGED_FLAG;
1126 if (*code_i == CODE_NOT_FOUND || converged_internal ||
1127 fpt->dist2 < *dist2_i)
1129 MFEM_FOREACH_THREAD(j,x,1)
1132 *code_i = converged_internal ? CODE_INTERNAL :
1134 *dist2_i = fpt->dist2;
1136 MFEM_FOREACH_THREAD(j,x,
DIM)
1141 if (converged_internal)
1152 int point_pos_ordering,
1161 auto pp = point_pos.
Read();
1163 auto pwt =
DEV.wtend.Read();
1164 auto pbb =
DEV.bb.Read();
1165 auto plhm =
DEV.loc_hash_min.Read();
1166 auto plhf =
DEV.loc_hash_fac.Read();
1167 auto plho =
DEV.loc_hash_offset.ReadWrite();
1168 auto pcode = code.
Write();
1169 auto pelem = elem.
Write();
1170 auto pref = ref.
Write();
1171 auto pdist = dist.
Write();
1172 auto pgll1d =
DEV.gll1d.ReadWrite();
1173 auto plc =
DEV.lagcoeff.Read();
1178 return FindPointsLocal2D_Kernel<2>(
1180 pbb,
DEV.h_nx, plhm, plhf, plho, pcode, pelem, pref, pdist,
1183 return FindPointsLocal2D_Kernel<3>(
1185 pbb,
DEV.h_nx, plhm, plhf, plho, pcode, pelem, pref, pdist,
1188 return FindPointsLocal2D_Kernel<4>(
1190 pbb,
DEV.h_nx, plhm, plhf, plho, pcode, pelem, pref, pdist,
1193 return FindPointsLocal2D_Kernel<5>(
1195 pbb,
DEV.h_nx, plhm, plhf, plho, pcode, pelem, pref, pdist,
1198 return FindPointsLocal2D_Kernel(npt,
DEV.newt_tol, pp, point_pos_ordering,
1200 plhm, plhf, plho, pcode, pelem,
1201 pref, pdist, pgll1d, plc,
DEV.dof1d);
1206#undef CODE_NOT_FOUND
1209 int point_pos_ordering,
1212 Vector &dist,
int npt) {};
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
struct mfem::FindPointsGSLIB::@24 DEV
void FindPointsLocal2(const Vector &point_pos, int point_pos_ordering, Array< unsigned int > &gsl_code_dev_l, Array< unsigned int > &gsl_elem_dev_l, Vector &gsl_ref_l, Vector &gsl_dist_l, int npt)
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
real_t u(const Vector &xvec)
void forall_2D(int N, int X, int Y, lambda &&body)
std::function< real_t(const Vector &)> f(real_t mass_coeff)
real_t p(const Vector &x, real_t t)