18#ifdef MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC
19#pragma GCC diagnostic push
20#pragma GCC diagnostic ignored "-Wunused-function"
23#define CODE_INTERNAL 0
25#define CODE_NOT_FOUND 2
31#ifndef GSLIB_RELEASE_VERSION
32#define GSLIB_RELEASE_VERSION 10007
38 struct dbl_range bnd[3];
46 struct dbl_range bnd[2];
51 struct findpts_dummy_ms_data
60 struct findpts_local_data_3 local;
61 struct hash_data_3 hash;
63 struct findpts_dummy_ms_data fdms;
70 struct findpts_local_data_2 local;
71 struct hash_data_2 hash;
73 struct findpts_dummy_ms_data fdms;
80#ifdef MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC
81#pragma GCC diagnostic pop
90 fdataD(nullptr), cr(nullptr), gsl_comm(nullptr),
91 dim(-1), points_cnt(-1), setupflag(false), default_interp_value(0),
92 avgtype(
AvgType::ARITHMETIC), bdr_tol(1e-8)
107 cr =
new gslib::crystal;
110 MPI_Initialized(&initialized);
111 if (!initialized) { MPI_Init(NULL, NULL); }
112 MPI_Comm comm = MPI_COMM_WORLD;
121 const double newt_tol,
const int npt_max)
152 fec_map_lin(nullptr),
153 fdataD(nullptr), cr(nullptr), gsl_comm(nullptr),
154 dim(-1), points_cnt(-1), setupflag(false), default_interp_value(0),
155 avgtype(
AvgType::ARITHMETIC), bdr_tol(1e-8)
170 cr =
new gslib::crystal;
176 const double newt_tol,
const int npt_max)
186 MFEM_VERIFY(m.
GetNodes() != NULL,
"Mesh nodes are required.");
188 "Mesh spatial dimension and reference element dimension must be the same");
189 const int meshOrder = m.
GetNodes()->FESpace()->GetMaxElementOrder();
196 const unsigned int dof1D = meshOrder+1;
205 DEV.dof1d = (int)dof1D;
208 unsigned nr[2] = { dof1D, dof1D };
209 unsigned mr[2] = { 2*dof1D, 2*dof1D };
210 double *
const elx[2] =
221 unsigned nr[3] = { dof1D, dof1D, dof1D };
222 unsigned mr[3] = { 2*dof1D, 2*dof1D, 2*dof1D };
223 double *
const elx[3] =
237 int point_pos_ordering)
239 MFEM_VERIFY(
setupflag,
"Use FindPointsGSLIB::Setup before finding points.");
248 bool tensor_product_only =
mesh->
GetNE() == 0 ||
253 MPI_Allreduce(MPI_IN_PLACE, &tensor_product_only, 1, MFEM_MPI_CXX_BOOL,
257 if (dev_mode && tensor_product_only)
259#if GSLIB_RELEASE_VERSION == 10007
262 MFEM_ABORT(
"Either update to gslib v1.0.9 for GPU support "
263 "or use SetGPUtoCPUFallback to use host-functions. See "
264 "INSTALL for instructions to update GSLIB.");
273 auto xvFill = [&](
const double *xv_base[],
unsigned xv_stride[])
275 for (
int d = 0; d <
dim; d++)
280 xv_stride[d] =
sizeof(double);
285 xv_stride[d] =
dim*
sizeof(double);
292 auto *findptsData = (gslib::findpts_data_2 *)this->
fdataD;
293 const double *xv_base[2];
294 unsigned xv_stride[2];
295 xvFill(xv_base, xv_stride);
305 auto *findptsData = (gslib::findpts_data_3 *)this->
fdataD;
306 const double *xv_base[3];
307 unsigned xv_stride[3];
308 xvFill(xv_base, xv_stride);
337#if GSLIB_RELEASE_VERSION >= 10009
338slong
lfloor(
double x) {
return floor(x); }
343 const slong i =
lfloor((x - low) * fac);
344 return i < 0 ? 0 : (n - 1 < (ulong)i ? n - 1 : (ulong)i);
350 const ulong n =
p->hash_n;
360 const ulong n =
p->hash_n;
367 auto *findptsData3 = (gslib::findpts_data_3 *)this->
fdataD;
368 auto *findptsData2 = (gslib::findpts_data_2 *)this->
fdataD;
370 DEV.newt_tol = dim == 2 ? findptsData2->local.tol : findptsData3->local.tol;
373 DEV.hash3 = &findptsData3->hash;
377 DEV.hash2 = &findptsData2->hash;
379 DEV.cr =
dim == 2 ? &findptsData2->cr : &findptsData3->cr;
385 auto p_bb =
DEV.bb.HostWrite();
392 auto box = findptsData3->local.obb[e];
393 for (
int d = 0; d <
dim; d++)
395 p_bb[n_box_ents*e + d] = box.c0[d];
396 p_bb[n_box_ents*e +
dim + d] = box.x[d].min;
397 p_bb[n_box_ents*e + 2*
dim + d] = box.x[d].max;
399 for (
int d = 0; d < dim2; ++d)
401 p_bb[n_box_ents*e + 3*
dim + d] = box.A[d];
409 auto box = findptsData2->local.obb[e];
410 for (
int d = 0; d <
dim; d++)
412 p_bb[n_box_ents*e + d] = box.c0[d];
413 p_bb[n_box_ents*e +
dim + d] = box.x[d].min;
414 p_bb[n_box_ents*e + 2*
dim + d] = box.x[d].max;
416 for (
int d = 0; d < dim2; ++d)
418 p_bb[n_box_ents*e + 3*
dim + d] = box.A[d];
423 DEV.loc_hash_min.UseDevice(
true);
DEV.loc_hash_min.SetSize(
dim);
424 DEV.loc_hash_fac.UseDevice(
true);
DEV.loc_hash_fac.SetSize(
dim);
427 auto hash = findptsData2->local.hd;
428 auto p_loc_hash_min =
DEV.loc_hash_min.HostWrite();
429 auto p_loc_hash_fac =
DEV.loc_hash_fac.HostWrite();
430 for (
int d = 0; d <
dim; d++)
432 p_loc_hash_min[d] = hash.bnd[d].min;
433 p_loc_hash_fac[d] = hash.fac[d];
435 DEV.h_nx = hash.hash_n;
439 auto hash = findptsData3->local.hd;
440 auto p_loc_hash_min =
DEV.loc_hash_min.HostWrite();
441 auto p_loc_hash_fac =
DEV.loc_hash_fac.HostWrite();
442 for (
int d = 0; d <
dim; d++)
444 p_loc_hash_min[d] = hash.bnd[d].min;
445 p_loc_hash_fac[d] = hash.fac[d];
447 DEV.h_nx = hash.hash_n;
451 findptsData2->local.hd.offset[(int)std::pow(
DEV.h_nx,
dim)] :
452 findptsData3->local.hd.offset[(int)std::pow(
DEV.h_nx,
dim)];
454 DEV.loc_hash_offset.SetSize(
DEV.h_o_size);
455 auto p_ou_offset =
DEV.loc_hash_offset.HostWrite();
456 for (
int i = 0; i <
DEV.h_o_size; i++)
458 p_ou_offset[i] =
dim == 2 ? findptsData2->local.hd.offset[i] :
459 findptsData3->local.hd.offset[i];
462 DEV.wtend.UseDevice(
true);
463 DEV.wtend.SetSize(6*
DEV.dof1d);
464 DEV.wtend.HostWrite();
465 DEV.wtend =
dim == 2 ? findptsData2->local.fed.wtend[0] :
466 findptsData3->local.fed.wtend[0];
469 DEV.gll1d.UseDevice(
true);
470 DEV.gll1d.SetSize(
DEV.dof1d);
471 DEV.gll1d.HostWrite();
472 DEV.gll1d =
dim == 2 ? findptsData2->local.fed.z[0] :
473 findptsData3->local.fed.z[0];
475 DEV.lagcoeff.UseDevice(
true);
476 DEV.lagcoeff.SetSize(
DEV.dof1d);
477 DEV.lagcoeff.HostWrite();
478 DEV.lagcoeff =
dim == 2 ? findptsData2->local.fed.lag_data[0] :
479 findptsData3->local.fed.lag_data[0];
481 DEV.setup_device =
true;
485 int point_pos_ordering)
487 if (!
DEV.setup_device)
491 DEV.find_device =
true;
526 double rbtol = 1e-12;
539 for (
int d = 0; d <
dim; d++)
568 struct gslib::array hash_pt, src_pt, out_pt;
573 unsigned int index, proc;
579 unsigned int index, code, el, proc;
586 array_init(
struct srcPt_t, &hash_pt,
points_cnt);
587 pt = (
struct srcPt_t *)hash_pt.ptr;
589 auto x =
new double[
dim];
594 for (
int d = 0; d <
dim; ++d)
596 int idx = point_pos_ordering == 0 ?
599 x[d] = point_pos(idx);
603 for (
int d = 0; d <
dim; ++d)
613 hash_pt.n = pt - (
struct srcPt_t *)hash_pt.ptr;
614 sarray_transfer(
struct srcPt_t, &hash_pt, proc, 1,
DEV.cr);
622 const unsigned int *
const hash_offset =
dim == 2 ?
DEV.hash2->offset :
625 unsigned int *proc, *proc_p;
626 const struct srcPt_t *
p = (
struct srcPt_t *)hash_pt.ptr,
627 *
const pe =
p + hash_pt.n;
634 const int i = hash_offset[hi], ie = hash_offset[hi + 1];
641 array_init(
struct srcPt_t, &src_pt, count);
642 q = (
struct srcPt_t *)src_pt.ptr;
644 p = (
struct srcPt_t *)hash_pt.ptr;
649 int i = hash_offset[hi];
650 const int ie = hash_offset[hi + 1];
653 const int pp = hash_offset[i];
664 array_free(&hash_pt);
665 src_pt.n = proc_p - proc;
667 sarray_transfer_ext(
struct srcPt_t, &src_pt, proc,
sizeof(uint),
DEV.cr);
676 const struct srcPt_t *spt;
678 array_init(
struct outPt_t, &out_pt, n);
680 spt = (
struct srcPt_t *)src_pt.ptr;
681 opt = (
struct outPt_t *)out_pt.ptr;
682 for (; n; --n, ++spt, ++opt)
684 opt->index = spt->index;
685 opt->proc = spt->proc;
687 spt = (
struct srcPt_t *)src_pt.ptr;
688 opt = (
struct outPt_t *)out_pt.ptr;
691 Vector gsl_ref_l, gsl_dist_l;
701 for (
int point = 0; point < n; ++point)
703 for (
int d = 0; d <
dim; d++)
705 int idx = point_pos_ordering == 0 ? point + d*n : point*
dim + d;
706 pointl[idx] = spt[point].x[d];
713 gsl_elem_l, gsl_ref_l, gsl_dist_l, n);
718 gsl_elem_l, gsl_ref_l, gsl_dist_l, n);
723 gsl_code_l.HostRead();
727 for (
int point = 0; point < n; point++)
729 opt[point].code =
AsConst(gsl_code_l)[point];
730 if (opt[point].code == CODE_NOT_FOUND)
734 opt[point].el =
AsConst(gsl_elem_l)[point];
735 opt[point].dist2 =
AsConst(gsl_dist_l)[point];
736 for (
int d = 0; d <
dim; ++d)
738 opt[point].r[d] =
AsConst(gsl_ref_l)[
dim * point + d];
744 ip.
Set2(0.5*opt[point].r[0]+0.5, 0.5*opt[point].r[1]+0.5);
748 ip.
Set3(0.5*opt[point].r[0]+0.5, 0.5*opt[point].r[1]+0.5,
749 0.5*opt[point].r[2]+0.5);
754 CODE_INTERNAL : CODE_BORDER;
755 opt[point].code = setcode==CODE_BORDER && opt[point].dist2>
bdr_tol ?
756 CODE_NOT_FOUND : setcode;
762 sarray_sort(
struct outPt_t, opt, out_pt.n, code, 0, &
DEV.cr->data);
765 while (n && opt[n - 1].code == CODE_NOT_FOUND)
771 sarray_transfer(
struct outPt_t, &out_pt, proc, 1,
DEV.cr);
782 struct outPt_t *opt = (
struct outPt_t *)out_pt.ptr;
783 for (; n; --n, ++opt)
785 const int index = opt->index;
790 if (
gsl_code[
index] == CODE_NOT_FOUND || opt->code == CODE_INTERNAL ||
793 for (
int d = 0; d <
dim; ++d)
816 for (
int d = 0; d <
dim; d++)
833 CODE_INTERNAL : CODE_BORDER;
835 CODE_NOT_FOUND : setcode;
842 unsigned int index, proc, el;
848 unsigned int index, proc;
862 DEV.dof1d_sol = dof1Dsol;
864 DEV.lagcoeff_sol.UseDevice(
true);
DEV.lagcoeff_sol.SetSize(dof1Dsol);
865 if (
DEV.dof1d_sol !=
DEV.dof1d || !
DEV.find_device)
867 gslib::lobatto_nodes(
DEV.gll1d_sol.HostWrite(), dof1Dsol);
868 gslib::gll_lag_setup(
DEV.lagcoeff_sol.HostWrite(), dof1Dsol);
872 DEV.gll1d_sol =
DEV.gll1d.HostRead();
873 DEV.lagcoeff_sol =
DEV.lagcoeff.HostRead();
878 struct gslib::array src, outpt;
910 array_init(evalSrcPt_t, &src, numSend);
911 pt = (evalSrcPt_t *)src.ptr;
916 if (*code != CODE_NOT_FOUND && *proc !=
gsl_comm->id)
918 for (
int d = 0; d <
dim; ++d)
927 else if (*code != CODE_NOT_FOUND && *proc ==
gsl_comm->id)
929 gsl_elem_temp[ctr] = *el;
930 for (
int d = 0; d <
dim; ++d)
932 gsl_ref_temp(
dim*ctr+d) = r[d];
934 index_temp[ctr] =
index;
944 src.n = pt - (evalSrcPt_t *)src.ptr;
945 sarray_transfer(evalSrcPt_t, &src, proc, 1,
cr);
950 Vector interp_vals(nlocal*ncomp);
979 int interp_Offset = interp_vals.
Size()/ncomp;
980 for (
int i = 0; i < ncomp; i++)
982 for (
int j = 0; j < nlocal; j++)
984 int pt_index = index_temp[j];
988 field_out(idx) =
AsConst(interp_vals)(j + interp_Offset*i);
1005 const evalSrcPt_t *spt;
1007 spt = (evalSrcPt_t *)src.ptr;
1016 spt = (evalSrcPt_t *)src.ptr;
1018 for (
int i = 0; i < n; i++, ++spt)
1020 gsl_elem_temp[i] = spt->el;
1021 for (
int d = 0; d <
dim; d++)
1023 gsl_ref_temp(i*
dim + d) = spt->r[d];
1027 Vector interp_vals(n*ncomp);
1034 interp_vals, n, ncomp,
1042 interp_vals, n, ncomp,
1051 int Offset = interp_vals.
Size()/ncomp;
1052 for (
int i = 0; i < ncomp; i++)
1054 spt = (evalSrcPt_t *)src.ptr;
1055 array_init(evalOutPt_t, &outpt, n);
1057 opt = (evalOutPt_t *)outpt.ptr;
1059 for (
int j = 0; j < n; j++)
1061 opt->index = spt->index;
1062 opt->proc = spt->proc;
1063 opt->out =
AsConst(interp_vals)(j + Offset*i);
1068 sarray_transfer(
struct evalOutPt_t, &outpt, proc, 1,
cr);
1070 opt = (evalOutPt_t *)outpt.ptr;
1075 opt->index*ncomp + i;
1076 field_out(idx) = opt->out;
1088 int point_pos_ordering) {};
1091 const int nel,
const int ncomp,
1093 const int ordering) {};
1097 int point_pos_ordering,
const double bb_t,
1098 const double newt_tol,
const int npt_max)
1109 int point_pos_ordering)
1117 int point_pos_ordering)
1119 FindPoints(m, point_pos, point_pos_ordering);
1132 findpts_free_2((gslib::findpts_data_2 *)this->
fdataD);
1136 findpts_free_3((gslib::findpts_data_3 *)this->
fdataD);
1145 for (
int i = 0; i < 4; i++)
1154 DEV.setup_device =
false;
1155 DEV.find_device =
false;
1168 const double quad_v[7][2] =
1170 {0, 0}, {0.5, 0}, {1, 0}, {0, 0.5},
1171 {1./3., 1./3.}, {0.5, 0.5}, {0, 1}
1173 const int quad_e[3][4] =
1175 {0, 1, 4, 3}, {1, 2, 5, 4}, {3, 4, 5, 6}
1178 for (
int j = 0; j < Nvert; j++)
1182 for (
int j = 0; j < NEsplit; j++)
1184 int attribute = j + 1;
1185 mesh_split[0]->AddQuad(quad_e[j], attribute);
1193 for (
int k = 0; k <
dim; k++)
1195 for (
int j = 0; j < npt; j++)
1214 const double hex_v[15][3] =
1216 {0, 0, 0.}, {1, 0., 0.}, {0., 1., 0.}, {0, 0., 1.},
1217 {0.5, 0., 0.}, {0.5, 0.5, 0.}, {0., 0.5, 0.},
1218 {0., 0., 0.5}, {0.5, 0., 0.5}, {0., 0.5, 0.5},
1219 {1./3., 0., 1./3.}, {1./3., 1./3., 1./3.}, {0, 1./3., 1./3.},
1220 {1./3., 1./3., 0}, {0.25, 0.25, 0.25}
1222 const int hex_e[4][8] =
1224 {7, 10, 4, 0, 12, 14, 13, 6},
1225 {10, 8, 1, 4, 14, 11, 5, 13},
1226 {14, 11, 5, 13, 12, 9, 2, 6},
1227 {7, 3, 8, 10, 12, 9, 11, 14}
1230 for (
int j = 0; j < Nvert; j++)
1234 for (
int j = 0; j < NEsplit; j++)
1236 int attribute = j + 1;
1245 for (
int k = 0; k <
dim; k++)
1247 for (
int j = 0; j < npt; j++)
1259 const double hex_v[14][3] =
1261 {0, 0, 0}, {0.5, 0, 0}, {1, 0, 0}, {0, 0.5, 0},
1262 {1./3., 1./3., 0}, {0.5, 0.5, 0}, {0, 1, 0},
1263 {0, 0, 1}, {0.5, 0, 1}, {1, 0, 1}, {0, 0.5, 1},
1264 {1./3., 1./3., 1}, {0.5, 0.5, 1}, {0, 1, 1}
1266 const int hex_e[3][8] =
1268 {0, 1, 4, 3, 7, 8, 11, 10},
1269 {1, 2, 5, 4, 8, 9, 12, 11},
1270 {3, 4, 5, 6, 10, 11, 12, 13}
1273 for (
int j = 0; j < Nvert; j++)
1277 for (
int j = 0; j < NEsplit; j++)
1279 int attribute = j + 1;
1288 for (
int k = 0; k <
dim; k++)
1290 for (
int j = 0; j < npt; j++)
1302 const double hex_v[23][3] =
1304 {0.0000, 0.0000, 0.0000}, {0.5000, 0.0000, 0.0000},
1305 {0.0000, 0.0000, 0.5000}, {0.3333, 0.0000, 0.3333},
1306 {0.0000, 0.5000, 0.0000}, {0.3333, 0.3333, 0.0000},
1307 {0.0000, 0.3333, 0.3333}, {0.2500, 0.2500, 0.2500},
1308 {1.0000, 0.0000, 0.0000}, {0.5000, 0.0000, 0.5000},
1309 {0.5000, 0.5000, 0.0000}, {0.3333, 0.3333, 0.3333},
1310 {0.0000, 1.0000, 0.0000}, {0.0000, 0.5000, 0.5000},
1311 {0.0000, 0.0000, 1.0000}, {1.0000, 0.5000, 0.0000},
1312 {0.6667, 0.3333, 0.3333}, {0.6667, 0.6667, 0.0000},
1313 {0.5000, 0.5000, 0.2500}, {1.0000, 1.0000, 0.0000},
1314 {0.5000, 0.5000, 0.5000}, {0.5000, 1.0000, 0.0000},
1315 {0.3333, 0.6667, 0.3333}
1317 const int hex_e[8][8] =
1319 {2, 3, 1, 0, 6, 7, 5, 4}, {3, 9, 8, 1, 7, 11, 10, 5},
1320 {7, 11, 10, 5, 6, 13, 12, 4}, {2, 14, 9, 3, 6, 13, 11, 7},
1321 {9, 16, 15, 8, 11, 18, 17, 10}, {16, 20, 19, 15, 18, 22, 21, 17},
1322 {18, 22, 21, 17, 11, 13, 12, 10}, {9, 14, 20, 16, 11, 13, 22, 18}
1325 for (
int j = 0; j < Nvert; j++)
1329 for (
int j = 0; j < NEsplit; j++)
1331 int attribute = j + 1;
1340 for (
int k = 0; k <
dim; k++)
1342 for (
int j = 0; j < npt; j++)
1358 const int NEsplit = meshin->
GetNE();
1361 pts_cnt = NEsplit * dof_cnt;
1366 MFEM_VERIFY(tbe != NULL,
"TensorBasis FiniteElement expected.");
1374 MFEM_ASSERT(irule->
GetNPoints() == pts_cnt,
"IntegrationRule does not have"
1375 "the correct number of points.");
1378 for (
int i = 0; i < NEsplit; i++)
1382 for (
int j = 0; j < dof_cnt; j++)
1384 for (
int d = 0; d <
dim; d++)
1386 irlist(pts_cnt * d + pt_id) = pos(dof_map[j], d);
1388 irule->
IntPoint(pt_id).
x = irlist(pt_id);
1389 irule->
IntPoint(pt_id).
y = irlist(pts_cnt + pt_id);
1392 irule->
IntPoint(pt_id).
z = irlist(2*pts_cnt + pt_id);
1401 MFEM_VERIFY(
mesh,
"Setup FindPointsGSLIB with mesh first.");
1402 const int dof1D = order+1;
1461 MFEM_ABORT(
"Unsupported geometry type.");
1464 for (
int i = 0; i < NEsplit; i++)
1478 const int vdim = fes->
GetVDim();
1483 const int dof_1D = maxOrder+1;
1484 const int pts_el = std::pow(dof_1D,
dim);
1486 node_vals.
SetSize(vdim * pts_cnt);
1493 int gsl_mesh_pt_index = 0;
1495 for (
int e = 0; e < NE; e++)
1499 bool el_to_split =
true;
1534 MFEM_ABORT(
"Unsupported geometry type.");
1541 for (
int i = 0; i < ir_split_temp->
GetNPoints(); i++)
1544 nodes->GetVectorValue(e, ip, locval);
1545 for (
int d = 0; d < vdim; d++)
1547 node_vals(pts_cnt*d + gsl_mesh_pt_index) = locval(d);
1549 gsl_mesh_pt_index++;
1554 const int dof_cnt_split = fe->
GetDof();
1558 MFEM_VERIFY(tbe != NULL,
"TensorBasis FiniteElement expected.");
1561 if (dm.
Size() > 0) { dof_map = dm; }
1562 else {
for (
int i = 0; i < dof_cnt_split; i++) { dof_map[i] = i; } }
1565 Vector posV(pos.
Data(), dof_cnt_split * vdim);
1569 nodes->GetSubVector(xdofs, posV);
1570 for (
int j = 0; j < dof_cnt_split; j++)
1572 for (
int d = 0; d < vdim; d++)
1574 node_vals(pts_cnt * d + gsl_mesh_pt_index) = pos(dof_map[j], d);
1576 gsl_mesh_pt_index++;
1597 double rbtol = 1e-12;
1611 struct gslib::array *outpt =
new gslib::array;
1612 struct out_pt {
double r[3]; uint
index, el, proc, code; };
1614 array_init(
struct out_pt, outpt, nptsend);
1616 pt = (
struct out_pt *)outpt->ptr;
1623 for (
int d = 0; d <
dim; ++d)
1635 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1639 pt = (
struct out_pt *)outpt->ptr;
1644 const int elem = pt->el;
1680 for (
int d = 0; d <
dim; d++)
1682 pt->r[d] = mfem_ref(d);
1692 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1696 pt = (
struct out_pt *)outpt->ptr;
1700 for (
int d = 0; d <
dim; d++)
1719 if (
dim == 3) { ip.
z = mfem_ref(2); }
1753 if (
dim == 3) { ip.
z = mfem_ref(2); }
1769 bool tensor_product_only =
mesh->
GetNE() == 0 ||
1774 MPI_Allreduce(MPI_IN_PLACE, &tensor_product_only, 1, MFEM_MPI_CXX_BOOL,
1781#if GSLIB_RELEASE_VERSION == 10007
1784 MFEM_ABORT(
"Either update to gslib v1.0.9 for GPU support "
1785 "or use SetGPUtoCPUFallback to use host-functions. See "
1786 "INSTALL for instructions to update GSLIB");
1790 "basis not supported");
1796 R->
Mult(field_in, node_vals);
1810 if (fec_h1 && gf_order == mesh_order &&
1833 int borderPts = indl2.
Size();
1835 MPI_Allreduce(MPI_IN_PLACE, &borderPts, 1, MPI_INT, MPI_SUM,
gsl_comm->c);
1837 if (borderPts == 0) {
return; }
1841 int gf_order_h1 = std::max(gf_order, 1);
1859 MFEM_ABORT(
"Invalid averaging type.");
1862 if (gf_order_h1 == mesh_order)
1872 for (
int j = 0; j < ncomp; j++)
1874 for (
int i = 0; i < indl2.
Size(); i++)
1879 field_out(idx) = field_out_l2(idx);
1891 for (
int e = 0; e < ind_fes.
GetMesh()->GetNE(); e++)
1902 points_fld = field_in.
Size() / ncomp;
1904 "FindPointsGSLIB::InterpolateH1: Inconsistent size of gsl_code");
1910 for (
int i = 0; i < ncomp; i++)
1912 const int dataptrin = i*points_fld,
1920 for (
int j = 0; j < points_fld; j++)
1922 field_in_scalar(j) = field_in(i + j*ncomp);
1929 findpts_eval_2(field_out.
GetData()+dataptrout,
sizeof(
double),
1935 (gslib::findpts_data_2 *)this->fdataD);
1939 findpts_eval_3(field_out.
GetData()+dataptrout,
sizeof(
double),
1945 (gslib::findpts_data_3 *)this->fdataD);
1950 Vector field_out_temp = field_out;
1951 for (
int i = 0; i < ncomp; i++)
1955 field_out(i + j*ncomp) = field_out_temp(j + i*
points_cnt);
1984 for (
int i = 0; i < ncomp; i++)
1986 field_out(
index + i*npt) = localval(i);
1991 for (
int i = 0; i < ncomp; i++)
1993 field_out(
index*ncomp + i) = localval(i);
2008 struct gslib::array *outpt =
new gslib::array;
2009 struct out_pt {
double r[3], ival; uint
index, el, proc; };
2011 array_init(
struct out_pt, outpt, nptsend);
2013 pt = (
struct out_pt *)outpt->ptr;
2025 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
2031 pt = (
struct out_pt *)outpt->ptr;
2036 pt->ival = field_in.
GetValue(pt->el, ip, 1);
2041 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
2043 pt = (
struct out_pt *)outpt->ptr;
2046 field_out(pt->index) = pt->ival;
2056 pt = (
struct out_pt *)outpt->ptr;
2057 Vector vec_int_vals(npt*ncomp);
2068 struct gslib::array *savpt =
new gslib::array;
2069 struct sav_pt { uint
index, proc; };
2071 array_init(
struct sav_pt, savpt, npt);
2073 spt = (
struct sav_pt *)savpt->ptr;
2074 pt = (
struct out_pt *)outpt->ptr;
2077 spt->index = pt->index;
2078 spt->proc = pt->proc;
2086 struct gslib::array *sendpt =
new gslib::array;
2087 struct send_pt {
double ival; uint
index, proc; };
2088 struct send_pt *sdpt;
2089 for (
int j = 0; j < ncomp; j++)
2091 array_init(
struct send_pt, sendpt, npt);
2093 spt = (
struct sav_pt *)savpt->ptr;
2094 sdpt = (
struct send_pt *)sendpt->ptr;
2097 sdpt->index = spt->index;
2098 sdpt->proc = spt->proc;
2099 sdpt->ival = vec_int_vals(j +
index*ncomp);
2103 sarray_transfer(
struct send_pt, sendpt, proc, 1,
cr);
2104 sdpt = (
struct send_pt *)sendpt->ptr;
2108 sdpt->index + j*nptorig :
2109 sdpt->index*ncomp + j;
2110 field_out(idx) = sdpt->ival;
2140 "Invalid size. Please make sure to call FindPoints method "
2141 "before calling this function.");
2144 struct gslib::array *outpt =
new gslib::array;
2146 struct out_pt {
double rst[3]; uint
index, elem, proc, code; };
2148 array_init(
struct out_pt, outpt,
points_cnt);
2150 pt = (
struct out_pt *)outpt->ptr;
2158 for (
int d = 0; d <
dim; ++d)
2166 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
2169 const int points_recv = outpt->n;
2171 recv_elem.
SetSize(points_recv);
2173 recv_code.
SetSize(points_recv);
2176 pt = (
struct out_pt *)outpt->ptr;
2180 recv_elem[
index] = pt->elem;
2182 recv_code[
index] = pt->code;
2183 for (
int d = 0; d <
dim; ++d)
2185 recv_ref(
index*
dim + d)= pt->rst[d];
2200 MFEM_VERIFY(points_recv == 0 ||
2201 int_vals.
Size() % points_recv == 0,
2202 "Incompatible size. Please return interpolated values"
2203 "corresponding to points received using"
2204 "SendCoordinatesToOwningProcessors.");
2207 for (
int v = 0; v < vdim; v++)
2210 struct gslib::array *outpt =
new gslib::array;
2211 struct out_pt {
double val; uint
index, proc; };
2213 array_init(
struct out_pt, outpt, points_recv);
2214 outpt->n=points_recv;
2215 pt = (
struct out_pt *)outpt->ptr;
2221 int_vals(
index + v*points_recv) :
2222 int_vals(
index*vdim + v);
2227 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
2230 MFEM_VERIFY(outpt->n ==
points_cnt,
"Incompatible size. Number of points "
2231 "received does not match the number of points originally "
2232 "found using FindPoints.");
2234 pt = (
struct out_pt *)outpt->ptr;
2240 field_out(idx) = pt->val;
2251 MFEM_VERIFY(
setupflag,
"Call FindPointsGSLIB::Setup method first");
2252 auto *findptsData3 = (gslib::findpts_data_3 *)this->
fdataD;
2253 auto *findptsData2 = (gslib::findpts_data_2 *)this->
fdataD;
2254 int nve =
dim == 2 ? 4 : 8;
2260 for (
int e = 0; e < nel; e++)
2262 auto box = findptsData3->local.obb[e];
2264 for (
int d = 0; d <
dim; d++)
2266 minn[d] = box.x[d].min;
2267 maxx[d] = box.x[d].max;
2270 aabb(e*nve*
dim + c++) = minn[0];
2271 aabb(e*nve*
dim + c++) = minn[1];
2272 aabb(e*nve*
dim + c++) = minn[2];
2273 aabb(e*nve*
dim + c++) = maxx[0];
2274 aabb(e*nve*
dim + c++) = minn[1];
2275 aabb(e*nve*
dim + c++) = minn[2];
2276 aabb(e*nve*
dim + c++) = maxx[0];
2277 aabb(e*nve*
dim + c++) = maxx[1];
2278 aabb(e*nve*
dim + c++) = minn[2];
2279 aabb(e*nve*
dim + c++) = minn[0];
2280 aabb(e*nve*
dim + c++) = maxx[1];
2281 aabb(e*nve*
dim + c++) = minn[2];
2282 aabb(e*nve*
dim + c++) = minn[0];
2283 aabb(e*nve*
dim + c++) = minn[1];
2284 aabb(e*nve*
dim + c++) = maxx[2];
2285 aabb(e*nve*
dim + c++) = maxx[0];
2286 aabb(e*nve*
dim + c++) = minn[1];
2287 aabb(e*nve*
dim + c++) = maxx[2];
2288 aabb(e*nve*
dim + c++) = maxx[0];
2289 aabb(e*nve*
dim + c++) = maxx[1];
2290 aabb(e*nve*
dim + c++) = maxx[2];
2291 aabb(e*nve*
dim + c++) = minn[0];
2292 aabb(e*nve*
dim + c++) = maxx[1];
2293 aabb(e*nve*
dim + c++) = maxx[2];
2298 for (
int e = 0; e < nel; e++)
2300 auto box = findptsData2->local.obb[e];
2302 for (
int d = 0; d <
dim; d++)
2304 minn[d] = box.x[d].min;
2305 maxx[d] = box.x[d].max;
2307 aabb(e*nve*
dim + 0) = minn[0];
2308 aabb(e*nve*
dim + 1) = minn[1];
2309 aabb(e*nve*
dim + 2) = maxx[0];
2310 aabb(e*nve*
dim + 3) = minn[1];
2311 aabb(e*nve*
dim + 4) = maxx[0];
2312 aabb(e*nve*
dim + 5) = maxx[1];
2313 aabb(e*nve*
dim + 6) = minn[0];
2314 aabb(e*nve*
dim + 7) = maxx[1];
2322 MFEM_VERIFY(
setupflag,
"Call FindPointsGSLIB::Setup method first");
2323 auto *findptsData3 = (gslib::findpts_data_3 *)this->
fdataD;
2324 auto *findptsData2 = (gslib::findpts_data_2 *)this->
fdataD;
2325 int nve =
dim == 2 ? 4 : 8;
2333 for (
int e = 0; e < nel; e++)
2335 auto box = findptsData3->local.obb[e];
2337 for (
int d = 0; d <
dim; d++)
2339 obbC(e*
dim + d) = box.c0[d];
2341 for (
int i = 0; i <
dim; i++)
2343 for (
int j = 0; j <
dim; j++)
2345 Ad[i*
dim + j] = box.A[i + j*
dim];
2355 v1(0) = -1.0; v1(1) = -1.0; v1(2) = -1.0;
2357 Amat.
Mult(v1, temp);
2359 v1(0) = 1.0; v1(1) = -1.0; v1(2) = -1.0;
2361 Amat.
Mult(v1, temp);
2363 v1(0) = 1.0; v1(1) = 1.0; v1(2) = -1.0;
2365 Amat.
Mult(v1, temp);
2367 v1(0) = -1.0; v1(1) = 1.0; v1(2) = -1.0;
2369 Amat.
Mult(v1, temp);
2371 v1(0) = -1.0; v1(1) = -1.0; v1(2) = 1.0;
2373 Amat.
Mult(v1, temp);
2375 v1(0) = 1.0; v1(1) = -1.0; v1(2) = 1.0;
2377 Amat.
Mult(v1, temp);
2379 v1(0) = 1.0; v1(1) = 1.0; v1(2) = 1.0;
2381 Amat.
Mult(v1, temp);
2383 v1(0) = -1.0; v1(1) = 1.0; v1(2) = 1.0;
2385 Amat.
Mult(v1, temp);
2391 for (
int e = 0; e < nel; e++)
2393 auto box = findptsData2->local.obb[e];
2395 for (
int d = 0; d <
dim; d++)
2397 obbC(e*
dim + d) = box.c0[d];
2399 for (
int i = 0; i <
dim; i++)
2401 for (
int j = 0; j <
dim; j++)
2403 Ad[i*
dim + j] = box.A[i + j*
dim];
2413 v1(0) = -1.0; v1(1) = -1.0;
2415 Amat.
Mult(v1, temp);
2417 v1(0) = 1.0; v1(1) = -1.0;
2419 Amat.
Mult(v1, temp);
2421 v1(0) = 1.0; v1(1) = 1.0;
2423 Amat.
Mult(v1, temp);
2425 v1(0) = -1.0; v1(1) = 1.0;
2427 Amat.
Mult(v1, temp);
2435 const double bb_t,
const double newt_tol,
2438 MFEM_VERIFY(m.
GetNodes() != NULL,
"Mesh nodes are required.");
2439 const int meshOrder = m.
GetNodes()->FESpace()->GetMaxElementOrder();
2442 MFEM_VERIFY(meshOrder == gfOrder,
2443 "Mesh order must match gfmax order in OversetFindPointsGSLIB.");
2451 unsigned dof1D = fe->
GetOrder() + 1;
2457 MFEM_ASSERT(meshid>=0,
" The ID should be greater than or equal to 0.");
2460 NEtot = pts_cnt/(int)pow(dof1D,
dim);
2475 unsigned nr[2] = { dof1D, dof1D };
2476 unsigned mr[2] = { 2*dof1D, 2*dof1D };
2477 double *
const elx[2] =
2479 pts_cnt == 0 ? nullptr : &
gsl_mesh(0),
2480 pts_cnt == 0 ? nullptr : &
gsl_mesh(pts_cnt)
2483 pts_cnt, pts_cnt, npt_max,
newt_tol,
2488 unsigned nr[3] = { dof1D, dof1D, dof1D };
2489 unsigned mr[3] = { 2*dof1D, 2*dof1D, 2*dof1D };
2490 double *
const elx[3] =
2492 pts_cnt == 0 ? nullptr : &
gsl_mesh(0),
2493 pts_cnt == 0 ? nullptr : &
gsl_mesh(pts_cnt),
2494 pts_cnt == 0 ? nullptr : &
gsl_mesh(2*pts_cnt)
2497 pts_cnt, pts_cnt, npt_max,
newt_tol,
2506 int point_pos_ordering)
2508 MFEM_VERIFY(
setupflag,
"Use OversetFindPointsGSLIB::Setup before "
2510 MFEM_VERIFY(
overset,
"Please use OversetFindPoints for overlapping grids.");
2512 unsigned int match = 0;
2520 auto xvFill = [&](
const double *xv_base[],
unsigned xv_stride[])
2522 for (
int d = 0; d <
dim; d++)
2527 xv_stride[d] =
sizeof(double);
2531 xv_base[d] = point_pos.
GetData() + d;
2532 xv_stride[d] =
dim*
sizeof(double);
2538 auto *findptsData = (gslib::findpts_data_2 *)this->
fdataD;
2539 const double *xv_base[2];
2540 unsigned xv_stride[2];
2541 xvFill(xv_base, xv_stride);
2548 point_id.
GetData(),
sizeof(
unsigned int), &match,
2553 auto *findptsData = (gslib::findpts_data_3 *)this->
fdataD;
2554 const double *xv_base[3];
2555 unsigned xv_stride[3];
2556 xvFill(xv_base, xv_stride);
2563 point_id.
GetData(),
sizeof(
unsigned int), &match,
2588 int point_pos_ordering)
2590 FindPoints(point_pos, point_id, point_pos_ordering);
2597 cr =
new gslib::crystal;
2600 MPI_Initialized(&initialized);
2601 if (!initialized) { MPI_Init(NULL, NULL); }
2602 MPI_Comm comm = MPI_COMM_WORLD;
2613 : cr(NULL), gsl_comm(NULL)
2616 cr =
new gslib::crystal;
2634 long long minval = ids.
Min();
2636 MPI_Allreduce(MPI_IN_PLACE, &minval, 1, MPI_LONG_LONG_INT,
2639 MFEM_VERIFY(minval >= 0,
"Unique identifier cannot be negative.");
2645 gslib::gs_crystal_router, 0);
2651 "Incompatible setup and GOP operation.");
2654 gslib_gs(senddata.
GetData(),gslib::gs_double,gslib::gs_add,0,
gsl_data,0);
2658 gslib_gs(senddata.
GetData(),gslib::gs_double,gslib::gs_mul,0,
gsl_data,0);
2662 gslib_gs(senddata.
GetData(),gslib::gs_double,gslib::gs_max,0,
gsl_data,0);
2666 gslib_gs(senddata.
GetData(),gslib::gs_double,gslib::gs_min,0,
gsl_data,0);
2670 MFEM_ABORT(
"Invalid GSOp operation.");
2677#undef CODE_NOT_FOUND
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
int Size() const
Return the logical size of the array.
void DeleteAll()
Delete the whole array.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
T * GetData()
Returns the data.
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
@ GaussLobatto
Closed type.
Data type dense matrix using column-major storage.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
real_t * Data() const
Returns the matrix data array. Warning: this method casts away constness.
void Invert()
Replaces the current matrix with its inverse.
Rank 3 tensor (array of matrices)
void SetSize(int i, int j, int k, MemoryType mt_=MemoryType::PRESERVE)
static MemoryType GetMemoryType()
(DEPRECATED) Equivalent to GetDeviceMemoryType().
static bool IsEnabled()
Return true if any backend other than Backend::CPU is enabled.
Geometry::Type GetGeometryType() const
FindPointsGSLIB can robustly evaluate a GridFunction on an arbitrary collection of points....
virtual void DistributePointInfoToOwningMPIRanks(Array< unsigned int > &recv_elem, Vector &recv_ref, Array< unsigned int > &recv_code)
struct mfem::FindPointsGSLIB::@24 DEV
virtual ~FindPointsGSLIB()
void FindPointsOnDevice(const Vector &point_pos, int point_pos_ordering=Ordering::byNODES)
Array< unsigned int > gsl_code
Array< Mesh * > mesh_split
void InterpolateLocal2(const Vector &field_in, Array< int > &gsl_elem_dev_l, Vector &gsl_ref_l, Vector &field_out, int npt, int ncomp, int nel, int dof1dsol)
void FindPoints(const Vector &point_pos, int point_pos_ordering=Ordering::byNODES)
void GetAxisAlignedBoundingBoxes(Vector &aabb)
void FindPointsLocal3(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)
void Setup(Mesh &m, const double bb_t=0.1, const double newt_tol=1.0e-12, const int npt_max=256)
virtual void Interpolate(const GridFunction &field_in, Vector &field_out)
virtual void InterpolateH1(const GridFunction &field_in, Vector &field_out)
Use GSLIB for communication and interpolation.
Array< FiniteElementSpace * > fes_rst_map
virtual void GetNodalValues(const GridFunction *gf_in, Vector &node_vals)
Get GridFunction value at the points expected by GSLIB.
Array< int > split_element_index
FiniteElementCollection * fec_map_lin
virtual void DistributeInterpolatedValues(const Vector &int_vals, const int vdim, const int ordering, Vector &field_out) const
struct gslib::comm * gsl_comm
void InterpolateLocal3(const Vector &field_in, Array< int > &gsl_elem_dev_l, Vector &gsl_ref_l, Vector &field_out, int npt, int ncomp, int nel, int dof1dsol)
Array< unsigned int > gsl_elem
Array< unsigned int > recv_proc
virtual void SetupSplitMeshesAndIntegrationRules(const int order)
Array< unsigned int > gsl_proc
virtual void SetupIntegrationRuleForSplitMesh(Mesh *mesh, IntegrationRule *irule, int order)
Array< unsigned int > gsl_mfem_elem
Array< IntegrationRule * > ir_split
double default_interp_value
virtual void SetupSplitMeshes()
virtual void MapRefPosAndElemIndices()
Array< unsigned int > GetPointsNotFoundIndices() const
Get array of indices of not-found points.
virtual void InterpolateGeneral(const GridFunction &field_in, Vector &field_out)
Array< GridFunction * > gf_rst_map
Array< int > split_element_map
void GetOrientedBoundingBoxes(DenseTensor &obbA, Vector &obbC, Vector &obbV)
void InterpolateOnDevice(const Vector &field_in_evec, Vector &field_out, const int nel, const int ncomp, const int dof1dsol, const int ordering)
Array< unsigned int > recv_index
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)
struct gslib::crystal * cr
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Ordering::Type GetOrdering() const
Return the ordering method.
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
virtual void Update(bool want_transform=true)
Reflect changes in the mesh: update number of DOFs, etc. Also, calculate GridFunction transformation ...
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
void SetElementOrder(int i, int p)
Sets the order of the i'th finite element.
const FiniteElementCollection * FEColl() const
Mesh * GetMesh() const
Returns the mesh.
int GetVDim() const
Returns the vector dimension of the finite element space.
const FiniteElement * GetTypicalFE() const
Return GetFE(0) if the local mesh is not empty; otherwise return a typical FE based on the Geometry t...
virtual int GetMaxElementOrder() const
Return the maximum polynomial order over all elements.
Abstract class for all finite elements.
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
int GetDof() const
Returns the number of degrees of freedom in the finite element.
struct gslib::comm * gsl_comm
void GS(Vector &senddata, GSOp op)
GSOPGSLIB(Array< long long > &ids)
GSOp
Supported operation types. See class description.
struct gslib::crystal * cr
struct gslib::gs_data * gsl_data
void UpdateIdentifiers(const Array< long long > &ids)
static bool CheckPoint(int GeomType, const IntegrationPoint &ip)
Check if the given point is inside the given reference element.
Class for grid function - Vector with associated FE space.
virtual real_t GetValue(int i, const IntegrationPoint &ip, int vdim=1) const
FiniteElementSpace * FESpace()
void ProjectDiscCoefficient(VectorCoefficient &coeff, Array< int > &dof_attr)
int VectorDim() const
Shortcut for calling FiniteElementSpace::GetVectorDim() on the underlying fes.
virtual void GetVectorValue(int i, const IntegrationPoint &ip, Vector &val) const
Arbitrary order H1-conforming (continuous) finite elements.
Class for integration point with weight.
void Set2(const real_t x1, const real_t x2)
void Set3(const real_t x1, const real_t x2, const real_t x3)
Class for an integration rule - an Array of IntegrationPoint.
int GetNPoints() const
Returns the number of the points in the integration rule.
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Arbitrary order "L2-conforming" discontinuous finite elements.
Element::Type GetElementType(int i) const
Returns the type of element i.
const FiniteElementSpace * GetNodalFESpace() const
const Element * GetElement(int i) const
Return pointer to the i'th element object.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
int SpaceDimension() const
Dimension of the physical space containing the mesh.
static Mesh MakeCartesian3D(int nx, int ny, int nz, Element::Type type, real_t sx=1.0, real_t sy=1.0, real_t sz=1.0, bool sfc_ordering=true)
Creates a mesh for the parallelepiped [0,sx]x[0,sy]x[0,sz], divided into nx*ny*nz hexahedra if type =...
void GetNodes(Vector &node_coord) const
virtual void SetNodalFESpace(FiniteElementSpace *nfes)
static Mesh MakeCartesian2D(int nx, int ny, Element::Type type, bool generate_edges=false, real_t sx=1.0, real_t sy=1.0, bool sfc_ordering=true)
Creates mesh for the rectangle [0,sx]x[0,sy], divided into nx*ny quadrilaterals if type = QUADRILATER...
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
static bool IsFinalized()
Return true if MPI has been finalized.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
void Setup(Mesh &m, const int meshid, GridFunction *gfmax=NULL, const double bb_t=0.1, const double newt_tol=1.0e-12, const int npt_max=256)
void Interpolate(const Vector &point_pos, Array< unsigned int > &point_id, const GridFunction &field_in, Vector &field_out, int point_pos_ordering=Ordering::byNODES)
void FindPoints(const Vector &point_pos, Array< unsigned int > &point_id, int point_pos_ordering=Ordering::byNODES)
Class for parallel meshes.
const Array< int > & GetDofMap() const
Get an Array<int> that maps lexicographically ordered indices to the indices of the respective nodes/...
Vector coefficient defined by a vector GridFunction.
virtual const real_t * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
void SetDataAndSize(real_t *d, int s)
Set the Vector data and size.
void Destroy()
Destroy a vector.
int Size() const
Returns the size of the vector.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
void SetSize(int s)
Resize the vector to size s.
virtual real_t * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
void NewDataAndSize(real_t *d, int s)
Set the Vector data and size, deleting the old data, if owned.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
virtual real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
int index(int i, int j, int nx, int ny)
ulong hash_index_2(const gslib::hash_data_2 *p, const double x[2])
ulong hash_index_3(const gslib::hash_data_3 *p, const double x[3])
const T & AsConst(const T &a)
Utility function similar to std::as_const in c++17.
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
ulong hash_index_aux(double low, double fac, ulong n, double x)
real_t p(const Vector &x, real_t t)
std::array< int, NCMesh::MaxFaceNodes > nodes