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(NULL), cr(NULL), gsl_comm(NULL),
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;
126 for (
int i = 0; i < 4; i++)
140 fdataD(NULL), cr(NULL), gsl_comm(NULL),
141 dim(-1), points_cnt(-1), setupflag(false), default_interp_value(0),
142 avgtype(
AvgType::ARITHMETIC), bdr_tol(1e-8)
157 cr =
new gslib::crystal;
166 MFEM_VERIFY(m.
GetNodes() != NULL,
"Mesh nodes are required.");
167 const int meshOrder = m.
GetNodes()->FESpace()->GetMaxElementOrder();
174 unsigned dof1D = meshOrder + 1;
211 DEV.dof1d = (int)dof1D;
214 unsigned nr[2] = { dof1D, dof1D };
215 unsigned mr[2] = { 2*dof1D, 2*dof1D };
216 double *
const elx[2] =
227 unsigned nr[3] = { dof1D, dof1D, dof1D };
228 unsigned mr[3] = { 2*dof1D, 2*dof1D, 2*dof1D };
229 double *
const elx[3] =
243 int point_pos_ordering)
245 MFEM_VERIFY(
setupflag,
"Use FindPointsGSLIB::Setup before finding points.");
254 bool tensor_product_only =
mesh->
GetNE() == 0 ||
259 MPI_Allreduce(MPI_IN_PLACE, &tensor_product_only, 1, MFEM_MPI_CXX_BOOL,
263 if (dev_mode && tensor_product_only)
265#if GSLIB_RELEASE_VERSION == 10007
268 MFEM_ABORT(
"Either update to gslib v1.0.9 for GPU support "
269 "or use SetGPUtoCPUFallback to use host-functions. See "
270 "INSTALL for instructions to update GSLIB.");
279 auto xvFill = [&](
const double *xv_base[],
unsigned xv_stride[])
281 for (
int d = 0; d <
dim; d++)
286 xv_stride[d] =
sizeof(double);
291 xv_stride[d] =
dim*
sizeof(double);
298 auto *findptsData = (gslib::findpts_data_2 *)this->
fdataD;
299 const double *xv_base[2];
300 unsigned xv_stride[2];
301 xvFill(xv_base, xv_stride);
311 auto *findptsData = (gslib::findpts_data_3 *)this->
fdataD;
312 const double *xv_base[3];
313 unsigned xv_stride[3];
314 xvFill(xv_base, xv_stride);
342#if GSLIB_RELEASE_VERSION >= 10009
343slong
lfloor(
double x) {
return floor(x); }
348 const slong i =
lfloor((x - low) * fac);
349 return i < 0 ? 0 : (n - 1 < (ulong)i ? n - 1 : (ulong)i);
355 const ulong n =
p->hash_n;
365 const ulong n =
p->hash_n;
372 auto *findptsData3 = (gslib::findpts_data_3 *)this->
fdataD;
373 auto *findptsData2 = (gslib::findpts_data_2 *)this->
fdataD;
375 DEV.newt_tol = dim == 2 ? findptsData2->local.tol : findptsData3->local.tol;
378 DEV.hash3 = &findptsData3->hash;
382 DEV.hash2 = &findptsData2->hash;
384 DEV.cr =
dim == 2 ? &findptsData2->cr : &findptsData3->cr;
390 auto p_bb =
DEV.bb.HostWrite();
397 auto box = findptsData3->local.obb[e];
398 for (
int d = 0; d <
dim; d++)
400 p_bb[n_box_ents*e + d] = box.c0[d];
401 p_bb[n_box_ents*e +
dim + d] = box.x[d].min;
402 p_bb[n_box_ents*e + 2*
dim + d] = box.x[d].max;
404 for (
int d = 0; d < dim2; ++d)
406 p_bb[n_box_ents*e + 3*
dim + d] = box.A[d];
414 auto box = findptsData2->local.obb[e];
415 for (
int d = 0; d <
dim; d++)
417 p_bb[n_box_ents*e + d] = box.c0[d];
418 p_bb[n_box_ents*e +
dim + d] = box.x[d].min;
419 p_bb[n_box_ents*e + 2*
dim + d] = box.x[d].max;
421 for (
int d = 0; d < dim2; ++d)
423 p_bb[n_box_ents*e + 3*
dim + d] = box.A[d];
428 DEV.loc_hash_min.UseDevice(
true);
DEV.loc_hash_min.SetSize(
dim);
429 DEV.loc_hash_fac.UseDevice(
true);
DEV.loc_hash_fac.SetSize(
dim);
432 auto hash = findptsData2->local.hd;
433 auto p_loc_hash_min =
DEV.loc_hash_min.HostWrite();
434 auto p_loc_hash_fac =
DEV.loc_hash_fac.HostWrite();
435 for (
int d = 0; d <
dim; d++)
437 p_loc_hash_min[d] = hash.bnd[d].min;
438 p_loc_hash_fac[d] = hash.fac[d];
440 DEV.h_nx = hash.hash_n;
444 auto hash = findptsData3->local.hd;
445 auto p_loc_hash_min =
DEV.loc_hash_min.HostWrite();
446 auto p_loc_hash_fac =
DEV.loc_hash_fac.HostWrite();
447 for (
int d = 0; d <
dim; d++)
449 p_loc_hash_min[d] = hash.bnd[d].min;
450 p_loc_hash_fac[d] = hash.fac[d];
452 DEV.h_nx = hash.hash_n;
456 findptsData2->local.hd.offset[(int)std::pow(
DEV.h_nx,
dim)] :
457 findptsData3->local.hd.offset[(int)std::pow(
DEV.h_nx,
dim)];
459 DEV.loc_hash_offset.SetSize(
DEV.h_o_size);
460 auto p_ou_offset =
DEV.loc_hash_offset.HostWrite();
461 for (
int i = 0; i <
DEV.h_o_size; i++)
463 p_ou_offset[i] =
dim == 2 ? findptsData2->local.hd.offset[i] :
464 findptsData3->local.hd.offset[i];
467 DEV.wtend.UseDevice(
true);
468 DEV.wtend.SetSize(6*
DEV.dof1d);
469 DEV.wtend.HostWrite();
470 DEV.wtend =
dim == 2 ? findptsData2->local.fed.wtend[0] :
471 findptsData3->local.fed.wtend[0];
474 DEV.gll1d.UseDevice(
true);
475 DEV.gll1d.SetSize(
DEV.dof1d);
476 DEV.gll1d.HostWrite();
477 DEV.gll1d =
dim == 2 ? findptsData2->local.fed.z[0] :
478 findptsData3->local.fed.z[0];
480 DEV.lagcoeff.UseDevice(
true);
481 DEV.lagcoeff.SetSize(
DEV.dof1d);
482 DEV.lagcoeff.HostWrite();
483 DEV.lagcoeff =
dim == 2 ? findptsData2->local.fed.lag_data[0] :
484 findptsData3->local.fed.lag_data[0];
486 DEV.setup_device =
true;
490 int point_pos_ordering)
492 if (!
DEV.setup_device)
496 DEV.find_device =
true;
531 double rbtol = 1e-12;
544 for (
int d = 0; d <
dim; d++)
573 struct gslib::array hash_pt, src_pt, out_pt;
578 unsigned int index, proc;
584 unsigned int index, code, el, proc;
591 array_init(
struct srcPt_t, &hash_pt,
points_cnt);
592 pt = (
struct srcPt_t *)hash_pt.ptr;
594 auto x =
new double[
dim];
599 for (
int d = 0; d <
dim; ++d)
601 int idx = point_pos_ordering == 0 ?
604 x[d] = point_pos(idx);
608 for (
int d = 0; d <
dim; ++d)
618 hash_pt.n = pt - (
struct srcPt_t *)hash_pt.ptr;
619 sarray_transfer(
struct srcPt_t, &hash_pt, proc, 1,
DEV.cr);
627 const unsigned int *
const hash_offset =
dim == 2 ?
DEV.hash2->offset :
630 unsigned int *proc, *proc_p;
631 const struct srcPt_t *
p = (
struct srcPt_t *)hash_pt.ptr,
632 *
const pe =
p + hash_pt.n;
639 const int i = hash_offset[hi], ie = hash_offset[hi + 1];
646 array_init(
struct srcPt_t, &src_pt, count);
647 q = (
struct srcPt_t *)src_pt.ptr;
649 p = (
struct srcPt_t *)hash_pt.ptr;
654 int i = hash_offset[hi];
655 const int ie = hash_offset[hi + 1];
658 const int pp = hash_offset[i];
669 array_free(&hash_pt);
670 src_pt.n = proc_p - proc;
672 sarray_transfer_ext(
struct srcPt_t, &src_pt, proc,
sizeof(uint),
DEV.cr);
681 const struct srcPt_t *spt;
683 array_init(
struct outPt_t, &out_pt, n);
685 spt = (
struct srcPt_t *)src_pt.ptr;
686 opt = (
struct outPt_t *)out_pt.ptr;
687 for (; n; --n, ++spt, ++opt)
689 opt->index = spt->index;
690 opt->proc = spt->proc;
692 spt = (
struct srcPt_t *)src_pt.ptr;
693 opt = (
struct outPt_t *)out_pt.ptr;
696 Vector gsl_ref_l, gsl_dist_l;
706 for (
int point = 0; point < n; ++point)
708 for (
int d = 0; d <
dim; d++)
710 int idx = point_pos_ordering == 0 ? point + d*n : point*
dim + d;
711 pointl[idx] = spt[point].x[d];
718 gsl_elem_l, gsl_ref_l, gsl_dist_l, n);
723 gsl_elem_l, gsl_ref_l, gsl_dist_l, n);
728 gsl_code_l.HostRead();
732 for (
int point = 0; point < n; point++)
734 opt[point].code =
AsConst(gsl_code_l)[point];
735 if (opt[point].code == CODE_NOT_FOUND)
739 opt[point].el =
AsConst(gsl_elem_l)[point];
740 opt[point].dist2 =
AsConst(gsl_dist_l)[point];
741 for (
int d = 0; d <
dim; ++d)
743 opt[point].r[d] =
AsConst(gsl_ref_l)[
dim * point + d];
749 ip.
Set2(0.5*opt[point].r[0]+0.5, 0.5*opt[point].r[1]+0.5);
753 ip.
Set3(0.5*opt[point].r[0]+0.5, 0.5*opt[point].r[1]+0.5,
754 0.5*opt[point].r[2]+0.5);
759 CODE_INTERNAL : CODE_BORDER;
760 opt[point].code = setcode==CODE_BORDER && opt[point].dist2>
bdr_tol ?
761 CODE_NOT_FOUND : setcode;
767 sarray_sort(
struct outPt_t, opt, out_pt.n, code, 0, &
DEV.cr->data);
770 while (n && opt[n - 1].code == CODE_NOT_FOUND)
776 sarray_transfer(
struct outPt_t, &out_pt, proc, 1,
DEV.cr);
787 struct outPt_t *opt = (
struct outPt_t *)out_pt.ptr;
788 for (; n; --n, ++opt)
790 const int index = opt->index;
795 if (
gsl_code[
index] == CODE_NOT_FOUND || opt->code == CODE_INTERNAL ||
798 for (
int d = 0; d <
dim; ++d)
821 for (
int d = 0; d <
dim; d++)
838 CODE_INTERNAL : CODE_BORDER;
840 CODE_NOT_FOUND : setcode;
847 unsigned int index, proc, el;
853 unsigned int index, proc;
867 DEV.dof1d_sol = dof1Dsol;
869 DEV.lagcoeff_sol.UseDevice(
true);
DEV.lagcoeff_sol.SetSize(dof1Dsol);
870 if (
DEV.dof1d_sol !=
DEV.dof1d || !
DEV.find_device)
872 gslib::lobatto_nodes(
DEV.gll1d_sol.HostWrite(), dof1Dsol);
873 gslib::gll_lag_setup(
DEV.lagcoeff_sol.HostWrite(), dof1Dsol);
877 DEV.gll1d_sol =
DEV.gll1d.HostRead();
878 DEV.lagcoeff_sol =
DEV.lagcoeff.HostRead();
883 struct gslib::array src, outpt;
915 array_init(evalSrcPt_t, &src, numSend);
916 pt = (evalSrcPt_t *)src.ptr;
921 if (*code != CODE_NOT_FOUND && *proc !=
gsl_comm->id)
923 for (
int d = 0; d <
dim; ++d)
932 else if (*code != CODE_NOT_FOUND && *proc ==
gsl_comm->id)
934 gsl_elem_temp[ctr] = *el;
935 for (
int d = 0; d <
dim; ++d)
937 gsl_ref_temp(
dim*ctr+d) = r[d];
939 index_temp[ctr] =
index;
949 src.n = pt - (evalSrcPt_t *)src.ptr;
950 sarray_transfer(evalSrcPt_t, &src, proc, 1,
cr);
955 Vector interp_vals(nlocal*ncomp);
984 int interp_Offset = interp_vals.
Size()/ncomp;
985 for (
int i = 0; i < ncomp; i++)
987 for (
int j = 0; j < nlocal; j++)
989 int pt_index = index_temp[j];
993 field_out(idx) =
AsConst(interp_vals)(j + interp_Offset*i);
1010 const evalSrcPt_t *spt;
1012 spt = (evalSrcPt_t *)src.ptr;
1021 spt = (evalSrcPt_t *)src.ptr;
1023 for (
int i = 0; i < n; i++, ++spt)
1025 gsl_elem_temp[i] = spt->el;
1026 for (
int d = 0; d <
dim; d++)
1028 gsl_ref_temp(i*
dim + d) = spt->r[d];
1032 Vector interp_vals(n*ncomp);
1039 interp_vals, n, ncomp,
1047 interp_vals, n, ncomp,
1056 int Offset = interp_vals.
Size()/ncomp;
1057 for (
int i = 0; i < ncomp; i++)
1059 spt = (evalSrcPt_t *)src.ptr;
1060 array_init(evalOutPt_t, &outpt, n);
1062 opt = (evalOutPt_t *)outpt.ptr;
1064 for (
int j = 0; j < n; j++)
1066 opt->index = spt->index;
1067 opt->proc = spt->proc;
1068 opt->out =
AsConst(interp_vals)(j + Offset*i);
1073 sarray_transfer(
struct evalOutPt_t, &outpt, proc, 1,
cr);
1075 opt = (evalOutPt_t *)outpt.ptr;
1080 opt->index*ncomp + i;
1081 field_out(idx) = opt->out;
1093 int point_pos_ordering) {};
1096 const int nel,
const int ncomp,
1098 const int ordering) {};
1102 int point_pos_ordering,
const double bb_t,
1103 const double newt_tol,
const int npt_max)
1114 int point_pos_ordering)
1122 int point_pos_ordering)
1124 FindPoints(m, point_pos, point_pos_ordering);
1133 findpts_free_2((gslib::findpts_data_2 *)this->
fdataD);
1137 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++)
1375 MFEM_ABORT(
"Unsupported geometry type.");
1378 for (
int i = 0; i < NEsplit; i++)
1393 const int NEsplit = meshin->
GetNE();
1396 pts_cnt = NEsplit * dof_cnt;
1401 MFEM_VERIFY(tbe != NULL,
"TensorBasis FiniteElement expected.");
1409 MFEM_ASSERT(irule->
GetNPoints() == pts_cnt,
"IntegrationRule does not have"
1410 "the correct number of points.");
1413 for (
int i = 0; i < NEsplit; i++)
1417 for (
int j = 0; j < dof_cnt; j++)
1419 for (
int d = 0; d <
dim; d++)
1421 irlist(pts_cnt * d + pt_id) = pos(dof_map[j], d);
1423 irule->
IntPoint(pt_id).
x = irlist(pt_id);
1424 irule->
IntPoint(pt_id).
y = irlist(pts_cnt + pt_id);
1427 irule->
IntPoint(pt_id).
z = irlist(2*pts_cnt + pt_id);
1440 const int vdim = fes->
GetVDim();
1445 const int dof_1D = maxOrder+1;
1446 const int pts_el = std::pow(dof_1D,
dim);
1448 node_vals.
SetSize(vdim * pts_cnt);
1455 int gsl_mesh_pt_index = 0;
1457 for (
int e = 0; e < NE; e++)
1461 bool el_to_split =
true;
1496 MFEM_ABORT(
"Unsupported geometry type.");
1503 for (
int i = 0; i < ir_split_temp->
GetNPoints(); i++)
1506 nodes->GetVectorValue(e, ip, locval);
1507 for (
int d = 0; d < vdim; d++)
1509 node_vals(pts_cnt*d + gsl_mesh_pt_index) = locval(d);
1511 gsl_mesh_pt_index++;
1516 const int dof_cnt_split = fe->
GetDof();
1520 MFEM_VERIFY(tbe != NULL,
"TensorBasis FiniteElement expected.");
1523 if (dm.
Size() > 0) { dof_map = dm; }
1524 else {
for (
int i = 0; i < dof_cnt_split; i++) { dof_map[i] = i; } }
1527 Vector posV(pos.
Data(), dof_cnt_split * vdim);
1531 nodes->GetSubVector(xdofs, posV);
1532 for (
int j = 0; j < dof_cnt_split; j++)
1534 for (
int d = 0; d < vdim; d++)
1536 node_vals(pts_cnt * d + gsl_mesh_pt_index) = pos(dof_map[j], d);
1538 gsl_mesh_pt_index++;
1559 double rbtol = 1e-12;
1573 struct gslib::array *outpt =
new gslib::array;
1574 struct out_pt {
double r[3]; uint
index, el, proc, code; };
1576 array_init(
struct out_pt, outpt, nptsend);
1578 pt = (
struct out_pt *)outpt->ptr;
1585 for (
int d = 0; d <
dim; ++d)
1597 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1601 pt = (
struct out_pt *)outpt->ptr;
1606 const int elem = pt->el;
1642 for (
int d = 0; d <
dim; d++)
1644 pt->r[d] = mfem_ref(d);
1654 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1658 pt = (
struct out_pt *)outpt->ptr;
1662 for (
int d = 0; d <
dim; d++)
1681 if (
dim == 3) { ip.
z = mfem_ref(2); }
1715 if (
dim == 3) { ip.
z = mfem_ref(2); }
1731 bool tensor_product_only =
mesh->
GetNE() == 0 ||
1736 MPI_Allreduce(MPI_IN_PLACE, &tensor_product_only, 1, MFEM_MPI_CXX_BOOL,
1743#if GSLIB_RELEASE_VERSION == 10007
1746 MFEM_ABORT(
"Either update to gslib v1.0.9 for GPU support "
1747 "or use SetGPUtoCPUFallback to use host-functions. See "
1748 "INSTALL for instructions to update GSLIB");
1752 "basis not supported");
1758 R->
Mult(field_in, node_vals);
1772 if (fec_h1 && gf_order == mesh_order &&
1795 int borderPts = indl2.
Size();
1797 MPI_Allreduce(MPI_IN_PLACE, &borderPts, 1, MPI_INT, MPI_SUM,
gsl_comm->c);
1799 if (borderPts == 0) {
return; }
1803 int gf_order_h1 = std::max(gf_order, 1);
1821 MFEM_ABORT(
"Invalid averaging type.");
1824 if (gf_order_h1 == mesh_order)
1834 for (
int j = 0; j < ncomp; j++)
1836 for (
int i = 0; i < indl2.
Size(); i++)
1841 field_out(idx) = field_out_l2(idx);
1853 for (
int e = 0; e < ind_fes.
GetMesh()->GetNE(); e++)
1864 points_fld = field_in.
Size() / ncomp;
1866 "FindPointsGSLIB::InterpolateH1: Inconsistent size of gsl_code");
1872 for (
int i = 0; i < ncomp; i++)
1874 const int dataptrin = i*points_fld,
1882 for (
int j = 0; j < points_fld; j++)
1884 field_in_scalar(j) = field_in(i + j*ncomp);
1891 findpts_eval_2(field_out.
GetData()+dataptrout,
sizeof(
double),
1897 (gslib::findpts_data_2 *)this->fdataD);
1901 findpts_eval_3(field_out.
GetData()+dataptrout,
sizeof(
double),
1907 (gslib::findpts_data_3 *)this->fdataD);
1912 Vector field_out_temp = field_out;
1913 for (
int i = 0; i < ncomp; i++)
1917 field_out(i + j*ncomp) = field_out_temp(j + i*
points_cnt);
1946 for (
int i = 0; i < ncomp; i++)
1948 field_out(
index + i*npt) = localval(i);
1953 for (
int i = 0; i < ncomp; i++)
1955 field_out(
index*ncomp + i) = localval(i);
1970 struct gslib::array *outpt =
new gslib::array;
1971 struct out_pt {
double r[3], ival; uint
index, el, proc; };
1973 array_init(
struct out_pt, outpt, nptsend);
1975 pt = (
struct out_pt *)outpt->ptr;
1987 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1993 pt = (
struct out_pt *)outpt->ptr;
1998 pt->ival = field_in.
GetValue(pt->el, ip, 1);
2003 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
2005 pt = (
struct out_pt *)outpt->ptr;
2008 field_out(pt->index) = pt->ival;
2018 pt = (
struct out_pt *)outpt->ptr;
2019 Vector vec_int_vals(npt*ncomp);
2030 struct gslib::array *savpt =
new gslib::array;
2031 struct sav_pt { uint
index, proc; };
2033 array_init(
struct sav_pt, savpt, npt);
2035 spt = (
struct sav_pt *)savpt->ptr;
2036 pt = (
struct out_pt *)outpt->ptr;
2039 spt->index = pt->index;
2040 spt->proc = pt->proc;
2048 struct gslib::array *sendpt =
new gslib::array;
2049 struct send_pt {
double ival; uint
index, proc; };
2050 struct send_pt *sdpt;
2051 for (
int j = 0; j < ncomp; j++)
2053 array_init(
struct send_pt, sendpt, npt);
2055 spt = (
struct sav_pt *)savpt->ptr;
2056 sdpt = (
struct send_pt *)sendpt->ptr;
2059 sdpt->index = spt->index;
2060 sdpt->proc = spt->proc;
2061 sdpt->ival = vec_int_vals(j +
index*ncomp);
2065 sarray_transfer(
struct send_pt, sendpt, proc, 1,
cr);
2066 sdpt = (
struct send_pt *)sendpt->ptr;
2070 sdpt->index + j*nptorig :
2071 sdpt->index*ncomp + j;
2072 field_out(idx) = sdpt->ival;
2089 "Invalid size. Please make sure to call FindPoints method "
2090 "before calling this function.");
2093 struct gslib::array *outpt =
new gslib::array;
2095 struct out_pt {
double rst[3]; uint
index, elem, proc, code; };
2097 array_init(
struct out_pt, outpt,
points_cnt);
2099 pt = (
struct out_pt *)outpt->ptr;
2107 for (
int d = 0; d <
dim; ++d)
2115 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
2118 const int points_recv = outpt->n;
2120 recv_elem.
SetSize(points_recv);
2122 recv_code.
SetSize(points_recv);
2125 pt = (
struct out_pt *)outpt->ptr;
2129 recv_elem[
index] = pt->elem;
2131 recv_code[
index] = pt->code;
2132 for (
int d = 0; d <
dim; ++d)
2134 recv_ref(
index*
dim + d)= pt->rst[d];
2149 MFEM_VERIFY(points_recv == 0 ||
2150 int_vals.
Size() % points_recv == 0,
2151 "Incompatible size. Please return interpolated values"
2152 "corresponding to points received using"
2153 "SendCoordinatesToOwningProcessors.");
2156 for (
int v = 0; v < vdim; v++)
2159 struct gslib::array *outpt =
new gslib::array;
2160 struct out_pt {
double val; uint
index, proc; };
2162 array_init(
struct out_pt, outpt, points_recv);
2163 outpt->n=points_recv;
2164 pt = (
struct out_pt *)outpt->ptr;
2170 int_vals(
index + v*points_recv) :
2171 int_vals(
index*vdim + v);
2176 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
2179 MFEM_VERIFY(outpt->n ==
points_cnt,
"Incompatible size. Number of points "
2180 "received does not match the number of points originally "
2181 "found using FindPoints.");
2183 pt = (
struct out_pt *)outpt->ptr;
2189 field_out(idx) = pt->val;
2200 MFEM_VERIFY(
setupflag,
"Call FindPointsGSLIB::Setup method first");
2201 auto *findptsData3 = (gslib::findpts_data_3 *)this->
fdataD;
2202 auto *findptsData2 = (gslib::findpts_data_2 *)this->
fdataD;
2203 int nve =
dim == 2 ? 4 : 8;
2209 for (
int e = 0; e < nel; e++)
2211 auto box = findptsData3->local.obb[e];
2213 for (
int d = 0; d <
dim; d++)
2215 minn[d] = box.x[d].min;
2216 maxx[d] = box.x[d].max;
2219 aabb(e*nve*
dim + c++) = minn[0];
2220 aabb(e*nve*
dim + c++) = minn[1];
2221 aabb(e*nve*
dim + c++) = minn[2];
2222 aabb(e*nve*
dim + c++) = maxx[0];
2223 aabb(e*nve*
dim + c++) = minn[1];
2224 aabb(e*nve*
dim + c++) = minn[2];
2225 aabb(e*nve*
dim + c++) = maxx[0];
2226 aabb(e*nve*
dim + c++) = maxx[1];
2227 aabb(e*nve*
dim + c++) = minn[2];
2228 aabb(e*nve*
dim + c++) = minn[0];
2229 aabb(e*nve*
dim + c++) = maxx[1];
2230 aabb(e*nve*
dim + c++) = minn[2];
2231 aabb(e*nve*
dim + c++) = minn[0];
2232 aabb(e*nve*
dim + c++) = minn[1];
2233 aabb(e*nve*
dim + c++) = maxx[2];
2234 aabb(e*nve*
dim + c++) = maxx[0];
2235 aabb(e*nve*
dim + c++) = minn[1];
2236 aabb(e*nve*
dim + c++) = maxx[2];
2237 aabb(e*nve*
dim + c++) = maxx[0];
2238 aabb(e*nve*
dim + c++) = maxx[1];
2239 aabb(e*nve*
dim + c++) = maxx[2];
2240 aabb(e*nve*
dim + c++) = minn[0];
2241 aabb(e*nve*
dim + c++) = maxx[1];
2242 aabb(e*nve*
dim + c++) = maxx[2];
2247 for (
int e = 0; e < nel; e++)
2249 auto box = findptsData2->local.obb[e];
2251 for (
int d = 0; d <
dim; d++)
2253 minn[d] = box.x[d].min;
2254 maxx[d] = box.x[d].max;
2256 aabb(e*nve*
dim + 0) = minn[0];
2257 aabb(e*nve*
dim + 1) = minn[1];
2258 aabb(e*nve*
dim + 2) = maxx[0];
2259 aabb(e*nve*
dim + 3) = minn[1];
2260 aabb(e*nve*
dim + 4) = maxx[0];
2261 aabb(e*nve*
dim + 5) = maxx[1];
2262 aabb(e*nve*
dim + 6) = minn[0];
2263 aabb(e*nve*
dim + 7) = maxx[1];
2271 MFEM_VERIFY(
setupflag,
"Call FindPointsGSLIB::Setup method first");
2272 auto *findptsData3 = (gslib::findpts_data_3 *)this->
fdataD;
2273 auto *findptsData2 = (gslib::findpts_data_2 *)this->
fdataD;
2274 int nve =
dim == 2 ? 4 : 8;
2282 for (
int e = 0; e < nel; e++)
2284 auto box = findptsData3->local.obb[e];
2286 for (
int d = 0; d <
dim; d++)
2288 obbC(e*
dim + d) = box.c0[d];
2290 for (
int i = 0; i <
dim; i++)
2292 for (
int j = 0; j <
dim; j++)
2294 Ad[i*
dim + j] = box.A[i + j*
dim];
2304 v1(0) = -1.0; v1(1) = -1.0; v1(2) = -1.0;
2306 Amat.
Mult(v1, temp);
2308 v1(0) = 1.0; v1(1) = -1.0; v1(2) = -1.0;
2310 Amat.
Mult(v1, temp);
2312 v1(0) = 1.0; v1(1) = 1.0; v1(2) = -1.0;
2314 Amat.
Mult(v1, temp);
2316 v1(0) = -1.0; v1(1) = 1.0; v1(2) = -1.0;
2318 Amat.
Mult(v1, temp);
2320 v1(0) = -1.0; v1(1) = -1.0; v1(2) = 1.0;
2322 Amat.
Mult(v1, temp);
2324 v1(0) = 1.0; v1(1) = -1.0; v1(2) = 1.0;
2326 Amat.
Mult(v1, temp);
2328 v1(0) = 1.0; v1(1) = 1.0; v1(2) = 1.0;
2330 Amat.
Mult(v1, temp);
2332 v1(0) = -1.0; v1(1) = 1.0; v1(2) = 1.0;
2334 Amat.
Mult(v1, temp);
2340 for (
int e = 0; e < nel; e++)
2342 auto box = findptsData2->local.obb[e];
2344 for (
int d = 0; d <
dim; d++)
2346 obbC(e*
dim + d) = box.c0[d];
2348 for (
int i = 0; i <
dim; i++)
2350 for (
int j = 0; j <
dim; j++)
2352 Ad[i*
dim + j] = box.A[i + j*
dim];
2362 v1(0) = -1.0; v1(1) = -1.0;
2364 Amat.
Mult(v1, temp);
2366 v1(0) = 1.0; v1(1) = -1.0;
2368 Amat.
Mult(v1, temp);
2370 v1(0) = 1.0; v1(1) = 1.0;
2372 Amat.
Mult(v1, temp);
2374 v1(0) = -1.0; v1(1) = 1.0;
2376 Amat.
Mult(v1, temp);
2384 const double bb_t,
const double newt_tol,
2387 MFEM_VERIFY(m.
GetNodes() != NULL,
"Mesh nodes are required.");
2388 const int meshOrder = m.
GetNodes()->FESpace()->GetMaxElementOrder();
2396 unsigned dof1D = fe->
GetOrder() + 1;
2430 MFEM_ASSERT(meshid>=0,
" The ID should be greater than or equal to 0.");
2433 NEtot = pts_cnt/(int)pow(dof1D,
dim);
2448 unsigned nr[2] = { dof1D, dof1D };
2449 unsigned mr[2] = { 2*dof1D, 2*dof1D };
2450 double *
const elx[2] =
2452 pts_cnt == 0 ? nullptr : &
gsl_mesh(0),
2453 pts_cnt == 0 ? nullptr : &
gsl_mesh(pts_cnt)
2456 pts_cnt, pts_cnt, npt_max,
newt_tol,
2461 unsigned nr[3] = { dof1D, dof1D, dof1D };
2462 unsigned mr[3] = { 2*dof1D, 2*dof1D, 2*dof1D };
2463 double *
const elx[3] =
2465 pts_cnt == 0 ? nullptr : &
gsl_mesh(0),
2466 pts_cnt == 0 ? nullptr : &
gsl_mesh(pts_cnt),
2467 pts_cnt == 0 ? nullptr : &
gsl_mesh(2*pts_cnt)
2470 pts_cnt, pts_cnt, npt_max,
newt_tol,
2479 int point_pos_ordering)
2481 MFEM_VERIFY(
setupflag,
"Use OversetFindPointsGSLIB::Setup before "
2483 MFEM_VERIFY(
overset,
"Please setup FindPoints for overlapping grids.");
2485 unsigned int match = 0;
2493 auto xvFill = [&](
const double *xv_base[],
unsigned xv_stride[])
2495 for (
int d = 0; d <
dim; d++)
2500 xv_stride[d] =
sizeof(double);
2504 xv_base[d] = point_pos.
GetData() + d;
2505 xv_stride[d] =
dim*
sizeof(double);
2511 auto *findptsData = (gslib::findpts_data_2 *)this->
fdataD;
2512 const double *xv_base[2];
2513 unsigned xv_stride[2];
2514 xvFill(xv_base, xv_stride);
2521 point_id.
GetData(),
sizeof(
unsigned int), &match,
2526 auto *findptsData = (gslib::findpts_data_3 *)this->
fdataD;
2527 const double *xv_base[3];
2528 unsigned xv_stride[3];
2529 xvFill(xv_base, xv_stride);
2536 point_id.
GetData(),
sizeof(
unsigned int), &match,
2561 int point_pos_ordering)
2563 FindPoints(point_pos, point_id, point_pos_ordering);
2570 cr =
new gslib::crystal;
2573 MPI_Initialized(&initialized);
2574 if (!initialized) { MPI_Init(NULL, NULL); }
2575 MPI_Comm comm = MPI_COMM_WORLD;
2586 : cr(NULL), gsl_comm(NULL)
2589 cr =
new gslib::crystal;
2607 long long minval = ids.
Min();
2609 MPI_Allreduce(MPI_IN_PLACE, &minval, 1, MPI_LONG_LONG_INT,
2612 MFEM_VERIFY(minval >= 0,
"Unique identifier cannot be negative.");
2618 gslib::gs_crystal_router, 0);
2624 "Incompatible setup and GOP operation.");
2627 gslib_gs(senddata.
GetData(),gslib::gs_double,gslib::gs_add,0,
gsl_data,0);
2631 gslib_gs(senddata.
GetData(),gslib::gs_double,gslib::gs_mul,0,
gsl_data,0);
2635 gslib_gs(senddata.
GetData(),gslib::gs_double,gslib::gs_max,0,
gsl_data,0);
2639 gslib_gs(senddata.
GetData(),gslib::gs_double,gslib::gs_min,0,
gsl_data,0);
2643 MFEM_ABORT(
"Invalid GSOp operation.");
2650#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.
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
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
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()
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.
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.
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)
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