73 for (
int d = 0; d <
dim; d++) { res += std::pow(x(d),
func_order); }
80 for (
int i = 1; i < F.
Size(); i++) { F(i) = (i+1)*F(0); }
83int main (
int argc,
char *argv[])
92 const char *mesh_file =
"../../data/rt-2d-q3.mesh";
94 int mesh_poly_deg = 3;
97 bool visualization =
false;
100 bool search_on_rank_0 =
false;
101 bool hrefinement =
false;
102 int point_ordering = 0;
104 const char *devopt =
"cpu";
105 int randomization = 0;
107 bool surface =
false;
108 double surf_aabb_sz_inc = 0.0;
112 args.
AddOption(&mesh_file,
"-m",
"--mesh",
113 "Mesh file to use.");
115 "Finite element order (polynomial degree).");
116 args.
AddOption(&mesh_poly_deg,
"-mo",
"--mesh-order",
117 "Polynomial degree of mesh finite element space.");
118 args.
AddOption(&rs_levels,
"-rs",
"--refine-serial",
119 "Number of times to refine the mesh uniformly in serial.");
120 args.
AddOption(&rp_levels,
"-rp",
"--refine-parallel",
121 "Number of times to refine the mesh uniformly in parallel.");
122 args.
AddOption(&fieldtype,
"-ft",
"--field-type",
123 "Field type: 0 - H1, 1 - L2, 2 - H(div), 3 - H(curl).");
125 "Number of components for H1 or L2 GridFunctions");
126 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
127 "--no-visualization",
128 "Enable or disable GLVis visualization.");
129 args.
AddOption(&search_on_rank_0,
"-sr0",
"--search-on-r0",
"-no-sr0",
131 "Enable search only on rank 0 (disable to search points on all tasks). "
132 "All points added by other procs are ignored.");
133 args.
AddOption(&hrefinement,
"-hr",
"--h-refinement",
"-no-hr",
135 "Do random h refinements to mesh (does not work for pyramids).");
136 args.
AddOption(&point_ordering,
"-po",
"--point-ordering",
137 "Ordering of points to be found."
138 "0 (default): byNodes, 1: byVDIM");
139 args.
AddOption(&gf_ordering,
"-gfo",
"--gridfunc-ordering",
140 "Ordering of fespace that will be used for grid function to be interpolated. "
141 "0 (default): byNodes, 1: byVDIM");
142 args.
AddOption(&devopt,
"-d",
"--device",
143 "Device configuration string, see Device::Configure().");
144 args.
AddOption(&randomization,
"-random",
"--random",
145 "0: generate points randomly in the bounding box of domain, "
146 "1: generate points randomly inside each element in mesh.");
148 "# points / rank initialized on entire mesh (random = 0) or every element (random = 1).");
149 args.
AddOption(&surface,
"-surf",
"--surface",
"-no-surf",
151 "Extract surface mesh from volume mesh.");
152 args.
AddOption(&surf_aabb_sz_inc,
"-sabs",
"--surface-aabb-size-inc",
153 "Absolute AABB expansion applied to surface-search "
154 "axis-aligned bounding boxes in FindPointsGSLIB surface meshes.");
163 bool cpu_mode = strcmp(devopt,
"cpu")==0;
165 if (myid == 0) { device.
Print();}
170 Mesh *input_mesh =
new Mesh(mesh_file, 1, 1,
false);
171 Mesh *mesh = surface ? nullptr : input_mesh;
175 "--surface requires a mesh with boundary attributes.");
185 cout <<
"Mesh curvature of the original mesh: ";
187 else { cout <<
"(NONE)"; }
193 MFEM_VERIFY(mesh_poly_deg > 0,
"The order of the mesh must be positive.");
197 cout <<
"--- Generating points for:\n"
198 <<
"x in [" << pos_min(0) <<
", " << pos_max(0) <<
"]\n";
201 cout <<
"y in [" << pos_min(1) <<
", " << pos_max(1) <<
"]" << std::endl;
205 cout <<
"z in [" << pos_min(2) <<
", " << pos_max(2) <<
"]" << std::endl;
211 ParMesh pmesh(MPI_COMM_WORLD, *mesh,
nullptr,
212 (
dim == 1 && sdim == 3) ? 0 : 1);
213 if (randomization == 0)
216 if (surface) {
delete input_mesh; }
236 cout <<
"Mesh curvature of the curved mesh: " << fecm.
Name() << endl;
241 MFEM_VERIFY(ncomp > 0,
"Invalid number of components.");
247 if (myid == 0) { cout <<
"H1-GridFunction" << std::endl; }
249 else if (fieldtype == 1)
252 if (myid == 0) { cout <<
"L2-GridFunction" << std::endl; }
254 else if (fieldtype == 2)
259 if (myid == 0) { cout <<
"H(div)-GridFunction" << std::endl; }
261 else if (fieldtype == 3)
266 if (myid == 0) { cout <<
"H(curl)-GridFunction" << std::endl; }
270 if (myid == 0) { MFEM_ABORT(
"Invalid FECollection type."); }
289 cout <<
"Unable to connect to GLVis server at "
290 <<
vishost <<
':' << 19916 << endl;
295 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
297 sout <<
"solution\n" << pmesh << field_vals;
298 if (sdim == 2) { sout <<
"keys RmjA*****\n"; }
299 if (sdim == 3) { sout <<
"keys mA\n"; }
300 sout <<
"window_title 'Solution'\n"
301 <<
"window_geometry "
302 << 0 <<
" " << 0 <<
" " << 400 <<
" " << 400 <<
"\n";
312 int npt_face_per_elem = 4;
313 int npt_total_face = 0;
314 if (randomization == 0)
320 for (
int i = 0; i < pts_cnt; i++)
322 for (
int d = 0; d < sdim; d++)
326 vxyz(i + d*pts_cnt) =
327 pos_min(d) + vxyz(i + d*pts_cnt) * (pos_max(d) - pos_min(d));
332 pos_min(d) + vxyz(i*sdim + d) * (pos_max(d) - pos_min(d));
339 pts_cnt = npt*nelemglob;
341 for (
int i=0; i<mesh->
GetNE(); i++)
346 for (
int j=0; j<npt; j++)
350 if (j < npt_face_per_elem)
357 for (
int d=0; d<sdim; d++)
361 vxyz(j + npt*i + d*npt*nelemglob) = pos_i(d);
365 vxyz((j + npt*i)*sdim + d) = pos_i(d);
371 if ( (myid != 0) && (search_on_rank_0) )
377 MPI_Allreduce(MPI_IN_PLACE, &npt_total_face, 1, MPI_INT, MPI_SUM,
381 Vector interp_vals(pts_cnt*vec_dim);
383 if (surface && surf_aabb_sz_inc > 0.0)
385 Vector bb_size({surf_aabb_sz_inc});
409 auto h_code_out = code_out.
HostRead();
410 auto h_task_id_out = task_id_out.
HostRead();
411 auto h_dist_p_out = dist_p_out.
HostRead();
413 int face_pts = 0, not_found = 0, found_loc = 0, found_away = 0;
414 double error = 0.0, max_error = 0.0, max_dist = 0.0;
417 for (
int j = 0; j < vec_dim; j++)
419 for (
int i = 0; i < pts_cnt; i++)
423 (h_task_id_out[i] == (unsigned)myid) ? found_loc++ : found_away++;
426 if (h_code_out[i] < 2)
428 for (
int d = 0; d < sdim; d++)
431 vxyz(d*pts_cnt + i) :
434 Vector exact_val(vec_dim);
437 fabs(exact_val(j) - interp_vals[i + j*pts_cnt]) :
438 fabs(exact_val(j) - interp_vals[i*vec_dim + j]);
439 max_error = std::max(max_error, error);
440 max_dist = std::max(max_dist, h_dist_p_out[i]);
441 if (h_code_out[i] == 1 && j == 0) { face_pts++; }
443 else {
if (j == 0) { not_found++; } }
447 MPI_Allreduce(MPI_IN_PLACE, &found_loc, 1, MPI_INT, MPI_SUM,
449 MPI_Allreduce(MPI_IN_PLACE, &found_away, 1, MPI_INT, MPI_SUM,
451 MPI_Allreduce(MPI_IN_PLACE, &face_pts, 1, MPI_INT, MPI_SUM, pfespace.
GetComm());
452 MPI_Allreduce(MPI_IN_PLACE, ¬_found, 1, MPI_INT, MPI_SUM,
454 MPI_Allreduce(MPI_IN_PLACE, &max_error, 1, MPI_DOUBLE, MPI_MAX,
456 MPI_Allreduce(MPI_IN_PLACE, &max_dist, 1, MPI_DOUBLE, MPI_MAX,
458 MPI_Allreduce(MPI_IN_PLACE, &error, 1, MPI_DOUBLE, MPI_SUM, pfespace.
GetComm());
463 cout << setprecision(16)
464 <<
"Total number of elements: " << nelemglob
465 <<
"\nTotal number of procs: " << num_procs
466 <<
"\nSearched total points: " << (search_on_rank_0 ? pts_cnt :
468 <<
"\nFound locally on ranks: " << found_loc
469 <<
"\nFound on other tasks: " << found_away
470 <<
"\nPoints not found: " << not_found
471 <<
"\nPoints on faces: " << face_pts <<
" out of "
473 <<
"\nMax interp error: " << max_error
474 <<
"\nMax dist^2 (of found): " << max_dist
481 if (randomization != 0)
484 if (surface) {
delete input_mesh; }
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
int Size() const
Return the logical size of the array.
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
void Print(std::ostream &os=mfem::out)
Print the configuration of the MFEM virtual device object.
FindPointsGSLIB can robustly evaluate a GridFunction on an arbitrary collection of points....
virtual const Vector & GetDist() const
Return distance between the sought and the found point in physical space.
void FindPoints(const Vector &point_pos, int point_pos_ordering=Ordering::byNODES)
Searches positions given in physical space by point_pos.
void Setup(Mesh &m, const double bbox_rel_size_inc=0.1, const double newt_tol=1.0e-12, const int npt_max=256)
Preprocess the internal mesh in gslib.
virtual void Interpolate(const GridFunction &field_in, Vector &field_out)
Interpolation of field values at prescribed reference space positions.
virtual const Array< unsigned int > & GetCode() const
Return code for each point searched by FindPoints: inside element (0), element boundary (1),...
void SetupSurfWithAABBExpansion(Mesh &m, const Vector &aabb_sz_inc, const double newt_tol=1.0e-12)
Preprocess the surface mesh to compute data for FindPoints using absolute AABB expansion.
virtual const Array< unsigned int > & GetProc() const
Return MPI rank on which each point was found by FindPoints.
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...
ElementTransformation * GetElementTransformation(int i) const
static void GetRandomPoint(int GeomType, IntegrationPoint &ip)
Get a random point in the reference element specified by GeomType.
Arbitrary order H1-conforming (continuous) finite elements.
const char * Name() const override
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Class for integration point with weight.
Arbitrary order "L2-conforming" discontinuous finite elements.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Geometry::Type GetElementGeometry(int i) const
const FiniteElementSpace * GetNodalFESpace() const
int GetNE() const
Returns number of elements.
void GetBoundingBox(Vector &min, Vector &max, int ref=2)
Returns the minimum and maximum corners of the mesh bounding box.
int Dimension() const
Dimension of the reference space used within the elements.
void RandomRefinement(real_t prob, bool aniso=false, int nonconforming=-1, int nc_limit=0)
Refine each element with given probability. Uses GeneralRefinement.
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1, int pyr_type=1)
Set the curvature of the mesh nodes using the given polynomial degree.
int SpaceDimension() const
Dimension of the physical space containing the mesh.
void SetNodalGridFunction(GridFunction *nodes, bool make_owner=false)
void GetNodes(Vector &node_coord) const
long long GetGlobalNE() const
Return the total (global) number of elements.
void EnsureNCMesh(bool simplices_nonconforming=false)
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
static int WorldRank()
Return the MPI rank in MPI_COMM_WORLD.
static int WorldSize()
Return the size of MPI_COMM_WORLD.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
Arbitrary order H(curl)-conforming Nedelec finite elements.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
Class for parallel grid function.
void ProjectCoefficient(Coefficient &coeff, ProjectType type=ProjectType::DEFAULT) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Class for parallel meshes.
void SetNodalFESpace(FiniteElementSpace *nfes) override
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
static SubMesh CreateFromBoundary(const Mesh &parent, const Array< int > &boundary_attributes)
Create a surface SubMesh from its parent.
A general vector function coefficient.
void Randomize(int seed=0)
Set random values in the vector.
virtual const real_t * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
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 * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
real_t p(const Vector &x, real_t t)
double field_func(const Vector &x)
void F_exact(const Vector &p, Vector &F)