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 const int meshOrder = m.
GetNodes()->FESpace()->GetMaxElementOrder();
119 unsigned dof1D = meshOrder + 1;
154 NEtot = pts_cnt/(int)pow(dof1D,
dim);
158 unsigned nr[2] = { dof1D, dof1D };
159 unsigned mr[2] = { 2*dof1D, 2*dof1D };
162 pts_cnt, pts_cnt, npt_max, newt_tol);
166 unsigned nr[3] = { dof1D, dof1D, dof1D };
167 unsigned mr[3] = { 2*dof1D, 2*dof1D, 2*dof1D };
168 double *
const elx[3] =
171 pts_cnt, pts_cnt, npt_max, newt_tol);
177 int point_pos_ordering)
179 MFEM_VERIFY(
setupflag,
"Use FindPointsGSLIB::Setup before finding points.");
187 auto xvFill = [&](
const double *xv_base[],
unsigned xv_stride[])
189 for (
int d = 0; d <
dim; d++)
194 xv_stride[d] =
sizeof(double);
198 xv_base[d] = point_pos.
GetData() + d;
199 xv_stride[d] =
dim*
sizeof(double);
205 const double *xv_base[2];
206 unsigned xv_stride[2];
207 xvFill(xv_base, xv_stride);
217 const double *xv_base[3];
218 unsigned xv_stride[3];
219 xvFill(xv_base, xv_stride);
246 int point_pos_ordering,
const double bb_t,
247 const double newt_tol,
const int npt_max)
251 Setup(m, bb_t, newt_tol, npt_max);
258 int point_pos_ordering)
266 int point_pos_ordering)
290 for (
int i = 0; i < 4; i++)
310 const double quad_v[7][2] =
312 {0, 0}, {0.5, 0}, {1, 0}, {0, 0.5},
313 {1./3., 1./3.}, {0.5, 0.5}, {0, 1}
315 const int quad_e[3][4] =
317 {0, 1, 4, 3}, {1, 2, 5, 4}, {3, 4, 5, 6}
320 for (
int j = 0; j < Nvert; j++)
324 for (
int j = 0; j < NEsplit; j++)
326 int attribute = j + 1;
334 for (
int k = 0; k <
dim; k++)
336 for (
int j = 0; j < npt; j++)
355 const double hex_v[15][3] =
357 {0, 0, 0.}, {1, 0., 0.}, {0., 1., 0.}, {0, 0., 1.},
358 {0.5, 0., 0.}, {0.5, 0.5, 0.}, {0., 0.5, 0.},
359 {0., 0., 0.5}, {0.5, 0., 0.5}, {0., 0.5, 0.5},
360 {1./3., 0., 1./3.}, {1./3., 1./3., 1./3.}, {0, 1./3., 1./3.},
361 {1./3., 1./3., 0}, {0.25, 0.25, 0.25}
363 const int hex_e[4][8] =
365 {7, 10, 4, 0, 12, 14, 13, 6},
366 {10, 8, 1, 4, 14, 11, 5, 13},
367 {14, 11, 5, 13, 12, 9, 2, 6},
368 {7, 3, 8, 10, 12, 9, 11, 14}
371 for (
int j = 0; j < Nvert; j++)
375 for (
int j = 0; j < NEsplit; j++)
377 int attribute = j + 1;
385 for (
int k = 0; k <
dim; k++)
387 for (
int j = 0; j < npt; j++)
399 const double hex_v[14][3] =
401 {0, 0, 0}, {0.5, 0, 0}, {1, 0, 0}, {0, 0.5, 0},
402 {1./3., 1./3., 0}, {0.5, 0.5, 0}, {0, 1, 0},
403 {0, 0, 1}, {0.5, 0, 1}, {1, 0, 1}, {0, 0.5, 1},
404 {1./3., 1./3., 1}, {0.5, 0.5, 1}, {0, 1, 1}
406 const int hex_e[3][8] =
408 {0, 1, 4, 3, 7, 8, 11, 10},
409 {1, 2, 5, 4, 8, 9, 12, 11},
410 {3, 4, 5, 6, 10, 11, 12, 13}
413 for (
int j = 0; j < Nvert; j++)
417 for (
int j = 0; j < NEsplit; j++)
419 int attribute = j + 1;
427 for (
int k = 0; k <
dim; k++)
429 for (
int j = 0; j < npt; j++)
441 const double hex_v[23][3] =
443 {0.0000, 0.0000, 0.0000}, {0.5000, 0.0000, 0.0000},
444 {0.0000, 0.0000, 0.5000}, {0.3333, 0.0000, 0.3333},
445 {0.0000, 0.5000, 0.0000}, {0.3333, 0.3333, 0.0000},
446 {0.0000, 0.3333, 0.3333}, {0.2500, 0.2500, 0.2500},
447 {1.0000, 0.0000, 0.0000}, {0.5000, 0.0000, 0.5000},
448 {0.5000, 0.5000, 0.0000}, {0.3333, 0.3333, 0.3333},
449 {0.0000, 1.0000, 0.0000}, {0.0000, 0.5000, 0.5000},
450 {0.0000, 0.0000, 1.0000}, {1.0000, 0.5000, 0.0000},
451 {0.6667, 0.3333, 0.3333}, {0.6667, 0.6667, 0.0000},
452 {0.5000, 0.5000, 0.2500}, {1.0000, 1.0000, 0.0000},
453 {0.5000, 0.5000, 0.5000}, {0.5000, 1.0000, 0.0000},
454 {0.3333, 0.6667, 0.3333}
456 const int hex_e[8][8] =
458 {2, 3, 1, 0, 6, 7, 5, 4}, {3, 9, 8, 1, 7, 11, 10, 5},
459 {7, 11, 10, 5, 6, 13, 12, 4}, {2, 14, 9, 3, 6, 13, 11, 7},
460 {9, 16, 15, 8, 11, 18, 17, 10}, {16, 20, 19, 15, 18, 22, 21, 17},
461 {18, 22, 21, 17, 11, 13, 12, 10}, {9, 14, 20, 16, 11, 13, 22, 18}
464 for (
int j = 0; j < Nvert; j++)
468 for (
int j = 0; j < NEsplit; j++)
470 int attribute = j + 1;
478 for (
int k = 0; k <
dim; k++)
480 for (
int j = 0; j < npt; j++)
513 MFEM_ABORT(
"Unsupported geometry type.");
516 for (
int i = 0; i < NEsplit; i++)
531 const int NEsplit = meshin->
GetNE();
534 pts_cnt = NEsplit * dof_cnt;
539 MFEM_VERIFY(tbe != NULL,
"TensorBasis FiniteElement expected.");
547 MFEM_ASSERT(irule->
GetNPoints() == pts_cnt,
"IntegrationRule does not have" 548 "the correct number of points.");
551 for (
int i = 0; i < NEsplit; i++)
554 nodesplit->GetSubVector(xdofs, posV);
555 for (
int j = 0; j < dof_cnt; j++)
557 for (
int d = 0; d <
dim; d++)
559 irlist(pts_cnt * d + pt_id) = pos(dof_map[j], d);
561 irule->
IntPoint(pt_id).
x = irlist(pt_id);
562 irule->
IntPoint(pt_id).
y = irlist(pts_cnt + pt_id);
565 irule->
IntPoint(pt_id).
z = irlist(2*pts_cnt + pt_id);
578 const int vdim = fes->
GetVDim();
583 const int dof_1D = maxOrder+1;
584 const int pts_el = std::pow(dof_1D,
dim);
586 node_vals.
SetSize(vdim * pts_cnt);
589 int gsl_mesh_pt_index = 0;
591 for (
int e = 0; e < NE; e++)
595 bool el_to_split =
true;
624 MFEM_ABORT(
"Unsupported geometry type.");
631 for (
int i = 0; i < ir_split_temp->
GetNPoints(); i++)
635 for (
int d = 0; d < vdim; d++)
637 node_vals(pts_cnt*d + gsl_mesh_pt_index) = locval(d);
644 const int dof_cnt_split = fe->
GetDof();
648 MFEM_VERIFY(tbe != NULL,
"TensorBasis FiniteElement expected.");
651 if (dm.
Size() > 0) { dof_map = dm; }
652 else {
for (
int i = 0; i < dof_cnt_split; i++) { dof_map[i] = i; } }
655 Vector posV(pos.
Data(), dof_cnt_split * vdim);
660 for (
int j = 0; j < dof_cnt_split; j++)
662 for (
int d = 0; d < vdim; d++)
664 node_vals(pts_cnt * d + gsl_mesh_pt_index) = pos(dof_map[j], d);
696 struct gslib::array *outpt =
new gslib::array;
697 struct out_pt {
double r[3];
uint index, el, proc; };
699 array_init(
struct out_pt, outpt, nptsend);
701 pt = (
struct out_pt *)outpt->ptr;
708 for (
int d = 0; d <
dim; ++d)
719 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
723 pt = (
struct out_pt *)outpt->ptr;
728 const int elem = pt->el;
757 for (
int d = 0; d <
dim; d++)
759 pt->r[d] = mfem_ref(d);
765 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
769 pt = (
struct out_pt *)outpt->ptr;
773 for (
int d = 0; d <
dim; d++)
813 ip.
Set2(mfem_ref.GetData());
814 if (
dim == 3) { ip.
z = mfem_ref(2); }
830 if (fec_h1 && gf_order == mesh_order &&
853 int borderPts = indl2.
Size();
855 MPI_Allreduce(MPI_IN_PLACE, &borderPts, 1, MPI_INT, MPI_SUM,
gsl_comm->c);
857 if (borderPts == 0) {
return; }
861 int gf_order_h1 = std::max(gf_order, 1);
867 if (
avgtype == AvgType::ARITHMETIC)
871 else if (
avgtype == AvgType::HARMONIC)
877 MFEM_ABORT(
"Invalid averaging type.");
880 if (gf_order_h1 == mesh_order)
890 for (
int j = 0; j < ncomp; j++)
892 for (
int i = 0; i < indl2.
Size(); i++)
897 field_out(idx) = field_out_l2(idx);
909 for (
int e = 0; e < ind_fes.GetMesh()->GetNE(); e++)
913 ind_fes.Update(
false);
919 points_fld = field_in.
Size() / ncomp;
921 "FindPointsGSLIB::InterpolateH1: Inconsistent size of gsl_code");
926 for (
int i = 0; i < ncomp; i++)
928 const int dataptrin = i*points_fld,
936 for (
int j = 0; j < points_fld; j++)
938 field_in_scalar(j) = field_in(i + j*ncomp);
945 findpts_eval_2(field_out.
GetData()+dataptrout,
sizeof(double),
954 findpts_eval_3(field_out.
GetData()+dataptrout,
sizeof(double),
964 Vector field_out_temp = field_out;
965 for (
int i = 0; i < ncomp; i++)
969 field_out(i + j*ncomp) = field_out_temp(j + i*
points_cnt);
997 for (
int i = 0; i < ncomp; i++)
999 field_out(
index + i*npt) = localval(i);
1004 for (
int i = 0; i < ncomp; i++)
1006 field_out(
index*ncomp + i) = localval(i);
1021 struct gslib::array *outpt =
new gslib::array;
1022 struct out_pt {
double r[3], ival;
uint index, el, proc; };
1024 array_init(
struct out_pt, outpt, nptsend);
1026 pt = (
struct out_pt *)outpt->ptr;
1038 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1044 pt = (
struct out_pt *)outpt->ptr;
1049 pt->ival = field_in.
GetValue(pt->el, ip, 1);
1054 sarray_transfer(
struct out_pt, outpt, proc, 1,
cr);
1056 pt = (
struct out_pt *)outpt->ptr;
1059 field_out(pt->index) = pt->ival;
1069 pt = (
struct out_pt *)outpt->ptr;
1070 Vector vec_int_vals(npt*ncomp);
1075 Vector localval(vec_int_vals.GetData()+
index*ncomp, ncomp);
1081 struct gslib::array *savpt =
new gslib::array;
1084 array_init(
struct sav_pt, savpt, npt);
1086 spt = (
struct sav_pt *)savpt->ptr;
1087 pt = (
struct out_pt *)outpt->ptr;
1090 spt->index = pt->index;
1091 spt->proc = pt->proc;
1099 struct gslib::array *sendpt =
new gslib::array;
1100 struct send_pt {
double ival;
uint index, proc; };
1101 struct send_pt *sdpt;
1102 for (
int j = 0; j < ncomp; j++)
1104 array_init(
struct send_pt, sendpt, npt);
1106 spt = (
struct sav_pt *)savpt->ptr;
1107 sdpt = (
struct send_pt *)sendpt->ptr;
1110 sdpt->index = spt->index;
1111 sdpt->proc = spt->proc;
1112 sdpt->ival = vec_int_vals(j +
index*ncomp);
1116 sarray_transfer(
struct send_pt, sendpt, proc, 1,
cr);
1117 sdpt = (
struct send_pt *)sendpt->ptr;
1118 for (
int index = 0; index < static_cast<int>(sendpt->n);
index++)
1121 sdpt->index + j*nptorig :
1122 sdpt->index*ncomp + j;
1123 field_out(idx) = sdpt->ival;
1137 const double bb_t,
const double newt_tol,
1140 MFEM_VERIFY(m.
GetNodes() != NULL,
"Mesh nodes are required.");
1141 const int meshOrder = m.
GetNodes()->FESpace()->GetMaxElementOrder();
1150 unsigned dof1D = fe->
GetOrder() + 1;
1184 MFEM_ASSERT(meshid>=0,
" The ID should be greater than or equal to 0.");
1187 NEtot = pts_cnt/(int)pow(dof1D,
dim);
1202 unsigned nr[2] = { dof1D, dof1D };
1203 unsigned mr[2] = { 2*dof1D, 2*dof1D };
1206 pts_cnt, pts_cnt, npt_max, newt_tol,
1211 unsigned nr[3] = { dof1D, dof1D, dof1D };
1212 unsigned mr[3] = { 2*dof1D, 2*dof1D, 2*dof1D };
1213 double *
const elx[3] =
1216 pts_cnt, pts_cnt, npt_max, newt_tol,
1225 int point_pos_ordering)
1227 MFEM_VERIFY(
setupflag,
"Use OversetFindPointsGSLIB::Setup before " 1229 MFEM_VERIFY(
overset,
" Please setup FindPoints for overlapping grids.");
1231 unsigned int match = 0;
1239 auto xvFill = [&](
const double *xv_base[],
unsigned xv_stride[])
1241 for (
int d = 0; d <
dim; d++)
1246 xv_stride[d] =
sizeof(double);
1250 xv_base[d] = point_pos.
GetData() + d;
1251 xv_stride[d] =
dim*
sizeof(double);
1257 const double *xv_base[2];
1258 unsigned xv_stride[2];
1259 xvFill(xv_base, xv_stride);
1266 point_id.
GetData(),
sizeof(
unsigned int), &match,
1271 const double *xv_base[3];
1272 unsigned xv_stride[3];
1273 xvFill(xv_base, xv_stride);
1280 point_id.
GetData(),
sizeof(
unsigned int), &match,
1305 int point_pos_ordering)
1307 FindPoints(point_pos, point_id, point_pos_ordering);
1314 #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.
void NewDataAndSize(double *d, int s)
Set the Vector data and size, deleting the old data, if owned.
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)
int Dimension() const
Dimension of the reference space used within the elements.
void SetSize(int s)
Resize the vector to size s.
Array< GridFunction * > gf_rst_map
void SetElementOrder(int i, int p)
Sets the order of the i'th finite element.
static Mesh MakeCartesian3D(int nx, int ny, int nz, Element::Type type, double sx=1.0, double sy=1.0, double sz=1.0, bool sfc_ordering=true)
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
Return pointer to the i'th element object.
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
int GetMaxElementOrder() const
Return the maximum polynomial order.
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 indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
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)
static Mesh MakeCartesian2D(int nx, int ny, Element::Type type, bool generate_edges=false, double sx=1.0, double sy=1.0, bool sfc_ordering=true)
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.
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
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.