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),
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),
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);
229 for (
int d = 0; d <
dim; d++) {
gsl_ref(i*dim + d) = -1.; }
239 int point_pos_ordering,
const double bb_t,
240 const double newt_tol,
const int npt_max)
244 Setup(m, bb_t, newt_tol, npt_max);
251 int point_pos_ordering)
259 int point_pos_ordering)
283 for (
int i = 0; i < 4; i++)
303 const double quad_v[7][2] =
305 {0, 0}, {0.5, 0}, {1, 0}, {0, 0.5},
306 {1./3., 1./3.}, {0.5, 0.5}, {0, 1}
308 const int quad_e[3][4] =
310 {0, 1, 4, 3}, {1, 2, 5, 4}, {3, 4, 5, 6}
313 for (
int j = 0; j < Nvert; j++)
317 for (
int j = 0; j < NEsplit; j++)
319 int attribute = j + 1;
327 for (
int k = 0; k <
dim; k++)
329 for (
int j = 0; j < npt; j++)
343 const double hex_v[15][3] =
345 {0, 0, 0.}, {1, 0., 0.}, {0., 1., 0.}, {0, 0., 1.},
346 {0.5, 0., 0.}, {0.5, 0.5, 0.}, {0., 0.5, 0.},
347 {0., 0., 0.5}, {0.5, 0., 0.5}, {0., 0.5, 0.5},
348 {1./3., 0., 1./3.}, {1./3., 1./3., 1./3.}, {0, 1./3., 1./3.},
349 {1./3., 1./3., 0}, {0.25, 0.25, 0.25}
351 const int hex_e[4][8] =
353 {7, 10, 4, 0, 12, 14, 13, 6},
354 {10, 8, 1, 4, 14, 11, 5, 13},
355 {14, 11, 5, 13, 12, 9, 2, 6},
356 {7, 3, 8, 10, 12, 9, 11, 14}
359 for (
int j = 0; j < Nvert; j++)
363 for (
int j = 0; j < NEsplit; j++)
365 int attribute = j + 1;
373 for (
int k = 0; k <
dim; k++)
375 for (
int j = 0; j < npt; j++)
387 const double hex_v[14][3] =
389 {0, 0, 0}, {0.5, 0, 0}, {1, 0, 0}, {0, 0.5, 0},
390 {1./3., 1./3., 0}, {0.5, 0.5, 0}, {0, 1, 0},
391 {0, 0, 1}, {0.5, 0, 1}, {1, 0, 1}, {0, 0.5, 1},
392 {1./3., 1./3., 1}, {0.5, 0.5, 1}, {0, 1, 1}
394 const int hex_e[3][8] =
396 {0, 1, 4, 3, 7, 8, 11, 10},
397 {1, 2, 5, 4, 8, 9, 12, 11},
398 {3, 4, 5, 6, 10, 11, 12, 13}
401 for (
int j = 0; j < Nvert; j++)
405 for (
int j = 0; j < NEsplit; j++)
407 int attribute = j + 1;
415 for (
int k = 0; k <
dim; k++)
417 for (
int j = 0; j < npt; j++)
429 const double hex_v[23][3] =
431 {0.0000, 0.0000, 0.0000}, {0.5000, 0.0000, 0.0000},
432 {0.0000, 0.0000, 0.5000}, {0.3333, 0.0000, 0.3333},
433 {0.0000, 0.5000, 0.0000}, {0.3333, 0.3333, 0.0000},
434 {0.0000, 0.3333, 0.3333}, {0.2500, 0.2500, 0.2500},
435 {1.0000, 0.0000, 0.0000}, {0.5000, 0.0000, 0.5000},
436 {0.5000, 0.5000, 0.0000}, {0.3333, 0.3333, 0.3333},
437 {0.0000, 1.0000, 0.0000}, {0.0000, 0.5000, 0.5000},
438 {0.0000, 0.0000, 1.0000}, {1.0000, 0.5000, 0.0000},
439 {0.6667, 0.3333, 0.3333}, {0.6667, 0.6667, 0.0000},
440 {0.5000, 0.5000, 0.2500}, {1.0000, 1.0000, 0.0000},
441 {0.5000, 0.5000, 0.5000}, {0.5000, 1.0000, 0.0000},
442 {0.3333, 0.6667, 0.3333}
444 const int hex_e[8][8] =
446 {2, 3, 1, 0, 6, 7, 5, 4}, {3, 9, 8, 1, 7, 11, 10, 5},
447 {7, 11, 10, 5, 6, 13, 12, 4}, {2, 14, 9, 3, 6, 13, 11, 7},
448 {9, 16, 15, 8, 11, 18, 17, 10}, {16, 20, 19, 15, 18, 22, 21, 17},
449 {18, 22, 21, 17, 11, 13, 12, 10}, {9, 14, 20, 16, 11, 13, 22, 18}
452 for (
int j = 0; j < Nvert; j++)
456 for (
int j = 0; j < NEsplit; j++)
458 int attribute = j + 1;
466 for (
int k = 0; k <
dim; k++)
468 for (
int j = 0; j < npt; j++)
501 MFEM_ABORT(
"Unsupported geometry type.");
504 for (
int i = 0; i < NEsplit; i++)
519 const int NEsplit = meshin->
GetNE();
522 pts_cnt = NEsplit * dof_cnt;
527 MFEM_VERIFY(tbe != NULL,
"TensorBasis FiniteElement expected.");
535 MFEM_ASSERT(irule->
GetNPoints() == pts_cnt,
"IntegrationRule does not have"
536 "the correct number of points.");
539 for (
int i = 0; i < NEsplit; i++)
542 nodesplit->GetSubVector(xdofs, posV);
543 for (
int j = 0; j < dof_cnt; j++)
545 for (
int d = 0; d <
dim; d++)
547 irlist(pts_cnt * d + pt_id) = pos(dof_map[j], d);
549 irule->
IntPoint(pt_id).
x = irlist(pt_id);
550 irule->
IntPoint(pt_id).
y = irlist(pts_cnt + pt_id);
553 irule->
IntPoint(pt_id).
z = irlist(2*pts_cnt + pt_id);
571 const int pts_el = std::pow(dof_1D,
dim);
573 node_vals.
SetSize(vdim * pts_cnt);
576 int gsl_mesh_pt_index = 0;
578 for (
int e = 0; e < NE; e++)
582 bool el_to_split =
true;
605 MFEM_ABORT(
"Unsupported geometry type.");
612 for (
int i = 0; i < ir_split_temp->
GetNPoints(); i++)
616 for (
int d = 0; d < vdim; d++)
618 node_vals(pts_cnt*d + gsl_mesh_pt_index) = locval(d);
625 const int dof_cnt_split = fe->
GetDof();
629 MFEM_VERIFY(tbe != NULL,
"TensorBasis FiniteElement expected.");
632 if (dm.
Size() > 0) { dof_map = dm; }
633 else {
for (
int i = 0; i < dof_cnt_split; i++) { dof_map[i] = i; } }
636 Vector posV(pos.
Data(), dof_cnt_split * vdim);
641 for (
int j = 0; j < dof_cnt_split; j++)
643 for (
int d = 0; d < vdim; d++)
645 node_vals(pts_cnt * d + gsl_mesh_pt_index) = pos(dof_map[j], d);
677 struct gslib::array *outpt =
new gslib::array;
678 struct out_pt {
double r[3];
uint index, el, proc; };
680 array_init(
struct out_pt, outpt, nptsend);
682 pt = (
struct out_pt *)outpt->ptr;
689 for (
int d = 0; d <
dim; ++d)
700 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
704 pt = (
struct out_pt *)outpt->ptr;
709 const int elem = pt->el;
738 for (
int d = 0; d <
dim; d++)
740 pt->r[d] = mfem_ref(d);
746 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
750 pt = (
struct out_pt *)outpt->ptr;
754 for (
int d = 0; d <
dim; d++)
794 ip.
Set2(mfem_ref.GetData());
795 if (dim == 3) { ip.
z = mfem_ref(2); }
811 if (fec_h1 && gf_order == mesh_order &&
833 int borderPts = indl2.
Size();
835 MPI_Allreduce(MPI_IN_PLACE, &borderPts, 1, MPI_INT, MPI_SUM,
gsl_comm->c);
837 if (borderPts == 0) {
return; }
841 int gf_order_h1 = std::max(gf_order, 1);
847 if (
avgtype == AvgType::ARITHMETIC)
851 else if (
avgtype == AvgType::HARMONIC)
857 MFEM_ABORT(
"Invalid averaging type.");
860 if (gf_order_h1 == mesh_order)
870 for (
int j = 0; j < ncomp; j++)
872 for (
int i = 0; i < indl2.
Size(); i++)
875 indl2[i] + j*points_cnt:
877 field_out(idx) = field_out_l2(idx);
891 points_fld = field_in.
Size() / ncomp,
894 field_out.
SetSize(points_cnt*ncomp);
897 for (
int i = 0; i < ncomp; i++)
899 const int dataptrin = i*points_fld,
903 field_in_scalar.NewDataAndSize(field_in.
GetData()+dataptrin, points_fld);
907 for (
int j = 0; j < points_fld; j++)
909 field_in_scalar(j) = field_in(i + j*ncomp);
916 findpts_eval_2(field_out.
GetData()+dataptrout,
sizeof(double),
925 findpts_eval_3(field_out.
GetData()+dataptrout,
sizeof(double),
935 Vector field_out_temp = field_out;
936 for (
int i = 0; i < ncomp; i++)
940 field_out(i + j*ncomp) = field_out_temp(j + i*points_cnt);
968 for (
int i = 0; i < ncomp; i++)
970 field_out(index + i*npt) = localval(i);
975 for (
int i = 0; i < ncomp; i++)
977 field_out(index*ncomp + i) = localval(i);
992 struct gslib::array *outpt =
new gslib::array;
993 struct out_pt {
double r[3], ival;
uint index, el, proc; };
995 array_init(
struct out_pt, outpt, nptsend);
997 pt = (
struct out_pt *)outpt->ptr;
1009 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1015 pt = (
struct out_pt *)outpt->ptr;
1020 pt->ival = field_in.
GetValue(pt->el, ip, 1);
1025 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1027 pt = (
struct out_pt *)outpt->ptr;
1030 field_out(pt->index) = pt->ival;
1040 pt = (
struct out_pt *)outpt->ptr;
1041 Vector vec_int_vals(npt*ncomp);
1046 Vector localval(vec_int_vals.GetData()+
index*ncomp, ncomp);
1052 struct gslib::array *savpt =
new gslib::array;
1055 array_init(
struct sav_pt, savpt, npt);
1057 spt = (
struct sav_pt *)savpt->ptr;
1058 pt = (
struct out_pt *)outpt->ptr;
1061 spt->index = pt->index;
1062 spt->proc = pt->proc;
1070 struct gslib::array *sendpt =
new gslib::array;
1071 struct send_pt {
double ival;
uint index, proc; };
1072 struct send_pt *sdpt;
1073 for (
int j = 0; j < ncomp; j++)
1075 array_init(
struct send_pt, sendpt, npt);
1077 spt = (
struct sav_pt *)savpt->ptr;
1078 sdpt = (
struct send_pt *)sendpt->ptr;
1081 sdpt->index = spt->index;
1082 sdpt->proc = spt->proc;
1083 sdpt->ival = vec_int_vals(j +
index*ncomp);
1087 sarray_transfer(
struct send_pt, sendpt, proc, 1,
cr);
1088 sdpt = (
struct send_pt *)sendpt->ptr;
1089 for (
int index = 0; index < static_cast<int>(sendpt->n);
index++)
1092 sdpt->index + j*nptorig :
1093 sdpt->index*ncomp + j;
1094 field_out(idx) = sdpt->ival;
1108 const double bb_t,
const double newt_tol,
1111 MFEM_VERIFY(m.
GetNodes() != NULL,
"Mesh nodes are required.");
1112 MFEM_VERIFY(!(m.
GetNodes()->FESpace()->IsVariableOrder()),
1113 "Variable order mesh is not currently supported.");
1122 unsigned dof1D = fe->
GetOrder() + 1;
1148 MFEM_ASSERT(meshid>=0,
" The ID should be greater than or equal to 0.");
1151 NEtot = pts_cnt/(int)pow(dof1D,
dim);
1166 unsigned nr[2] = { dof1D, dof1D };
1167 unsigned mr[2] = { 2*dof1D, 2*dof1D };
1170 pts_cnt, pts_cnt, npt_max, newt_tol,
1175 unsigned nr[3] = { dof1D, dof1D, dof1D };
1176 unsigned mr[3] = { 2*dof1D, 2*dof1D, 2*dof1D };
1177 double *
const elx[3] =
1180 pts_cnt, pts_cnt, npt_max, newt_tol,
1189 int point_pos_ordering)
1191 MFEM_VERIFY(
setupflag,
"Use OversetFindPointsGSLIB::Setup before "
1193 MFEM_VERIFY(
overset,
" Please setup FindPoints for overlapping grids.");
1195 unsigned int match = 0;
1203 auto xvFill = [&](
const double *xv_base[],
unsigned xv_stride[],
int dim)
1205 for (
int d = 0; d <
dim; d++)
1210 xv_stride[d] =
sizeof(double);
1214 xv_base[d] = point_pos.
GetData() + d;
1215 xv_stride[d] = dim*
sizeof(double);
1221 const double *xv_base[2];
1222 unsigned xv_stride[2];
1223 xvFill(xv_base, xv_stride, dim);
1230 point_id.
GetData(),
sizeof(
unsigned int), &match,
1235 const double *xv_base[3];
1236 unsigned xv_stride[3];
1237 xvFill(xv_base, xv_stride, dim);
1244 point_id.
GetData(),
sizeof(
unsigned int), &match,
1254 for (
int d = 0; d <
dim; d++) {
gsl_ref(i*dim + d) = -1.; }
1267 int point_pos_ordering)
1269 FindPoints(point_pos, point_id, point_pos_ordering);
1276 #endif // MFEM_USE_GSLIB
int GetNPoints() const
Returns the number of the points in the integration rule.
Abstract class for all finite elements.
virtual void Interpolate(const GridFunction &field_in, Vector &field_out)
Geometry::Type GetGeometryType() const
Ordering::Type GetOrdering() const
Return the ordering method.
int Size() const
Return the logical size of the array.
Array< unsigned int > gsl_elem
Class for an integration rule - an Array of IntegrationPoint.
Class for grid function - Vector with associated FE space.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
virtual ~FindPointsGSLIB()
void FindPoints(const Vector &point_pos, int point_pos_ordering=Ordering::byNODES)
virtual void GetVectorValue(int i, const IntegrationPoint &ip, Vector &val) const
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
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
T * GetData()
Returns the data.
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
virtual void SetupSplitMeshes()
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
void Interpolate(const Vector &point_pos, Array< unsigned int > &point_id, const GridFunction &field_in, Vector &field_out, int point_pos_ordering=Ordering::byNODES)
int GetNE() const
Returns number of elements.
double * GetData() const
Return a pointer to the beginning of the Vector data.
Array< unsigned int > gsl_proc
Array< Mesh * > mesh_split
void DeleteAll()
Delete the whole array.
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
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
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
const Element * GetElement(int i) const
void Set2(const double x1, const double x2)
virtual void SetNodalFESpace(FiniteElementSpace *nfes)
int GetVDim() const
Returns vector dimension.
FiniteElementSpace * FESpace()
Array< int > split_element_index
Array< FiniteElementSpace * > fes_rst_map
void Set3(const double x1, const double x2, const double x3)
Array< unsigned int > gsl_code
double * Data() const
Returns the matrix data array.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
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)
struct gslib::findpts_data_2 * fdata2D
const Array< int > & GetDofMap() const
Get an Array<int> that maps lexicographically ordered indices to the indices of the respective nodes/...
Class for integration point with weight.
const FiniteElementSpace * GetNodalFESpace() const
Array< int > split_element_map
void Destroy()
Destroy a vector.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int index(int i, int j, int nx, int ny)
struct gslib::comm * gsl_comm
FiniteElementCollection * fec_map_lin
const FiniteElementCollection * FEColl() const
void GetNodes(Vector &node_coord) const
Vector coefficient defined by a vector GridFunction.
Arbitrary order H1-conforming (continuous) finite elements.
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)
virtual void InterpolateH1(const GridFunction &field_in, Vector &field_out)
Use GSLIB for communication and interpolation.
virtual double GetValue(int i, const IntegrationPoint &ip, int vdim=1) const
Arbitrary order "L2-conforming" discontinuous finite elements.