17 #ifdef MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC 18 #pragma GCC diagnostic push 19 #pragma GCC diagnostic ignored "-Wunused-function" 28 #ifdef MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC 29 #pragma GCC diagnostic pop 38 fdata2D(NULL), fdata3D(NULL), cr(NULL), gsl_comm(NULL),
39 dim(-1), points_cnt(0), setupflag(false), default_interp_value(0),
40 avgtype(
AvgType::ARITHMETIC), bdr_tol(1e-8)
55 cr =
new gslib::crystal;
58 MPI_Initialized(&initialized);
59 if (!initialized) { MPI_Init(NULL, NULL); }
60 MPI_Comm comm = MPI_COMM_WORLD;
71 for (
int i = 0; i < 4; i++)
85 fdata2D(NULL), fdata3D(NULL), cr(NULL), gsl_comm(NULL),
86 dim(-1), points_cnt(0), setupflag(false), default_interp_value(0),
87 avgtype(
AvgType::ARITHMETIC), bdr_tol(1e-8)
102 cr =
new gslib::crystal;
110 MFEM_VERIFY(m.
GetNodes() != NULL,
"Mesh nodes are required.");
111 MFEM_VERIFY(!(m.
GetNodes()->FESpace()->IsVariableOrder()),
112 "Variable order mesh is not currently supported.");
121 unsigned dof1D = fe->
GetOrder() + 1;
149 NEtot = pts_cnt/(int)pow(dof1D,
dim);
153 unsigned nr[2] = { dof1D, dof1D };
154 unsigned mr[2] = { 2*dof1D, 2*dof1D };
157 pts_cnt, pts_cnt, npt_max, newt_tol);
161 unsigned nr[3] = { dof1D, dof1D, dof1D };
162 unsigned mr[3] = { 2*dof1D, 2*dof1D, 2*dof1D };
163 double *
const elx[3] =
166 pts_cnt, pts_cnt, npt_max, newt_tol);
172 int point_pos_ordering)
174 MFEM_VERIFY(
setupflag,
"Use FindPointsGSLIB::Setup before finding points.");
182 auto xvFill = [&](
const double *xv_base[],
unsigned xv_stride[],
int dim)
184 for (
int d = 0; d <
dim; d++)
189 xv_stride[d] =
sizeof(double);
193 xv_base[d] = point_pos.
GetData() + d;
194 xv_stride[d] =
dim*
sizeof(double);
200 const double *xv_base[2];
201 unsigned xv_stride[2];
202 xvFill(xv_base, xv_stride,
dim);
212 const double *xv_base[3];
213 unsigned xv_stride[3];
214 xvFill(xv_base, xv_stride,
dim);
241 int point_pos_ordering,
const double bb_t,
242 const double newt_tol,
const int npt_max)
246 Setup(m, bb_t, newt_tol, npt_max);
253 int point_pos_ordering)
261 int point_pos_ordering)
285 for (
int i = 0; i < 4; i++)
305 const double quad_v[7][2] =
307 {0, 0}, {0.5, 0}, {1, 0}, {0, 0.5},
308 {1./3., 1./3.}, {0.5, 0.5}, {0, 1}
310 const int quad_e[3][4] =
312 {0, 1, 4, 3}, {1, 2, 5, 4}, {3, 4, 5, 6}
315 for (
int j = 0; j < Nvert; j++)
319 for (
int j = 0; j < NEsplit; j++)
321 int attribute = j + 1;
329 for (
int k = 0; k <
dim; k++)
331 for (
int j = 0; j < npt; j++)
345 const double hex_v[15][3] =
347 {0, 0, 0.}, {1, 0., 0.}, {0., 1., 0.}, {0, 0., 1.},
348 {0.5, 0., 0.}, {0.5, 0.5, 0.}, {0., 0.5, 0.},
349 {0., 0., 0.5}, {0.5, 0., 0.5}, {0., 0.5, 0.5},
350 {1./3., 0., 1./3.}, {1./3., 1./3., 1./3.}, {0, 1./3., 1./3.},
351 {1./3., 1./3., 0}, {0.25, 0.25, 0.25}
353 const int hex_e[4][8] =
355 {7, 10, 4, 0, 12, 14, 13, 6},
356 {10, 8, 1, 4, 14, 11, 5, 13},
357 {14, 11, 5, 13, 12, 9, 2, 6},
358 {7, 3, 8, 10, 12, 9, 11, 14}
361 for (
int j = 0; j < Nvert; j++)
365 for (
int j = 0; j < NEsplit; j++)
367 int attribute = j + 1;
375 for (
int k = 0; k <
dim; k++)
377 for (
int j = 0; j < npt; j++)
389 const double hex_v[14][3] =
391 {0, 0, 0}, {0.5, 0, 0}, {1, 0, 0}, {0, 0.5, 0},
392 {1./3., 1./3., 0}, {0.5, 0.5, 0}, {0, 1, 0},
393 {0, 0, 1}, {0.5, 0, 1}, {1, 0, 1}, {0, 0.5, 1},
394 {1./3., 1./3., 1}, {0.5, 0.5, 1}, {0, 1, 1}
396 const int hex_e[3][8] =
398 {0, 1, 4, 3, 7, 8, 11, 10},
399 {1, 2, 5, 4, 8, 9, 12, 11},
400 {3, 4, 5, 6, 10, 11, 12, 13}
403 for (
int j = 0; j < Nvert; j++)
407 for (
int j = 0; j < NEsplit; j++)
409 int attribute = j + 1;
417 for (
int k = 0; k <
dim; k++)
419 for (
int j = 0; j < npt; j++)
431 const double hex_v[23][3] =
433 {0.0000, 0.0000, 0.0000}, {0.5000, 0.0000, 0.0000},
434 {0.0000, 0.0000, 0.5000}, {0.3333, 0.0000, 0.3333},
435 {0.0000, 0.5000, 0.0000}, {0.3333, 0.3333, 0.0000},
436 {0.0000, 0.3333, 0.3333}, {0.2500, 0.2500, 0.2500},
437 {1.0000, 0.0000, 0.0000}, {0.5000, 0.0000, 0.5000},
438 {0.5000, 0.5000, 0.0000}, {0.3333, 0.3333, 0.3333},
439 {0.0000, 1.0000, 0.0000}, {0.0000, 0.5000, 0.5000},
440 {0.0000, 0.0000, 1.0000}, {1.0000, 0.5000, 0.0000},
441 {0.6667, 0.3333, 0.3333}, {0.6667, 0.6667, 0.0000},
442 {0.5000, 0.5000, 0.2500}, {1.0000, 1.0000, 0.0000},
443 {0.5000, 0.5000, 0.5000}, {0.5000, 1.0000, 0.0000},
444 {0.3333, 0.6667, 0.3333}
446 const int hex_e[8][8] =
448 {2, 3, 1, 0, 6, 7, 5, 4}, {3, 9, 8, 1, 7, 11, 10, 5},
449 {7, 11, 10, 5, 6, 13, 12, 4}, {2, 14, 9, 3, 6, 13, 11, 7},
450 {9, 16, 15, 8, 11, 18, 17, 10}, {16, 20, 19, 15, 18, 22, 21, 17},
451 {18, 22, 21, 17, 11, 13, 12, 10}, {9, 14, 20, 16, 11, 13, 22, 18}
454 for (
int j = 0; j < Nvert; j++)
458 for (
int j = 0; j < NEsplit; j++)
460 int attribute = j + 1;
468 for (
int k = 0; k <
dim; k++)
470 for (
int j = 0; j < npt; j++)
503 MFEM_ABORT(
"Unsupported geometry type.");
506 for (
int i = 0; i < NEsplit; i++)
521 const int NEsplit = meshin->
GetNE();
524 pts_cnt = NEsplit * dof_cnt;
529 MFEM_VERIFY(tbe != NULL,
"TensorBasis FiniteElement expected.");
537 MFEM_ASSERT(irule->
GetNPoints() == pts_cnt,
"IntegrationRule does not have" 538 "the correct number of points.");
541 for (
int i = 0; i < NEsplit; i++)
544 nodesplit->GetSubVector(xdofs, posV);
545 for (
int j = 0; j < dof_cnt; j++)
547 for (
int d = 0; d <
dim; d++)
549 irlist(pts_cnt * d + pt_id) = pos(dof_map[j], d);
551 irule->
IntPoint(pt_id).
x = irlist(pt_id);
552 irule->
IntPoint(pt_id).
y = irlist(pts_cnt + pt_id);
555 irule->
IntPoint(pt_id).
z = irlist(2*pts_cnt + pt_id);
573 const int pts_el = std::pow(dof_1D,
dim);
575 node_vals.
SetSize(vdim * pts_cnt);
578 int gsl_mesh_pt_index = 0;
580 for (
int e = 0; e < NE; e++)
584 bool el_to_split =
true;
607 MFEM_ABORT(
"Unsupported geometry type.");
614 for (
int i = 0; i < ir_split_temp->
GetNPoints(); i++)
618 for (
int d = 0; d < vdim; d++)
620 node_vals(pts_cnt*d + gsl_mesh_pt_index) = locval(d);
627 const int dof_cnt_split = fe->
GetDof();
631 MFEM_VERIFY(tbe != NULL,
"TensorBasis FiniteElement expected.");
634 if (dm.
Size() > 0) { dof_map = dm; }
635 else {
for (
int i = 0; i < dof_cnt_split; i++) { dof_map[i] = i; } }
638 Vector posV(pos.
Data(), dof_cnt_split * vdim);
643 for (
int j = 0; j < dof_cnt_split; j++)
645 for (
int d = 0; d < vdim; d++)
647 node_vals(pts_cnt * d + gsl_mesh_pt_index) = pos(dof_map[j], d);
679 struct gslib::array *outpt =
new gslib::array;
680 struct out_pt {
double r[3];
uint index, el, proc; };
682 array_init(
struct out_pt, outpt, nptsend);
684 pt = (
struct out_pt *)outpt->ptr;
691 for (
int d = 0; d <
dim; ++d)
702 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
706 pt = (
struct out_pt *)outpt->ptr;
711 const int elem = pt->el;
740 for (
int d = 0; d <
dim; d++)
742 pt->r[d] = mfem_ref(d);
748 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
752 pt = (
struct out_pt *)outpt->ptr;
756 for (
int d = 0; d <
dim; d++)
796 ip.
Set2(mfem_ref.GetData());
797 if (
dim == 3) { ip.
z = mfem_ref(2); }
813 if (fec_h1 && gf_order == mesh_order &&
835 int borderPts = indl2.
Size();
837 MPI_Allreduce(MPI_IN_PLACE, &borderPts, 1, MPI_INT, MPI_SUM,
gsl_comm->c);
839 if (borderPts == 0) {
return; }
843 int gf_order_h1 = std::max(gf_order, 1);
849 if (
avgtype == AvgType::ARITHMETIC)
853 else if (
avgtype == AvgType::HARMONIC)
859 MFEM_ABORT(
"Invalid averaging type.");
862 if (gf_order_h1 == mesh_order)
872 for (
int j = 0; j < ncomp; j++)
874 for (
int i = 0; i < indl2.
Size(); i++)
879 field_out(idx) = field_out_l2(idx);
893 points_fld = field_in.
Size() / ncomp,
899 for (
int i = 0; i < ncomp; i++)
901 const int dataptrin = i*points_fld,
905 field_in_scalar.NewDataAndSize(field_in.
GetData()+dataptrin, points_fld);
909 for (
int j = 0; j < points_fld; j++)
911 field_in_scalar(j) = field_in(i + j*ncomp);
918 findpts_eval_2(field_out.
GetData()+dataptrout,
sizeof(double),
927 findpts_eval_3(field_out.
GetData()+dataptrout,
sizeof(double),
937 Vector field_out_temp = field_out;
938 for (
int i = 0; i < ncomp; i++)
942 field_out(i + j*ncomp) = field_out_temp(j + i*
points_cnt);
970 for (
int i = 0; i < ncomp; i++)
972 field_out(
index + i*npt) = localval(i);
977 for (
int i = 0; i < ncomp; i++)
979 field_out(
index*ncomp + i) = localval(i);
994 struct gslib::array *outpt =
new gslib::array;
995 struct out_pt {
double r[3], ival;
uint index, el, proc; };
997 array_init(
struct out_pt, outpt, nptsend);
999 pt = (
struct out_pt *)outpt->ptr;
1011 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1017 pt = (
struct out_pt *)outpt->ptr;
1022 pt->ival = field_in.
GetValue(pt->el, ip, 1);
1027 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1029 pt = (
struct out_pt *)outpt->ptr;
1032 field_out(pt->index) = pt->ival;
1042 pt = (
struct out_pt *)outpt->ptr;
1043 Vector vec_int_vals(npt*ncomp);
1048 Vector localval(vec_int_vals.GetData()+
index*ncomp, ncomp);
1054 struct gslib::array *savpt =
new gslib::array;
1057 array_init(
struct sav_pt, savpt, npt);
1059 spt = (
struct sav_pt *)savpt->ptr;
1060 pt = (
struct out_pt *)outpt->ptr;
1063 spt->index = pt->index;
1064 spt->proc = pt->proc;
1072 struct gslib::array *sendpt =
new gslib::array;
1073 struct send_pt {
double ival;
uint index, proc; };
1074 struct send_pt *sdpt;
1075 for (
int j = 0; j < ncomp; j++)
1077 array_init(
struct send_pt, sendpt, npt);
1079 spt = (
struct sav_pt *)savpt->ptr;
1080 sdpt = (
struct send_pt *)sendpt->ptr;
1083 sdpt->index = spt->index;
1084 sdpt->proc = spt->proc;
1085 sdpt->ival = vec_int_vals(j +
index*ncomp);
1089 sarray_transfer(
struct send_pt, sendpt, proc, 1,
cr);
1090 sdpt = (
struct send_pt *)sendpt->ptr;
1091 for (
int index = 0; index < static_cast<int>(sendpt->n);
index++)
1094 sdpt->index + j*nptorig :
1095 sdpt->index*ncomp + j;
1096 field_out(idx) = sdpt->ival;
1110 const double bb_t,
const double newt_tol,
1113 MFEM_VERIFY(m.
GetNodes() != NULL,
"Mesh nodes are required.");
1114 MFEM_VERIFY(!(m.
GetNodes()->FESpace()->IsVariableOrder()),
1115 "Variable order mesh is not currently supported.");
1124 unsigned dof1D = fe->
GetOrder() + 1;
1150 MFEM_ASSERT(meshid>=0,
" The ID should be greater than or equal to 0.");
1153 NEtot = pts_cnt/(int)pow(dof1D,
dim);
1168 unsigned nr[2] = { dof1D, dof1D };
1169 unsigned mr[2] = { 2*dof1D, 2*dof1D };
1172 pts_cnt, pts_cnt, npt_max, newt_tol,
1177 unsigned nr[3] = { dof1D, dof1D, dof1D };
1178 unsigned mr[3] = { 2*dof1D, 2*dof1D, 2*dof1D };
1179 double *
const elx[3] =
1182 pts_cnt, pts_cnt, npt_max, newt_tol,
1191 int point_pos_ordering)
1193 MFEM_VERIFY(
setupflag,
"Use OversetFindPointsGSLIB::Setup before " 1195 MFEM_VERIFY(
overset,
" Please setup FindPoints for overlapping grids.");
1197 unsigned int match = 0;
1205 auto xvFill = [&](
const double *xv_base[],
unsigned xv_stride[],
int dim)
1207 for (
int d = 0; d <
dim; d++)
1212 xv_stride[d] =
sizeof(double);
1216 xv_base[d] = point_pos.
GetData() + d;
1217 xv_stride[d] =
dim*
sizeof(double);
1223 const double *xv_base[2];
1224 unsigned xv_stride[2];
1225 xvFill(xv_base, xv_stride,
dim);
1232 point_id.
GetData(),
sizeof(
unsigned int), &match,
1237 const double *xv_base[3];
1238 unsigned xv_stride[3];
1239 xvFill(xv_base, xv_stride,
dim);
1246 point_id.
GetData(),
sizeof(
unsigned int), &match,
1271 int point_pos_ordering)
1273 FindPoints(point_pos, point_id, point_pos_ordering);
1280 #endif // MFEM_USE_GSLIB Abstract class for all finite elements.
virtual void Interpolate(const GridFunction &field_in, Vector &field_out)
int GetNPoints() const
Returns the number of the points in the integration rule.
Array< unsigned int > gsl_elem
Class for an integration rule - an Array of IntegrationPoint.
const FiniteElementSpace * GetNodalFESpace() const
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
Class for grid function - Vector with associated FE space.
virtual void GetVectorValue(int i, const IntegrationPoint &ip, Vector &val) const
virtual ~FindPointsGSLIB()
void FindPoints(const Vector &point_pos, int point_pos_ordering=Ordering::byNODES)
void SetSize(int s)
Resize the vector to size s.
Array< GridFunction * > gf_rst_map
void ProjectDiscCoefficient(VectorCoefficient &coeff, Array< int > &dof_attr)
Array< unsigned int > gsl_mfem_elem
T * GetData()
Returns the data.
int Size() const
Returns the size of the vector.
virtual void SetupSplitMeshes()
Data type dense matrix using column-major storage.
double * Data() const
Returns the matrix data array.
void Interpolate(const Vector &point_pos, Array< unsigned int > &point_id, const GridFunction &field_in, Vector &field_out, int point_pos_ordering=Ordering::byNODES)
const Element * GetElement(int i) const
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Array< unsigned int > gsl_proc
Array< Mesh * > mesh_split
virtual double GetValue(int i, const IntegrationPoint &ip, int vdim=1) const
void DeleteAll()
Delete the whole array.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
const Array< int > & GetDofMap() const
Get an Array<int> that maps lexicographically ordered indices to the indices of the respective nodes/...
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
virtual void MapRefPosAndElemIndices()
struct gslib::findpts_data_3 * fdata3D
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
virtual void GetNodalValues(const GridFunction *gf_in, Vector &node_vals)
Get GridFunction value at the points expected by GSLIB.
Array< IntegrationRule * > ir_split
Geometry::Type GetGeometryType() const
int Append(const T &el)
Append element 'el' to array, resize if necessary.
const FiniteElementCollection * FEColl() const
void Setup(Mesh &m, const double bb_t=0.1, const double newt_tol=1.0e-12, const int npt_max=256)
double default_interp_value
struct gslib::crystal * cr
void Set2(const double x1, const double x2)
virtual void SetNodalFESpace(FiniteElementSpace *nfes)
FiniteElementSpace * FESpace()
Array< int > split_element_index
Array< FiniteElementSpace * > fes_rst_map
double * GetData() const
Return a pointer to the beginning of the Vector data.
int GetVDim() const
Returns vector dimension.
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void Set3(const double x1, const double x2, const double x3)
Array< unsigned int > gsl_code
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
virtual void InterpolateGeneral(const GridFunction &field_in, Vector &field_out)
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
virtual void SetupIntegrationRuleForSplitMesh(Mesh *mesh, IntegrationRule *irule, int order)
int GetDof() const
Returns the number of degrees of freedom in the finite element.
struct gslib::findpts_data_2 * fdata2D
int GetNE() const
Returns number of elements.
Class for integration point with weight.
Ordering::Type GetOrdering() const
Return the ordering method.
Array< int > split_element_map
void Destroy()
Destroy a vector.
int index(int i, int j, int nx, int ny)
struct gslib::comm * gsl_comm
int Size() const
Return the logical size of the array.
FiniteElementCollection * fec_map_lin
Vector coefficient defined by a vector GridFunction.
Arbitrary order H1-conforming (continuous) finite elements.
void GetNodes(Vector &node_coord) const
void FindPoints(const Vector &point_pos, Array< unsigned int > &point_id, int point_pos_ordering=Ordering::byNODES)
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)
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
virtual void InterpolateH1(const GridFunction &field_in, Vector &field_out)
Use GSLIB for communication and interpolation.
Arbitrary order "L2-conforming" discontinuous finite elements.