MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
pfindpts.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11//
12// ----------------------------------------------------------------------
13// Parallel Find Points Miniapp: Evaluate grid function in physical space
14// ----------------------------------------------------------------------
15//
16// This miniapp demonstrates the interpolation of a high-order grid function on
17// a set of points in physical-space. The miniapp is based on GSLIB-FindPoints,
18// which provides two key functionalities. First, for a given set of points in
19// the physical-space, it determines the computational coordinates (element
20// number, reference-space coordinates inside the element, and processor number
21// [in parallel]) for each point. Second, based on computational coordinates, it
22// interpolates a grid function in the given points. Inside GSLIB, computation
23// of the coordinates requires use of a Hash Table to identify the candidate
24// processor and element for each point, followed by the Newton's method to
25// determine the reference-space coordinates inside the candidate element.
26//
27// Compile with: make pfindpts
28//
29// Sample runs:
30// mpirun -np 2 pfindpts -m ../../data/rt-2d-p4-tri.mesh -o 8 -mo 4
31// mpirun -np 2 pfindpts -m ../../data/inline-tri.mesh -o 3
32// mpirun -np 2 pfindpts -m ../../data/inline-quad.mesh -o 3
33// mpirun -np 2 pfindpts -m ../../data/inline-quad.mesh -o 3 -po 1
34// mpirun -np 2 pfindpts -m ../../data/inline-quad.mesh -o 3 -po 1 -gfo 1 -nc 2
35// mpirun -np 2 pfindpts -m ../../data/inline-quad.mesh -o 3 -hr
36// mpirun -np 2 pfindpts -m ../../data/inline-tet.mesh -o 3
37// mpirun -np 2 pfindpts -m ../../data/inline-hex.mesh -o 3
38// mpirun -np 2 pfindpts -m ../../data/inline-wedge.mesh -o 3
39// mpirun -np 2 pfindpts -m ../../data/amr-quad.mesh -o 2
40// mpirun -np 2 pfindpts -m ../../data/rt-2d-q3.mesh -o 8 -mo 4 -ft 2
41// mpirun -np 2 pfindpts -m ../../data/inline-quad.mesh -ft 1 -sr0
42// mpirun -np 2 pfindpts -m ../../data/square-mixed.mesh -o 2 -mo 2
43// mpirun -np 2 pfindpts -m ../../data/square-mixed.mesh -o 2 -mo 2 -hr
44// mpirun -np 2 pfindpts -m ../../data/square-mixed.mesh -o 2 -mo 3 -ft 2
45// mpirun -np 2 pfindpts -m ../../data/fichera-mixed.mesh -o 3 -mo 2
46// mpirun -np 2 pfindpts -m ../../data/inline-pyramid.mesh -o 1 -mo 1
47// mpirun -np 2 pfindpts -m ../../data/tinyzoo-3d.mesh -o 1 -mo 1
48// Device runs:
49// mpirun -np 2 pfindpts -m ../../data/inline-quad.mesh -o 3 -mo 2 -random 1 -d debug
50// mpirun -np 2 pfindpts -m ../../data/amr-quad.mesh -rs 1 -o 4 -mo 2 -random 1 -npt 100 -d debug
51// mpirun -np 2 pfindpts -m ../../data/inline-hex.mesh -o 3 -mo 2 -random 1 -d debug
52
53
54#include "mfem.hpp"
55#include "general/forall.hpp"
57
58using namespace mfem;
59using namespace std;
60
62
63// Scalar function to project
64double field_func(const Vector &x)
65{
66 const int dim = x.Size();
67 double res = 0.0;
68 for (int d = 0; d < dim; d++) { res += std::pow(x(d), func_order); }
69 return res;
70}
71
72void F_exact(const Vector &p, Vector &F)
73{
74 F(0) = field_func(p);
75 for (int i = 1; i < F.Size(); i++) { F(i) = (i+1)*F(0); }
76}
77
78int main (int argc, char *argv[])
79{
80 // Initialize MPI and HYPRE.
81 Mpi::Init(argc, argv);
82 int num_procs = Mpi::WorldSize();
83 int myid = Mpi::WorldRank();
85
86 // Set the method's default parameters.
87 const char *mesh_file = "../../data/rt-2d-q3.mesh";
88 int order = 3;
89 int mesh_poly_deg = 3;
90 int rs_levels = 0;
91 int rp_levels = 0;
92 bool visualization = false;
93 int fieldtype = 0;
94 int ncomp = 1;
95 bool search_on_rank_0 = false;
96 bool hrefinement = false;
97 int point_ordering = 0;
98 int gf_ordering = 0;
99 const char *devopt = "cpu";
100 int randomization = 0;
101 int npt = 100; //points per proc
102 int visport = 19916;
103
104 // Parse command-line options.
105 OptionsParser args(argc, argv);
106 args.AddOption(&mesh_file, "-m", "--mesh",
107 "Mesh file to use.");
108 args.AddOption(&order, "-o", "--order",
109 "Finite element order (polynomial degree).");
110 args.AddOption(&mesh_poly_deg, "-mo", "--mesh-order",
111 "Polynomial degree of mesh finite element space.");
112 args.AddOption(&rs_levels, "-rs", "--refine-serial",
113 "Number of times to refine the mesh uniformly in serial.");
114 args.AddOption(&rp_levels, "-rp", "--refine-parallel",
115 "Number of times to refine the mesh uniformly in parallel.");
116 args.AddOption(&fieldtype, "-ft", "--field-type",
117 "Field type: 0 - H1, 1 - L2, 2 - H(div), 3 - H(curl).");
118 args.AddOption(&ncomp, "-nc", "--ncomp",
119 "Number of components for H1 or L2 GridFunctions");
120 args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
121 "--no-visualization",
122 "Enable or disable GLVis visualization.");
123 args.AddOption(&search_on_rank_0, "-sr0", "--search-on-r0", "-no-sr0",
124 "--no-search-on-r0",
125 "Enable search only on rank 0 (disable to search points on all tasks).");
126 args.AddOption(&hrefinement, "-hr", "--h-refinement", "-no-hr",
127 "--no-h-refinement",
128 "Do random h refinements to mesh (does not work for pyramids).");
129 args.AddOption(&point_ordering, "-po", "--point-ordering",
130 "Ordering of points to be found."
131 "0 (default): byNodes, 1: byVDIM");
132 args.AddOption(&gf_ordering, "-gfo", "--gridfunc-ordering",
133 "Ordering of fespace that will be used for grid function to be interpolated."
134 "0 (default): byNodes, 1: byVDIM");
135 args.AddOption(&devopt, "-d", "--device",
136 "Device configuration string, see Device::Configure().");
137 args.AddOption(&randomization, "-random", "--random",
138 "0: generate points randomly in the bounding box of domain,"
139 "1: generate points randomly inside each element in mesh.");
140 args.AddOption(&npt, "-npt", "--npt",
141 "# points per proc or element");
142 args.AddOption(&visport, "-p", "--send-port", "Socket for GLVis.");
143
144 args.Parse();
145 if (!args.Good())
146 {
147 args.PrintUsage(cout);
148 return 1;
149 }
150 if (myid == 0) { args.PrintOptions(cout); }
151
152 bool cpu_mode = strcmp(devopt,"cpu")==0;
153 Device device(devopt);
154 if (myid == 0) { device.Print();}
155
156 func_order = std::min(order, 2);
157
158 // Initialize and refine the starting mesh.
159 Mesh *mesh = new Mesh(mesh_file, 1, 1, false);
160 for (int lev = 0; lev < rs_levels; lev++) { mesh->UniformRefinement(); }
161 const int dim = mesh->Dimension();
162
163 if (mesh->GetNumGeometries(dim) != 1 ||
166 {
167 randomization = 0;
168 }
169
170 Vector xmin, xmax;
171 mesh->GetBoundingBox(xmin, xmax);
172
173 if (myid == 0)
174 {
175 cout << "Mesh curvature of the original mesh: ";
176 if (mesh->GetNodes()) { cout << mesh->GetNodes()->OwnFEC()->Name(); }
177 else { cout << "(NONE)"; }
178 cout << endl;
179 }
180
181 // Mesh bounding box (for the full serial mesh).
182 Vector pos_min, pos_max;
183 MFEM_VERIFY(mesh_poly_deg > 0, "The order of the mesh must be positive.");
184 mesh->GetBoundingBox(pos_min, pos_max, mesh_poly_deg);
185 if (myid == 0)
186 {
187 cout << "--- Generating equidistant point for:\n"
188 << "x in [" << pos_min(0) << ", " << pos_max(0) << "]\n"
189 << "y in [" << pos_min(1) << ", " << pos_max(1) << "]" << std::endl;
190 if (dim == 3)
191 {
192 cout << "z in [" << pos_min(2) << ", " << pos_max(2) << "]" << std::endl;
193 }
194 }
195
196 // Distribute the mesh.
197 if (hrefinement) { mesh->EnsureNCMesh(); }
198 ParMesh pmesh(MPI_COMM_WORLD, *mesh);
199 if (randomization == 0) { delete mesh; }
200 else
201 {
202 // we will need mesh nodal space later
203 if (mesh->GetNodes() == NULL) { mesh->SetCurvature(1); }
204 }
205 for (int lev = 0; lev < rp_levels; lev++) { pmesh.UniformRefinement(); }
206
207 // Random h-refinements to mesh
208 if (hrefinement) { pmesh.RandomRefinement(0.5); }
209
210 // Curve the mesh based on the chosen polynomial degree.
211 H1_FECollection fecm(mesh_poly_deg, dim);
212 ParFiniteElementSpace pfespace(&pmesh, &fecm, dim);
213 pmesh.SetNodalFESpace(&pfespace);
214 ParGridFunction x(&pfespace);
215 pmesh.SetNodalGridFunction(&x);
216 if (myid == 0)
217 {
218 cout << "Mesh curvature of the curved mesh: " << fecm.Name() << endl;
219 }
220
221 int nelemglob = pmesh.GetGlobalNE();
222
223 MFEM_VERIFY(ncomp > 0, "Invalid number of components.");
224 int vec_dim = ncomp;
225 FiniteElementCollection *fec = NULL;
226 if (fieldtype == 0)
227 {
228 fec = new H1_FECollection(order, dim);
229 if (myid == 0) { cout << "H1-GridFunction" << std::endl; }
230 }
231 else if (fieldtype == 1)
232 {
233 fec = new L2_FECollection(order, dim);
234 if (myid == 0) { cout << "L2-GridFunction" << std::endl; }
235 }
236 else if (fieldtype == 2)
237 {
238 fec = new RT_FECollection(order, dim);
239 ncomp = 1;
240 vec_dim = dim;
241 if (myid == 0) { cout << "H(div)-GridFunction" << std::endl; }
242 }
243 else if (fieldtype == 3)
244 {
245 fec = new ND_FECollection(order, dim);
246 ncomp = 1;
247 vec_dim = dim;
248 if (myid == 0) { cout << "H(curl)-GridFunction" << std::endl; }
249 }
250 else
251 {
252 if (myid == 0) { MFEM_ABORT("Invalid FECollection type."); }
253 }
254 ParFiniteElementSpace sc_fes(&pmesh, fec, ncomp, gf_ordering);
255 ParGridFunction field_vals(&sc_fes);
256
257 // Project the GridFunction using VectorFunctionCoefficient.
259 field_vals.ProjectCoefficient(F);
260
261 // Display the mesh and the field through glvis.
262 if (visualization)
263 {
264 char vishost[] = "localhost";
265 socketstream sout;
266 sout.open(vishost, visport);
267 if (!sout)
268 {
269 if (myid == 0)
270 {
271 cout << "Unable to connect to GLVis server at "
272 << vishost << ':' << visport << endl;
273 }
274 }
275 else
276 {
277 sout << "parallel " << num_procs << " " << myid << "\n";
278 sout.precision(8);
279 sout << "solution\n" << pmesh << field_vals;
280 if (dim == 2) { sout << "keys RmjA*****\n"; }
281 if (dim == 3) { sout << "keys mA\n"; }
282 sout << flush;
283 }
284 }
285
286 // Generate equidistant points in physical coordinates over the whole mesh.
287 // Note that some points might be outside, if the mesh is not a box. Note
288 // also that all tasks search the same points (not mandatory).
289 int pts_cnt = npt;
290 Vector vxyz;
291 vxyz.UseDevice(!cpu_mode);
292 int npt_face_per_elem = 4; // number of pts on el faces for randomization != 0
293 if (randomization == 0)
294 {
295 vxyz.SetSize(pts_cnt * dim);
296 vxyz.Randomize(myid+1);
297
298 // Scale based on min/max dimensions
299 for (int i = 0; i < pts_cnt; i++)
300 {
301 for (int d = 0; d < dim; d++)
302 {
303 if (point_ordering == Ordering::byNODES)
304 {
305 vxyz(i + d*pts_cnt) =
306 pos_min(d) + vxyz(i + d*pts_cnt) * (pos_max(d) - pos_min(d));
307 }
308 else
309 {
310 vxyz(i*dim + d) =
311 pos_min(d) + vxyz(i*dim + d) * (pos_max(d) - pos_min(d));
312 }
313 }
314 }
315 }
316 else // randomization == 1
317 {
318 pts_cnt = npt*nelemglob;
319 vxyz.SetSize(pts_cnt * dim);
320 for (int i=0; i<mesh->GetNE(); i++)
321 {
322 const FiniteElementSpace *s_fespace = mesh->GetNodalFESpace();
323 ElementTransformation *transf = s_fespace->GetElementTransformation(i);
324
325 Vector pos_ref1(npt*dim);
326 pos_ref1.Randomize((myid+1)*17.0);
327 for (int j=0; j<npt; j++)
328 {
330 ip.x = pos_ref1(j*dim + 0);
331 ip.y = pos_ref1(j*dim + 1);
332 if (dim == 3)
333 {
334 ip.z = pos_ref1(j*dim + 2);
335 }
336 if (j < npt_face_per_elem)
337 {
338 ip.x = 0.0; // force point to be on the face
339 }
340 Vector pos_i(dim);
341 transf->Transform(ip, pos_i);
342 for (int d=0; d<dim; d++)
343 {
344 if (point_ordering == Ordering::byNODES)
345 {
346 vxyz(j + npt*i + d*npt*nelemglob) = pos_i(d);
347 }
348 else
349 {
350 vxyz((j + npt*i)*dim + d) = pos_i(d);
351 }
352 }
353 }
354 }
355 }
356
357 if ( (myid != 0) && (search_on_rank_0) )
358 {
359 pts_cnt = 0;
360 vxyz.Destroy();
361 }
362
363 // Find and Interpolate FE function values on the desired points.
364 Vector interp_vals(pts_cnt*vec_dim);
365 FindPointsGSLIB finder(MPI_COMM_WORLD);
366 finder.Setup(pmesh);
368 // Enable GPU to CPU fallback for GPUData only if you must use an older
369 // version of GSLIB.
370 // finder.SetGPUtoCPUFallback(true);
371 finder.FindPoints(vxyz, point_ordering);
372
373 Array<unsigned int> code_out1 = finder.GetCode();
374 Array<unsigned int> el_out1 = finder.GetGSLIBElem();
375 Vector ref_rst1 = finder.GetGSLIBReferencePosition();
376 Vector ref_rst0 = finder.GetReferencePosition();
377 Vector dist1 = finder.GetDist();
378 Array<unsigned int> proc_out1 = finder.GetProc();
379
380 finder.Interpolate(field_vals, interp_vals);
381 if (interp_vals.UseDevice())
382 {
383 interp_vals.HostReadWrite();
384 }
385 vxyz.HostReadWrite();
386
387 Array<unsigned int> code_out = finder.GetCode();
388 Array<unsigned int> task_id_out = finder.GetProc();
389 Vector dist_p_out = finder.GetDist();
390 Vector rst = finder.GetReferencePosition();
391
392 int face_pts = 0, not_found = 0, found_loc = 0, found_away = 0;
393 double error = 0.0, max_error = 0.0, max_dist = 0.0;
394
395 Vector pos(dim);
396 for (int j = 0; j < vec_dim; j++)
397 {
398 for (int i = 0; i < pts_cnt; i++)
399 {
400 if (j == 0)
401 {
402 (task_id_out[i] == (unsigned)myid) ? found_loc++ : found_away++;
403 }
404
405 if (code_out[i] < 2)
406 {
407 for (int d = 0; d < dim; d++)
408 {
409 pos(d) = point_ordering == Ordering::byNODES ?
410 vxyz(d*pts_cnt + i) :
411 vxyz(i*dim + d);
412 }
413 Vector exact_val(vec_dim);
414 F_exact(pos, exact_val);
415 error = gf_ordering == Ordering::byNODES ?
416 fabs(exact_val(j) - interp_vals[i + j*pts_cnt]) :
417 fabs(exact_val(j) - interp_vals[i*vec_dim + j]);
418 max_error = std::max(max_error, error);
419 max_dist = std::max(max_dist, dist_p_out(i));
420 if (code_out[i] == 1 && j == 0) { face_pts++; }
421 }
422 else { if (j == 0) { not_found++; } }
423 }
424 }
425
426 MPI_Allreduce(MPI_IN_PLACE, &found_loc, 1, MPI_INT, MPI_SUM,
427 pfespace.GetComm());
428 MPI_Allreduce(MPI_IN_PLACE, &found_away, 1, MPI_INT, MPI_SUM,
429 pfespace.GetComm());
430 MPI_Allreduce(MPI_IN_PLACE, &face_pts, 1, MPI_INT, MPI_SUM, pfespace.GetComm());
431 MPI_Allreduce(MPI_IN_PLACE, &not_found, 1, MPI_INT, MPI_SUM,
432 pfespace.GetComm());
433 MPI_Allreduce(MPI_IN_PLACE, &max_error, 1, MPI_DOUBLE, MPI_MAX,
434 pfespace.GetComm());
435 MPI_Allreduce(MPI_IN_PLACE, &max_dist, 1, MPI_DOUBLE, MPI_MAX,
436 pfespace.GetComm());
437 MPI_Allreduce(MPI_IN_PLACE, &error, 1, MPI_DOUBLE, MPI_SUM, pfespace.GetComm());
438
439
440 if (myid == 0)
441 {
442 cout << setprecision(16)
443 << "Total number of elements: " << nelemglob
444 << "\nTotal number of procs: " << num_procs
445 << "\nSearched total points: " << pts_cnt*num_procs
446 << "\nFound locally on ranks: " << found_loc
447 << "\nFound on other tasks: " << found_away
448 << "\nPoints not found: " << not_found
449 << "\nPoints on faces: " << face_pts
450 << "\nMax interp error: " << max_error
451 << "\nMax dist (of found): " << max_dist
452 << endl;
453 }
454
455 // Free the internal gslib data.
456 finder.FreeData();
457
458 delete fec;
459 if (randomization != 0) { delete mesh; }
460
461 return 0;
462}
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
Definition device.hpp:123
void Print(std::ostream &out=mfem::out)
Print the configuration of the MFEM virtual device object.
Definition device.cpp:297
virtual void Transform(const IntegrationPoint &, Vector &)=0
Transform integration point from reference coordinates to physical coordinates and store them in the ...
FindPointsGSLIB can robustly evaluate a GridFunction on an arbitrary collection of points.
Definition gslib.hpp:67
virtual const Vector & GetDist() const
Definition gslib.hpp:304
void FindPoints(const Vector &point_pos, int point_pos_ordering=Ordering::byNODES)
Definition gslib.cpp:242
virtual const Vector & GetReferencePosition() const
Return reference coordinates for each point found by FindPoints.
Definition gslib.hpp:301
void Setup(Mesh &m, const double bb_t=0.1, const double newt_tol=1.0e-12, const int npt_max=256)
Definition gslib.cpp:163
virtual void Interpolate(const GridFunction &field_in, Vector &field_out)
Definition gslib.cpp:1721
virtual const Array< unsigned int > & GetCode() const
Definition gslib.hpp:295
virtual const Array< unsigned int > & GetGSLIBElem() const
Definition gslib.hpp:308
virtual const Vector & GetGSLIBReferencePosition() const
Definition gslib.hpp:311
virtual void FreeData()
Definition gslib.cpp:1128
virtual const Array< unsigned int > & GetProc() const
Return MPI rank on which each point was found by FindPoints.
Definition gslib.hpp:299
virtual void SetDistanceToleranceForPointsFoundOnBoundary(double bdr_tol_)
Definition gslib.hpp:279
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition fe_coll.hpp:27
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:244
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
Definition fespace.hpp:924
Arbitrary order H1-conforming (continuous) finite elements.
Definition fe_coll.hpp:275
const char * Name() const override
Definition fe_coll.hpp:297
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Definition hypre.cpp:33
Class for integration point with weight.
Definition intrules.hpp:35
Arbitrary order "L2-conforming" discontinuous finite elements.
Definition fe_coll.hpp:346
Mesh data type.
Definition mesh.hpp:64
Element::Type GetElementType(int i) const
Returns the type of element i.
Definition mesh.cpp:7635
const FiniteElementSpace * GetNodalFESpace() const
Definition mesh.cpp:6479
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1282
void GetBoundingBox(Vector &min, Vector &max, int ref=2)
Returns the minimum and maximum corners of the mesh bounding box.
Definition mesh.cpp:138
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1216
void RandomRefinement(real_t prob, bool aniso=false, int nonconforming=-1, int nc_limit=0)
Refine each element with given probability. Uses GeneralRefinement.
Definition mesh.cpp:10975
void SetNodalGridFunction(GridFunction *nodes, bool make_owner=false)
Definition mesh.cpp:6473
void GetNodes(Vector &node_coord) const
Definition mesh.cpp:9294
long long GetGlobalNE() const
Return the total (global) number of elements.
Definition mesh.hpp:1311
void EnsureNCMesh(bool simplices_nonconforming=false)
Definition mesh.cpp:10951
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
Definition mesh.cpp:7243
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
Set the curvature of the mesh nodes using the given polynomial degree.
Definition mesh.cpp:6484
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Definition mesh.cpp:11295
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.
Definition fe_coll.hpp:482
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...
Definition optparser.hpp:82
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
Definition pfespace.hpp:29
MPI_Comm GetComm() const
Definition pfespace.hpp:334
Class for parallel grid function.
Definition pgridfunc.hpp:50
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Class for parallel meshes.
Definition pmesh.hpp:34
void SetNodalFESpace(FiniteElementSpace *nfes) override
Definition pmesh.cpp:2027
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Definition fe_coll.hpp:403
A general vector function coefficient.
Vector data type.
Definition vector.hpp:82
void Randomize(int seed=0)
Set random values in the vector.
Definition vector.cpp:915
void Destroy()
Destroy a vector.
Definition vector.hpp:635
int Size() const
Returns the size of the vector.
Definition vector.hpp:226
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
Definition vector.hpp:144
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:558
virtual real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
Definition vector.hpp:514
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
int dim
Definition ex24.cpp:53
int main()
const char vishost[]
real_t p(const Vector &x, real_t t)
double field_func(const Vector &x)
Definition pfindpts.cpp:64
double func_order
Definition pfindpts.cpp:61
void F_exact(const Vector &p, Vector &F)
Definition pfindpts.cpp:72