MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
phpref.cpp
Go to the documentation of this file.
1// Parallel hp-refinement example
2//
3// Compile with: make phpref
4//
5// Sample runs: mpirun -np 4 phpref -dim 2 -n 1000
6// mpirun -np 8 phpref -dim 3 -n 200
7// mpirun -np 8 phpref -dim 3 -n 20 --anisotropic --fixed-order
8//
9// Description: This example demonstrates h- and p-refinement in a parallel
10// finite element discretization of the Poisson problem (cf. ex1p)
11// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
12// Refinements are performed iteratively, each iteration having h-
13// or p-refinements on all MPI processes. For simplicity, we
14// randomly choose the elements and the type of refinement, for
15// each iteration. In practice, these choices may be made in a
16// problem-dependent way, but this example serves only to
17// illustrate the capabilities of hp-refinement in parallel.
18//
19// We recommend viewing Example 1 before viewing this example.
20
21#include "mfem.hpp"
22#include <fstream>
23#include <iostream>
24
25using namespace std;
26using namespace mfem;
27
29
30// Deterministic function for "random" integers.
31int DetRand(int & seed)
32{
33 seed++;
34 return int(std::abs(1.0e5 * sin(seed * 1.1234 * M_PI)));
35}
36
37void f_exact(const Vector &x, Vector &f);
38
39int main(int argc, char *argv[])
40{
41 // 1. Initialize MPI and HYPRE.
42 Mpi::Init();
43 const int num_procs = Mpi::WorldSize();
44 const int myid = Mpi::WorldRank();
46
47 // 2. Parse command-line options.
48 int order = 1;
49 const char *device_config = "cpu";
50 bool visualization = true;
51 int numIter = 0;
52 int dim = 2;
53 bool anisotropic = false;
54 bool fixedOrder = false;
55 bool deterministic = true;
56 bool projectSolution = false;
57
58 OptionsParser args(argc, argv);
59 args.AddOption(&order, "-o", "--order",
60 "Finite element order (polynomial degree) or -1 for"
61 " isoparametric space.");
62 args.AddOption(&device_config, "-d", "--device",
63 "Device configuration string, see Device::Configure().");
64 args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
65 "--no-visualization",
66 "Enable or disable GLVis visualization.");
67 args.AddOption(&numIter, "-n", "--num-iter", "Number of hp-ref iterations");
68 args.AddOption(&dim, "-dim", "--dim", "Mesh dimension (2 or 3)");
69 args.AddOption(&anisotropic, "-aniso", "--anisotropic", "-iso",
70 "--isotropic",
71 "Whether to use anisotropic refinements");
72 args.AddOption(&fixedOrder, "-fo", "--fixed-order", "-vo",
73 "--variable-order",
74 "Whether to fix the finite element order on all elements");
75 args.AddOption(&deterministic, "-det", "--deterministic", "-not-det",
76 "--not-deterministic",
77 "Use deterministic random refinements");
78 args.AddOption(&projectSolution, "-proj", "--project-solution", "-no-proj",
79 "--no-project",
80 "Project a coefficient to solution");
81
82 args.Parse();
83 if (!args.Good())
84 {
85 if (myid == 0)
86 {
87 args.PrintUsage(cout);
88 }
89 return 1;
90 }
91 if (myid == 0)
92 {
93 args.PrintOptions(cout);
94 }
95
96 MFEM_VERIFY(!anisotropic || fixedOrder,
97 "Variable-order is not supported with anisotropic refinement");
98
99 // 3. Enable hardware devices such as GPUs, and programming models such as
100 // CUDA, OCCA, RAJA and OpenMP based on command line options.
101 Device device(device_config);
102 if (myid == 0) { device.Print(); }
103
104 // 4. Construct a uniform coarse mesh on all processors.
105 Mesh mesh;
106 if (dim == 3)
107 {
109 }
110 else
111 {
113 }
114
115 mesh.EnsureNCMesh();
116
117 // 5. Define a parallel mesh by a partitioning of the serial mesh. Refine
118 // this mesh further in parallel to increase the resolution. Once the
119 // parallel mesh is defined, the serial mesh can be deleted.
120 ParMesh pmesh(MPI_COMM_WORLD, mesh);
121 mesh.Clear();
122 {
123 int par_ref_levels = 0;
124 for (int l = 0; l < par_ref_levels; l++)
125 {
126 pmesh.UniformRefinement();
127 }
128 }
129
130 // 6. Define a parallel finite element space on the parallel mesh. Here we
131 // use continuous Lagrange finite elements of the specified order. If
132 // order < 1, we instead use an isoparametric/isogeometric space.
134 bool delete_fec;
135 if (order > 0)
136 {
137 fec = new H1_FECollection(order, dim);
138 delete_fec = true;
139 }
140 else if (pmesh.GetNodes())
141 {
142 fec = pmesh.GetNodes()->OwnFEC();
143 delete_fec = false;
144 if (myid == 0)
145 {
146 cout << "Using isoparametric FEs: " << fec->Name() << endl;
147 }
148 }
149 else
150 {
151 fec = new H1_FECollection(order = 1, dim);
152 delete_fec = true;
153 }
154
155 const int fespaceDim = projectSolution ? dim : 1;
156 ParFiniteElementSpace fespace(&pmesh, fec, fespaceDim);
157
158 // 7. Iteratively perform h- and p-refinements.
159
160 int numH = 0;
161 int numP = 0;
162 int seed = myid;
163
164 const std::vector<char> hp_char = {'h', 'p'};
165
166 for (int iter=0; iter<numIter; ++iter)
167 {
168 const int r1 = deterministic ? DetRand(seed) : rand();
169 const int r2 = deterministic ? DetRand(seed) : rand();
170 const int elem = r1 % pmesh.GetNE();
171 int hp = r2 % 2;
172 char htype = 7;
173 MPI_Bcast(&hp, 1, MPI_INT, 0, MPI_COMM_WORLD);
174
175 if (fixedOrder) { hp = 0; } // Only perform h-refinement
176 if (anisotropic)
177 {
178 const int r3 = deterministic ? DetRand(seed) : rand();
179 htype = (r3 % 7) + 1;
180 }
181
182 if (myid == 0)
183 cout << "hp-refinement iteration " << iter << ": "
184 << hp_char[hp] << "-refinement\n";
185
186 if (hp == 1)
187 {
188 // p-refinement
190 refs.Append(pRefinement(elem, 1)); // Increase the element order by 1
191 fespace.PRefineAndUpdate(refs);
192 numP++;
193 }
194 else
195 {
196 // h-refinement
198 refs.Append(Refinement(elem, htype));
199 if (anisotropic)
200 {
201 std::set<int> conflicts; // Indices in refs of conflicting elements
202 const bool conflict = pmesh.AnisotropicConflict(refs, conflicts);
203 if (conflict)
204 {
205 if (myid == 0)
206 cout << "Anisotropic conflict on iteration " << iter
207 << ", retrying\n";
208 iter--;
209 continue;
210 }
211 }
212
213 pmesh.GeneralRefinement(refs);
214 fespace.Update(false);
215 numH++;
216 }
217 }
218
219 const HYPRE_BigInt size = fespace.GlobalTrueVSize();
220 const int maxP = fespace.GetMaxElementOrder();
221 if (myid == 0)
222 {
223 cout << "Number of finite element unknowns: " << size << endl;
224 cout << "Total number of h-refinements: " << numH
225 << "\nTotal number of p-refinements: " << numP
226 << "\nMaximum order " << maxP << "\n";
227 }
228
229 ParGridFunction x(&fespace);
230 Vector X;
231
232 if (projectSolution)
233 {
235 x.ProjectCoefficient(vec_coef);
236
237 X.SetSize(fespace.GetTrueVSize());
238
239 fespace.GetRestrictionMatrix()->Mult(x, X);
240 fespace.GetProlongationMatrix()->Mult(X, x);
241
242 // Compute and print the L^2 norm of the error.
243 const real_t error = x.ComputeL2Error(vec_coef);
244 if (myid == 0)
245 {
246 cout << "\n|| E_h - E ||_{L^2} = " << error << '\n' << endl;
247 }
248 }
249 else
250 {
251 // 8. Determine the list of true (i.e. parallel conforming) essential
252 // boundary dofs. In this example, the boundary conditions are defined
253 // by marking all the boundary attributes from the mesh as essential
254 // (Dirichlet) and converting them to a list of true dofs.
255 Array<int> ess_tdof_list;
256 if (pmesh.bdr_attributes.Size())
257 {
258 Array<int> ess_bdr(pmesh.bdr_attributes.Max());
259 ess_bdr = 1;
260 fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
261 }
262
263 // 9. Set up the parallel linear form b(.) which corresponds to the
264 // right-hand side of the FEM linear system, which in this case is
265 // (1,phi_i) where phi_i are the basis functions in fespace.
266 ParLinearForm b(&fespace);
267 ConstantCoefficient one(1.0);
268 b.AddDomainIntegrator(new DomainLFIntegrator(one));
269 b.Assemble();
270
271 // 10. Define the solution vector x as a parallel finite element grid
272 // function corresponding to fespace. Initialize x with initial guess of
273 // zero, which satisfies the boundary conditions.
274 x = 0.0;
275
276 // 11. Set up the parallel bilinear form a(.,.) on the finite element space
277 // corresponding to the Laplacian operator -Delta, by adding the
278 // diffusion domain integrator.
279 ParBilinearForm a(&fespace);
280 a.AddDomainIntegrator(new DiffusionIntegrator(one));
281
282 // 12. Assemble the parallel bilinear form and the corresponding linear
283 // system, applying any necessary transformations such as: parallel
284 // assembly, eliminating boundary conditions, applying conforming
285 // constraints for non-conforming AMR, static condensation, etc.
286 a.Assemble();
287
288 OperatorPtr A;
289 Vector B;
290 a.FormLinearSystem(ess_tdof_list, x, b, A, X, B);
291
292 // 13. Solve the linear system A X = B.
293 // * With full assembly, use the BoomerAMG preconditioner from hypre.
294 // * With partial assembly, use Jacobi smoothing, for now.
295 Solver *prec = new HypreBoomerAMG;
296 CGSolver cg(MPI_COMM_WORLD);
297 cg.SetRelTol(1e-12);
298 cg.SetMaxIter(2000);
299 cg.SetPrintLevel(1);
300 if (prec) { cg.SetPreconditioner(*prec); }
301 cg.SetOperator(*A);
302 cg.Mult(B, X);
303 delete prec;
304
305 // 14. Recover the parallel grid function corresponding to X. This is the
306 // local finite element solution on each processor.
307 a.RecoverFEMSolution(X, b, x);
308 }
309
310 if (fespaceDim == 1)
311 {
312 const real_t h1error = CheckH1Continuity(x);
313 if (myid == 0) { cout << "H1 continuity error " << h1error << endl; }
314 MFEM_VERIFY(h1error < 1.0e-12, "H1 continuity is not satisfied");
315 }
316
317 L2_FECollection fecL2(0, dim);
318 ParFiniteElementSpace l2fespace(&pmesh, &fecL2);
319 ParGridFunction xo(&l2fespace);
320 xo = 0.0;
321
322 for (int e=0; e<pmesh.GetNE(); ++e)
323 {
324 const int p_elem = fespace.GetElementOrder(e);
325 Array<int> dofs;
326 l2fespace.GetElementDofs(e, dofs);
327 MFEM_VERIFY(dofs.Size() == 1, "");
328 xo[dofs[0]] = p_elem;
329 }
330
331 // 15. Save the refined mesh and the solution in parallel. This output can
332 // be viewed later using GLVis: "glvis -np <np> -m mesh -g sol".
333 std::unique_ptr<GridFunction> vis_x = x.ProlongateToMaxOrder();
334 {
335 ostringstream mesh_name, sol_name, order_name;
336 mesh_name << "mesh." << setfill('0') << setw(6) << myid;
337 sol_name << "sol." << setfill('0') << setw(6) << myid;
338 order_name << "order." << setfill('0') << setw(6) << myid;
339
340 ofstream mesh_ofs(mesh_name.str().c_str());
341 mesh_ofs.precision(8);
342 pmesh.ParPrint(mesh_ofs);
343
344 ofstream sol_ofs(sol_name.str().c_str());
345 sol_ofs.precision(8);
346
347 vis_x->Save(sol_ofs);
348
349 ofstream order_ofs(order_name.str().c_str());
350 order_ofs.precision(8);
351 xo.Save(order_ofs);
352 }
353
354 // 16. Send the solution by socket to a GLVis server.
355 if (visualization)
356 {
357 char vishost[] = "localhost";
358 int visport = 19916;
359 socketstream sol_sock(vishost, visport);
360 sol_sock << "parallel " << num_procs << " " << myid << "\n";
361 sol_sock.precision(8);
362 sol_sock << "solution\n" << pmesh << *vis_x << flush;
363 }
364
365 // 17. Free the used memory.
366 if (delete_fec)
367 {
368 delete fec;
369 }
370
371 return 0;
372}
373
375{
377
378 const ParFiniteElementSpace *fes = x.ParFESpace();
379 ParMesh *mesh = fes->GetParMesh();
380
381 const int dim = mesh->Dimension();
382
383 // Following the example of KellyErrorEstimator::ComputeEstimates(),
384 // we loop over interior faces and then shared faces.
385
386 // Compute error contribution from local interior faces
387 real_t errorMax = 0.0;
388 for (int f = 0; f < mesh->GetNumFaces(); f++)
389 {
390 if (mesh->FaceIsInterior(f))
391 {
392 int Inf1, Inf2, NCFace;
393 mesh->GetFaceInfos(f, &Inf1, &Inf2, &NCFace);
394
395 auto FT = mesh->GetFaceElementTransformations(f);
396
397 const int faceOrder = dim == 3 ? fes->GetFaceOrder(f) :
398 fes->GetEdgeOrder(f);
399 auto &int_rule = IntRules.Get(FT->FaceGeom, 2 * faceOrder);
400 const auto nip = int_rule.GetNPoints();
401
402 // Convention
403 // * Conforming face: Face side with smaller element id handles
404 // the integration
405 // * Non-conforming face: The slave handles the integration.
406 // See FaceInfo documentation for details.
407 bool isNCSlave = FT->Elem2No >= 0 && NCFace >= 0;
408 bool isConforming = FT->Elem2No >= 0 && NCFace == -1;
409 if ((FT->Elem1No < FT->Elem2No && isConforming) || isNCSlave)
410 {
411 for (int i = 0; i < nip; i++)
412 {
413 const auto &fip = int_rule.IntPoint(i);
415
416 FT->Loc1.Transform(fip, ip);
417 const real_t v1 = x.GetValue(FT->Elem1No, ip);
418
419 FT->Loc2.Transform(fip, ip);
420 const real_t v2 = x.GetValue(FT->Elem2No, ip);
421
422 const real_t err_i = std::abs(v1 - v2);
423 errorMax = std::max(errorMax, err_i);
424 }
425 }
426 }
427 }
428
429 // Compute error contribution from shared interior faces
430 for (int sf = 0; sf < mesh->GetNSharedFaces(); sf++)
431 {
432 const int f = mesh->GetSharedFace(sf);
433 const bool trueInterior = mesh->FaceIsTrueInterior(f);
434 if (!trueInterior) { continue; }
435
436 auto FT = mesh->GetSharedFaceTransformations(sf, true);
437 const int faceOrder = dim == 3 ? fes->GetFaceOrder(f) : fes->GetEdgeOrder(f);
438 const auto &int_rule = IntRules.Get(FT->FaceGeom, 2 * faceOrder);
439 const auto nip = int_rule.GetNPoints();
440
441 for (int i = 0; i < nip; i++)
442 {
443 const auto &fip = int_rule.IntPoint(i);
445
446 FT->Loc1.Transform(fip, ip);
447 const real_t v1 = x.GetValue(FT->Elem1No, ip);
448
449 FT->Loc2.Transform(fip, ip);
450 const real_t v2 = x.GetValue(FT->Elem2No, ip);
451
452 const real_t err_i = std::abs(v1 - v2);
453 errorMax = std::max(errorMax, err_i);
454 }
455 }
456
457 real_t errorMaxGlobal = 0.0;
458 MPI_Allreduce(&errorMax, &errorMaxGlobal, 1, MFEM_MPI_REAL_T, MPI_MAX,
459 fes->GetComm());
460 return errorMaxGlobal;
461}
462
463void f_exact(const Vector &x, Vector &f)
464{
465 constexpr real_t freq = 1.0;
466 constexpr real_t kappa = freq * M_PI;
467
468 if (x.Size() == 3)
469 {
470 f(0) = (1. + kappa * kappa) * sin(kappa * x(1));
471 f(1) = (1. + kappa * kappa) * sin(kappa * x(2));
472 f(2) = (1. + kappa * kappa) * sin(kappa * x(0));
473 }
474 else
475 {
476 f(0) = (1. + kappa * kappa) * sin(kappa * x(1));
477 f(1) = (1. + kappa * kappa) * sin(kappa * x(0));
478 if (x.Size() == 3) { f(2) = 0.0; }
479 }
480}
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Definition array.cpp:69
int Size() const
Return the logical size of the array.
Definition array.hpp:166
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Definition array.hpp:912
Conjugate gradient method.
Definition solvers.hpp:627
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the Conjugate Gradient method.
Definition solvers.cpp:869
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
Definition solvers.hpp:640
A coefficient that is constant across space and time.
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
Definition device.hpp:124
void Print(std::ostream &os=mfem::out)
Print the configuration of the MFEM virtual device object.
Definition device.cpp:317
Class for domain integration .
Definition lininteg.hpp:108
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition fe_coll.hpp:27
virtual const char * Name() const
Definition fe_coll.hpp:79
int GetEdgeOrder(int edge, int variant=0) const
Definition fespace.cpp:3343
int GetFaceOrder(int face, int variant=0) const
Returns the polynomial degree of the i'th face finite element.
Definition fespace.cpp:3359
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
Definition fespace.cpp:193
Arbitrary order H1-conforming (continuous) finite elements.
Definition fe_coll.hpp:279
The BoomerAMG solver in hypre.
Definition hypre.hpp:1737
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
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition intrules.hpp:256
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void SetRelTol(real_t rtol)
Definition solvers.hpp:238
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition solvers.cpp:178
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
Definition solvers.cpp:76
void SetMaxIter(int max_it)
Definition solvers.hpp:240
Arbitrary order "L2-conforming" discontinuous finite elements.
Definition fe_coll.hpp:350
Mesh data type.
Definition mesh.hpp:65
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition mesh.hpp:304
void GetFaceInfos(int Face, int *Inf1, int *Inf2) const
Definition mesh.cpp:1563
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
Definition mesh.cpp:6846
void GeneralRefinement(const Array< Refinement > &refinements, int nonconforming=-1, int nc_limit=0)
Definition mesh.cpp:11225
void Clear()
Clear the contents of the Mesh.
Definition mesh.hpp:827
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1377
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1306
bool FaceIsInterior(int FaceNo) const
Return true if the given face is interior.
Definition mesh.hpp:1563
static Mesh MakeCartesian3D(int nx, int ny, int nz, Element::Type type, real_t sx=1.0, real_t sy=1.0, real_t sz=1.0, bool sfc_ordering=true)
Creates a mesh for the parallelepiped [0,sx]x[0,sy]x[0,sz], divided into nx*ny*nz hexahedra if type =...
Definition mesh.cpp:4627
void GetNodes(Vector &node_coord) const
Definition mesh.cpp:9627
void EnsureNCMesh(bool simplices_nonconforming=false)
Definition mesh.cpp:11293
static Mesh MakeCartesian2D(int nx, int ny, Element::Type type, bool generate_edges=false, real_t sx=1.0, real_t sy=1.0, bool sfc_ordering=true)
Creates mesh for the rectangle [0,sx]x[0,sy], divided into nx*ny quadrilaterals if type = QUADRILATER...
Definition mesh.cpp:4617
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Definition mesh.cpp:11637
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).
Pointer to an Operator of a specified type.
Definition handle.hpp:34
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
virtual void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x)
Reconstruct a solution vector x (e.g. a GridFunction) from the solution X of a constrained linear sys...
Definition operator.cpp:148
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.
Class for parallel bilinear form.
Abstract parallel finite element space.
Definition pfespace.hpp:31
MPI_Comm GetComm() const
Definition pfespace.hpp:337
int GetMaxElementOrder() const override
Returns the maximum polynomial order over all elements globally.
void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const override
HYPRE_BigInt GlobalTrueVSize() const
Definition pfespace.hpp:349
int GetTrueVSize() const override
Return the number of local vector true dofs.
Definition pfespace.hpp:353
const Operator * GetProlongationMatrix() const override
void GetElementDofs(int i, Array< int > &dofs, DofTransformation &doftrans) const override
The same as GetElementDofs(), but with a user-provided DofTransformation object.
Definition pfespace.cpp:562
void PRefineAndUpdate(const Array< pRefinement > &refs, bool want_transfer=true) override
const SparseMatrix * GetRestrictionMatrix() const override
Get the R matrix which restricts a local dof vector to true dof vector.
Definition pfespace.hpp:470
ParMesh * GetParMesh() const
Definition pfespace.hpp:341
void Update(bool want_transform=true) override
Class for parallel grid function.
Definition pgridfunc.hpp:50
void Save(std::ostream &out) const override
real_t ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const override
Returns ||u_ex - u_h||_L2 in parallel for H1 or L2 elements.
real_t GetValue(int i, const IntegrationPoint &ip, int vdim=1) const override
ParFiniteElementSpace * ParFESpace() const
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
std::unique_ptr< ParGridFunction > ProlongateToMaxOrder() const
Return a GridFunction with the values of this, prolongated to the maximum order of all elements in th...
Class for parallel linear form.
Class for parallel meshes.
Definition pmesh.hpp:34
void ParPrint(std::ostream &out, const std::string &comments="") const
Definition pmesh.cpp:6341
int GetNSharedFaces() const
Return the number of shared faces (3D), edges (2D), vertices (1D)
Definition pmesh.cpp:3164
FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31) override
Definition pmesh.cpp:2907
bool AnisotropicConflict(const Array< Refinement > &refinements, std::set< int > &conflicts) const
Return true if the input array of refinements to be performed would result in conflicting anisotropic...
Definition pmesh.cpp:3900
bool FaceIsTrueInterior(int FaceNo) const
Definition mesh.hpp:610
int GetSharedFace(int sface) const
Return the local face index for the given shared face.
Definition pmesh.cpp:3183
FaceElementTransformations * GetSharedFaceTransformations(int sf, bool fill2=true)
Get the FaceElementTransformations for the given shared face (edge 2D) using the shared face index sf...
Definition pmesh.cpp:2933
Base class for solvers.
Definition operator.hpp:792
void Mult(const Vector &x, Vector &y) const override
Matrix vector multiplication.
A general vector function coefficient.
Vector data type.
Definition vector.hpp:82
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
real_t kappa
Definition ex24.cpp:54
int dim
Definition ex24.cpp:53
real_t freq
Definition ex24.cpp:54
int main()
HYPRE_Int HYPRE_BigInt
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
float real_t
Definition config.hpp:46
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition intrules.hpp:492
const char vishost[]
int DetRand(int &seed)
Definition phpref.cpp:31
void f_exact(const Vector &x, Vector &f)
Definition phpref.cpp:463
real_t CheckH1Continuity(ParGridFunction &x)
Definition phpref.cpp:374