MFEM  v4.5.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
polar-nc.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, 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 // Polar NC: Generate polar non-conforming meshes
14 // ----------------------------------------------
15 //
16 // This miniapp generates a circular sector mesh that consist of quadrilaterals
17 // and triangles of similar sizes. The 3D version of the mesh is made of prisms
18 // and tetrahedra. The mesh is non-conforming by design, and can optionally be
19 // made curvilinear. The elements are ordered along a space-filling curve by
20 // default, which makes the mesh ready for parallel non-conforming AMR in MFEM.
21 //
22 // The implementation also demonstrates how to initialize a non-conforming mesh
23 // on the fly by marking hanging nodes with Mesh::AddVertexParents.
24 //
25 // Compile with: make polar-nc
26 //
27 // Sample runs: polar-nc --radius 1 --nsteps 10
28 // polar-nc --aspect 2
29 // polar-nc --dim 3 --order 4
30 
31 #include "mfem.hpp"
32 #include <fstream>
33 #include <iostream>
34 
35 using namespace mfem;
36 using namespace std;
37 
38 
39 struct Params2
40 {
41  double r, dr;
42  double a, da;
43 
44  Params2() = default;
45  Params2(double r0, double r1, double a0, double a1)
46  : r(r0), dr(r1 - r0), a(a0), da(a1 - a0) {}
47 };
48 
49 Mesh* Make2D(int nsteps, double rstep, double phi, double aspect, int order,
50  bool sfc)
51 {
52  Mesh *mesh = new Mesh(2, 0, 0);
53 
54  int origin = mesh->AddVertex(0.0, 0.0);
55 
56  // n is the number of steps in the polar direction
57  int n = 1;
58  while (phi * rstep/2 / n * aspect > rstep) { n++; }
59 
60  double r = rstep;
61  int first = mesh->AddVertex(r, 0.0);
62 
63  Array<Params2> params;
64  Array<Pair<int, int>> blocks;
65 
66  // create triangles around the origin
67  double prev_alpha = 0.0;
68  for (int i = 0; i < n; i++)
69  {
70  double alpha = phi * (i+1) / n;
71  mesh->AddVertex(r*cos(alpha), r*sin(alpha));
72  mesh->AddTriangle(origin, first+i, first+i+1);
73 
74  params.Append(Params2(0, r, prev_alpha, alpha));
75  prev_alpha = alpha;
76  }
77 
78  mesh->AddBdrSegment(origin, first, 1);
79  mesh->AddBdrSegment(first+n, origin, 2);
80 
81  for (int k = 1; k < nsteps; k++)
82  {
83  // m is the number of polar steps of the previous row
84  int m = n;
85  int prev_first = first;
86 
87  double prev_r = r;
88  r += rstep;
89 
90  if (phi * (r + prev_r)/2 / n * aspect < rstep * sqrt(2))
91  {
92  if (k == 1) { blocks.Append(Pair<int, int>(mesh->GetNE(), n)); }
93 
94  first = mesh->AddVertex(r, 0.0);
95  mesh->AddBdrSegment(prev_first, first, 1);
96 
97  // create a row of quads, same number as in previous row
98  prev_alpha = 0.0;
99  for (int i = 0; i < n; i++)
100  {
101  double alpha = phi * (i+1) / n;
102  mesh->AddVertex(r*cos(alpha), r*sin(alpha));
103  mesh->AddQuad(prev_first+i, first+i, first+i+1, prev_first+i+1);
104 
105  params.Append(Params2(prev_r, r, prev_alpha, alpha));
106  prev_alpha = alpha;
107  }
108 
109  mesh->AddBdrSegment(first+n, prev_first+n, 2);
110  }
111  else // we need to double the number of elements per row
112  {
113  n *= 2;
114 
115  blocks.Append(Pair<int, int>(mesh->GetNE(), n));
116 
117  // first create hanging vertices
118  int hang;
119  for (int i = 0; i < m; i++)
120  {
121  double alpha = phi * (2*i+1) / n;
122  int index = mesh->AddVertex(prev_r*cos(alpha), prev_r*sin(alpha));
123  mesh->AddVertexParents(index, prev_first+i, prev_first+i+1);
124  if (!i) { hang = index; }
125  }
126 
127  first = mesh->AddVertex(r, 0.0);
128  int a = prev_first, b = first;
129 
130  mesh->AddBdrSegment(a, b, 1);
131 
132  // create a row of quad pairs
133  prev_alpha = 0.0;
134  for (int i = 0; i < m; i++)
135  {
136  int c = hang+i, e = a+1;
137 
138  double alpha_half = phi * (2*i+1) / n;
139  int d = mesh->AddVertex(r*cos(alpha_half), r*sin(alpha_half));
140 
141  double alpha = phi * (2*i+2) / n;
142  int f = mesh->AddVertex(r*cos(alpha), r*sin(alpha));
143 
144  mesh->AddQuad(a, b, d, c);
145  mesh->AddQuad(c, d, f, e);
146 
147  a = e, b = f;
148 
149  params.Append(Params2(prev_r, r, prev_alpha, alpha_half));
150  params.Append(Params2(prev_r, r, alpha_half, alpha));
151  prev_alpha = alpha;
152  }
153 
154  mesh->AddBdrSegment(b, a, 2);
155  }
156  }
157 
158  for (int i = 0; i < n; i++)
159  {
160  mesh->AddBdrSegment(first+i, first+i+1, 3);
161  }
162 
163  // reorder blocks of elements with Grid SFC ordering
164  if (sfc)
165  {
166  blocks.Append(Pair<int, int>(mesh->GetNE(), 0));
167 
168  Array<Params2> new_params(params.Size());
169 
170  Array<int> ordering(mesh->GetNE());
171  for (int i = 0; i < blocks[0].one; i++)
172  {
173  ordering[i] = i;
174  new_params[i] = params[i];
175  }
176 
177  Array<int> coords;
178  for (int i = 0; i < blocks.Size()-1; i++)
179  {
180  int beg = blocks[i].one;
181  int width = blocks[i].two;
182  int height = (blocks[i+1].one - blocks[i].one) / width;
183 
184  NCMesh::GridSfcOrdering2D(width, height, coords);
185 
186  for (int j = 0, k = 0; j < coords.Size(); k++, j += 2)
187  {
188  int sfc_index = ((i & 1) ? coords[j] : (width-1 - coords[j]))
189  + coords[j+1]*width;
190  int old_index = beg + sfc_index;
191 
192  ordering[old_index] = beg + k;
193  new_params[beg + k] = params[old_index];
194  }
195  }
196 
197  mesh->ReorderElements(ordering, false);
198 
199  mfem::Swap(params, new_params);
200  }
201 
202  mesh->FinalizeMesh();
203 
204  // create high-order curvature
205  if (order > 1)
206  {
207  mesh->SetCurvature(order);
208 
209  GridFunction *nodes = mesh->GetNodes();
210  const FiniteElementSpace *fes = mesh->GetNodalFESpace();
211 
212  Array<int> dofs;
213  MFEM_ASSERT(params.Size() == mesh->GetNE(), "");
214 
215  for (int i = 0; i < mesh->GetNE(); i++)
216  {
217  const Params2 &par = params[i];
218  const IntegrationRule &ir = fes->GetFE(i)->GetNodes();
219  Geometry::Type geom = mesh->GetElementBaseGeometry(i);
220  fes->GetElementDofs(i, dofs);
221 
222  for (int j = 0; j < dofs.Size(); j++)
223  {
224  double a;
225  if (geom == Geometry::SQUARE)
226  {
227  r = par.r + ir[j].x * par.dr;
228  a = par.a + ir[j].y * par.da;
229  }
230  else
231  {
232  double rr = ir[j].x + ir[j].y;
233  if (std::abs(rr) < 1e-12) { continue; }
234  r = par.r + rr * par.dr;
235  a = par.a + ir[j].y/rr * par.da;
236  }
237  (*nodes)(fes->DofToVDof(dofs[j], 0)) = r*cos(a);
238  (*nodes)(fes->DofToVDof(dofs[j], 1)) = r*sin(a);
239  }
240  }
241 
242  nodes->RestrictConforming();
243  }
244 
245  return mesh;
246 }
247 
248 
249 const double pi2 = M_PI / 2;
250 
251 struct Params3
252 {
253  double r, dr;
254  double u1, u2, u3;
255  double v1, v2, v3;
256 
257  Params3() = default;
258  Params3(double r0, double r1,
259  double u1, double v1, double u2, double v2, double u3, double v3)
260  : r(r0), dr(r1 - r0), u1(u1), u2(u2), u3(u3), v1(v1), v2(v2), v3(v3) {}
261 };
262 
263 struct Vert : public Hashed2
264 {
265  int id;
266 };
267 
268 int GetMidVertex(int v1, int v2, double r, double u, double v, bool hanging,
269  Mesh *mesh, HashTable<Vert> &hash)
270 {
271  int vmid = hash.FindId(v1, v2);
272  if (vmid < 0)
273  {
274  vmid = hash.GetId(v1, v2);
275 
276  double w = 1.0 - u - v;
277  double q = r / sqrt(u*u + v*v + w*w);
278  int index = mesh->AddVertex(u*q, v*q, w*q);
279 
280  if (hanging) { mesh->AddVertexParents(index, v1, v2); }
281 
282  hash[vmid].id = index;
283  }
284  return hash[vmid].id;
285 }
286 
287 void MakeLayer(int vx1, int vy1, int vz1, int vx2, int vy2, int vz2, int level,
288  double r1, double r2, double u1, double v1, double u2, double v2,
289  double u3, double v3, bool bnd1, bool bnd2, bool bnd3, bool bnd4,
290  Mesh *mesh, HashTable<Vert> &hash, Array<Params3> &params)
291 {
292  if (!level)
293  {
294  mesh->AddWedge(vx1, vy1, vz1, vx2, vy2, vz2);
295 
296  if (bnd1) { mesh->AddBdrQuad(vx1, vy1, vy2, vx2, 1); }
297  if (bnd2) { mesh->AddBdrQuad(vy1, vz1, vz2, vy2, 2); }
298  if (bnd3) { mesh->AddBdrQuad(vz1, vx1, vx2, vz2, 3); }
299  if (bnd4) { mesh->AddBdrTriangle(vx2, vy2, vz2, 4); }
300 
301  params.Append(Params3(r1, r2, u1, v1, u2, v2, u3, v3));
302  }
303  else
304  {
305  double u12 = (u1+u2)/2, v12 = (v1+v2)/2;
306  double u23 = (u2+u3)/2, v23 = (v2+v3)/2;
307  double u31 = (u3+u1)/2, v31 = (v3+v1)/2;
308 
309  bool hang = (level == 1);
310 
311  int vxy1 = GetMidVertex(vx1, vy1, r1, u12, v12, hang, mesh, hash);
312  int vyz1 = GetMidVertex(vy1, vz1, r1, u23, v23, hang, mesh, hash);
313  int vxz1 = GetMidVertex(vx1, vz1, r1, u31, v31, hang, mesh, hash);
314  int vxy2 = GetMidVertex(vx2, vy2, r2, u12, v12, false, mesh, hash);
315  int vyz2 = GetMidVertex(vy2, vz2, r2, u23, v23, false, mesh, hash);
316  int vxz2 = GetMidVertex(vx2, vz2, r2, u31, v31, false, mesh, hash);
317 
318  MakeLayer(vx1, vxy1, vxz1, vx2, vxy2, vxz2, level-1,
319  r1, r2, u1, v1, u12, v12, u31, v31,
320  bnd1, false, bnd3, bnd4, mesh, hash, params);
321  MakeLayer(vxy1, vy1, vyz1, vxy2, vy2, vyz2, level-1,
322  r1, r2, u12, v12, u2, v2, u23, v23,
323  bnd1, bnd2, false, bnd4, mesh, hash, params);
324  MakeLayer(vxz1, vyz1, vz1, vxz2, vyz2, vz2, level-1,
325  r1, r2, u31, v31, u23, v23, u3, v3,
326  false, bnd2, bnd3, bnd4, mesh, hash, params);
327  MakeLayer(vyz1, vxz1, vxy1, vyz2, vxz2, vxy2, level-1,
328  r1, r2, u23, v23, u31, v31, u12, v12,
329  false, false, false, bnd4, mesh, hash, params);
330  }
331 }
332 
333 void MakeCenter(int origin, int vx, int vy, int vz, int level, double r,
334  double u1, double v1, double u2, double v2, double u3, double v3,
335  bool bnd1, bool bnd2, bool bnd3, bool bnd4,
336  Mesh *mesh, HashTable<Vert> &hash, Array<Params3> &params)
337 {
338  if (!level)
339  {
340  mesh->AddTet(origin, vx, vy, vz);
341 
342  if (bnd1) { mesh->AddBdrTriangle(0, vy, vx, 1); }
343  if (bnd2) { mesh->AddBdrTriangle(0, vz, vy, 2); }
344  if (bnd3) { mesh->AddBdrTriangle(0, vx, vz, 3); }
345  if (bnd4) { mesh->AddBdrTriangle(vx, vy, vz, 4); }
346 
347  params.Append(Params3(0, r, u1, v1, u2, v2, u3, v3));
348  }
349  else
350  {
351  double u12 = (u1+u2)/2, v12 = (v1+v2)/2;
352  double u23 = (u2+u3)/2, v23 = (v2+v3)/2;
353  double u31 = (u3+u1)/2, v31 = (v3+v1)/2;
354 
355  int vxy = GetMidVertex(vx, vy, r, u12, v12, false, mesh, hash);
356  int vyz = GetMidVertex(vy, vz, r, u23, v23, false, mesh, hash);
357  int vxz = GetMidVertex(vx, vz, r, u31, v31, false, mesh, hash);
358 
359  MakeCenter(origin, vx, vxy, vxz, level-1, r, u1, v1, u12, v12, u31, v31,
360  bnd1, false, bnd3, bnd4, mesh, hash, params);
361  MakeCenter(origin, vxy, vy, vyz, level-1, r, u12, v12, u2, v2, u23, v23,
362  bnd1, bnd2, false, bnd4, mesh, hash, params);
363  MakeCenter(origin, vxz, vyz, vz, level-1, r, u31, v31, u23, v23, u3, v3,
364  false, bnd2, bnd3, bnd4, mesh, hash, params);
365  MakeCenter(origin, vyz, vxz, vxy, level-1, r, u23, v23, u31, v31, u12, v12,
366  false, false, false, bnd4, mesh, hash, params);
367  }
368 }
369 
370 Mesh* Make3D(int nsteps, double rstep, double aspect, int order, bool sfc)
371 {
372  Mesh *mesh = new Mesh(3, 0, 0);
373 
374  HashTable<Vert> hash;
375  Array<Params3> params;
376 
377  int origin = mesh->AddVertex(0, 0, 0);
378 
379  double r = rstep;
380  int a = mesh->AddVertex(r, 0, 0);
381  int b = mesh->AddVertex(0, r, 0);
382  int c = mesh->AddVertex(0, 0, r);
383 
384  int levels = 0;
385  while (pi2 * rstep / (1 << levels) * aspect > rstep) { levels++; }
386 
387  MakeCenter(origin, a, b, c, levels, r, 1, 0, 0, 1, 0, 0,
388  true, true, true, (nsteps == 1), mesh, hash, params);
389 
390  for (int k = 1; k < nsteps; k++)
391  {
392  double prev_r = r;
393  r += rstep;
394 
395  if ((prev_r + rstep/2) * pi2 * aspect / (1 << levels) > rstep * sqrt(2))
396  {
397  levels++;
398  }
399 
400  int d = mesh->AddVertex(r, 0, 0);
401  int e = mesh->AddVertex(0, r, 0);
402  int f = mesh->AddVertex(0, 0, r);
403 
404  MakeLayer(a, b, c, d, e, f, levels, prev_r, r,
405  1, 0, 0, 1, 0, 0, true, true, true, (k == nsteps-1),
406  mesh, hash, params);
407 
408  a = d;
409  b = e;
410  c = f;
411  }
412 
413  // reorder mesh with Hilbert spatial sort
414  if (sfc)
415  {
416  Array<int> ordering;
417  mesh->GetHilbertElementOrdering(ordering);
418  mesh->ReorderElements(ordering, false);
419 
420  Array<Params3> new_params(params.Size());
421  for (int i = 0; i < ordering.Size(); i++)
422  {
423  new_params[ordering[i]] = params[i];
424  }
425  mfem::Swap(params, new_params);
426  }
427 
428  mesh->FinalizeMesh();
429 
430  // create high-order curvature
431  if (order > 1)
432  {
433  mesh->SetCurvature(order);
434 
435  GridFunction *nodes = mesh->GetNodes();
436  const FiniteElementSpace *fes = mesh->GetNodalFESpace();
437 
438  Array<int> dofs;
439  MFEM_ASSERT(params.Size() == mesh->GetNE(), "");
440 
441  for (int i = 0; i < mesh->GetNE(); i++)
442  {
443  const Params3 &par = params[i];
444  const IntegrationRule &ir = fes->GetFE(i)->GetNodes();
445  Geometry::Type geom = mesh->GetElementBaseGeometry(i);
446  fes->GetElementDofs(i, dofs);
447 
448  for (int j = 0; j < dofs.Size(); j++)
449  {
450  const IntegrationPoint &ip = ir[j];
451 
452  double u, v, w;
453  if (geom == Geometry::PRISM)
454  {
455  double l1 = 1.0 - ip.x - ip.y;
456  double l2 = ip.x, l3 = ip.y;
457  u = l1 * par.u1 + l2 * par.u2 + l3 * par.u3;
458  v = l1 * par.v1 + l2 * par.v2 + l3 * par.v3;
459  w = 1.0 - u - v;
460  r = par.r + ip.z * par.dr;
461  }
462  else
463  {
464  u = ip.x * par.u1 + ip.y * par.u2 + ip.z * par.u3;
465  v = ip.x * par.v1 + ip.y * par.v2 + ip.z * par.v3;
466  double rr = ip.x + ip.y + ip.z;
467  if (std::abs(rr) < 1e-12) { continue; }
468  w = rr - u - v;
469  r = par.r + rr * par.dr;
470  }
471 
472  double q = r / sqrt(u*u + v*v + w*w);
473  (*nodes)(fes->DofToVDof(dofs[j], 0)) = u*q;
474  (*nodes)(fes->DofToVDof(dofs[j], 1)) = v*q;
475  (*nodes)(fes->DofToVDof(dofs[j], 2)) = w*q;
476  }
477  }
478 
479  nodes->RestrictConforming();
480  }
481 
482  return mesh;
483 }
484 
485 
486 int main(int argc, char *argv[])
487 {
488  int dim = 2;
489  double radius = 1.0;
490  int nsteps = 10;
491  double angle = 90;
492  double aspect = 1.0;
493  int order = 2;
494  bool sfc = true;
495  bool visualization = true;
496 
497  // parse command line
498  OptionsParser args(argc, argv);
499  args.AddOption(&dim, "-d", "--dim", "Mesh dimension (2 or 3).");
500  args.AddOption(&radius, "-r", "--radius", "Radius of the domain.");
501  args.AddOption(&nsteps, "-n", "--nsteps",
502  "Number of elements along the radial direction");
503  args.AddOption(&aspect, "-a", "--aspect",
504  "Target aspect ratio of the elements.");
505  args.AddOption(&angle, "-phi", "--phi", "Angular range (2D only).");
506  args.AddOption(&order, "-o", "--order",
507  "Polynomial degree of mesh curvature.");
508  args.AddOption(&sfc, "-sfc", "--sfc", "-no-sfc", "--no-sfc",
509  "Try to order elements along a space-filling curve.");
510  args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
511  "--no-visualization",
512  "Enable or disable GLVis visualization.");
513  args.Parse();
514  if (!args.Good())
515  {
516  args.PrintUsage(cout);
517  return EXIT_FAILURE;
518  }
519  args.PrintOptions(cout);
520 
521  // validate options
522  MFEM_VERIFY(radius > 0, "");
523  MFEM_VERIFY(aspect > 0, "");
524  MFEM_VERIFY(dim >= 2 && dim <= 3, "");
525  MFEM_VERIFY(angle > 0 && angle < 360, "");
526  MFEM_VERIFY(nsteps > 0, "");
527 
528  double phi = angle * M_PI / 180;
529 
530  // generate
531  Mesh *mesh;
532  if (dim == 2)
533  {
534  mesh = Make2D(nsteps, radius/nsteps, phi, aspect, order, sfc);
535  }
536  else
537  {
538  mesh = Make3D(nsteps, radius/nsteps, aspect, order, sfc);
539  }
540 
541  // save the final mesh
542  ofstream ofs("polar-nc.mesh");
543  ofs.precision(8);
544  mesh->Print(ofs);
545 
546  // output the mesh to GLVis
547  if (visualization)
548  {
549  char vishost[] = "localhost";
550  int visport = 19916;
551  socketstream sol_sock(vishost, visport);
552  sol_sock.precision(8);
553  sol_sock << "mesh\n" << *mesh << flush;
554  }
555 
556  delete mesh;
557 
558  return EXIT_SUCCESS;
559 }
const char vishost[]
Mesh * Make3D(int nsteps, double rstep, double aspect, int order, bool sfc)
Definition: polar-nc.cpp:370
int Size() const
Return the logical size of the array.
Definition: array.hpp:138
static void GridSfcOrdering2D(int width, int height, Array< int > &coords)
Definition: ncmesh.cpp:4738
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:90
Class for grid function - Vector with associated FE space.
Definition: gridfunc.hpp:30
int DofToVDof(int dof, int vd, int ndofs=-1) const
Definition: fespace.cpp:251
int AddQuad(int v1, int v2, int v3, int v4, int attr=1)
Definition: mesh.cpp:1674
void MakeCenter(int origin, int vx, int vy, int vz, int level, double r, double u1, double v1, double u2, double v2, double u3, double v3, bool bnd1, bool bnd2, bool bnd3, bool bnd4, Mesh *mesh, HashTable< Vert > &hash, Array< Params3 > &params)
Definition: polar-nc.cpp:333
int GetMidVertex(int v1, int v2, double r, double u, double v, bool hanging, Mesh *mesh, HashTable< Vert > &hash)
Definition: polar-nc.cpp:268
void RestrictConforming()
Definition: gridfunc.cpp:1982
int AddTriangle(int v1, int v2, int v3, int attr=1)
Definition: mesh.cpp:1660
int GetNE() const
Returns number of elements.
Definition: mesh.hpp:923
Geometry::Type GetElementBaseGeometry(int i) const
Definition: mesh.hpp:1069
void MakeLayer(int vx1, int vy1, int vz1, int vx2, int vy2, int vz2, int level, double r1, double r2, double u1, double v1, double u2, double v2, double u3, double v3, bool bnd1, bool bnd2, bool bnd3, bool bnd4, Mesh *mesh, HashTable< Vert > &hash, Array< Params3 > &params)
Definition: polar-nc.cpp:287
int AddBdrTriangle(int v1, int v2, int v3, int attr=1)
Definition: mesh.cpp:1837
Mesh * Make2D(int nsteps, double rstep, double phi, double aspect, int order, bool sfc)
Definition: polar-nc.cpp:49
int AddVertex(double x, double y=0.0, double z=0.0)
Definition: mesh.cpp:1613
double f(const Vector &xvec)
Definition: lor_mms.hpp:32
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
Definition: optparser.cpp:151
int Append(const T &el)
Append element &#39;el&#39; to array, resize if necessary.
Definition: array.hpp:751
double b
Definition: lissajous.cpp:42
int AddTet(int v1, int v2, int v3, int v4, int attr=1)
Definition: mesh.cpp:1688
A pair of objects.
Definition: sort_pairs.hpp:23
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
Definition: mesh.cpp:5343
const IntegrationRule & GetNodes() const
Get a const reference to the nodes of the element.
Definition: fe_base.hpp:390
int AddBdrSegment(int v1, int v2, int attr=1)
Definition: mesh.cpp:1823
void GetHilbertElementOrdering(Array< int > &ordering)
Definition: mesh.cpp:2197
const int visport
void PrintUsage(std::ostream &out) const
Print the usage message.
Definition: optparser.cpp:454
virtual DofTransformation * GetElementDofs(int elem, Array< int > &dofs) const
Returns indices of degrees of freedom of element &#39;elem&#39;.
Definition: fespace.cpp:2678
void Swap(Array< T > &, Array< T > &)
Definition: array.hpp:630
void FinalizeMesh(int refine=0, bool fix_orientation=true)
Finalize the construction of any type of Mesh.
Definition: mesh.cpp:2883
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:96
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 &#39;var&#39; to receive the value. Enable/disable tags are used to set the bool...
Definition: optparser.hpp:82
int AddBdrQuad(int v1, int v2, int v3, int v4, int attr=1)
Definition: mesh.cpp:1851
double a
Definition: lissajous.cpp:41
Class for integration point with weight.
Definition: intrules.hpp:25
const double radius
Definition: distance.cpp:107
const FiniteElementSpace * GetNodalFESpace() const
Definition: mesh.cpp:5338
virtual void Print(std::ostream &os=mfem::out) const
Definition: mesh.hpp:1671
void ReorderElements(const Array< int > &ordering, bool reorder_vertices=true)
Definition: mesh.cpp:2249
int dim
Definition: ex24.cpp:53
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i&#39;th element in t...
Definition: fespace.cpp:2781
int index(int i, int j, int nx, int ny)
Definition: life.cpp:235
void PrintOptions(std::ostream &out) const
Print the options.
Definition: optparser.cpp:324
int AddWedge(int v1, int v2, int v3, int v4, int v5, int v6, int attr=1)
Definition: mesh.cpp:1709
const double pi2
Definition: polar-nc.cpp:249
const double alpha
Definition: ex15.cpp:369
void GetNodes(Vector &node_coord) const
Definition: mesh.cpp:7908
int GetId(int p1, int p2)
Get id of item whose parents are p1, p2... Create it if it doesn&#39;t exist.
Definition: hash.hpp:608
double u(const Vector &xvec)
Definition: lor_mms.hpp:24
int FindId(int p1, int p2) const
Find id of item whose parents are p1, p2... Return -1 if it doesn&#39;t exist.
Definition: hash.hpp:699
int main()
bool Good() const
Return true if the command line options were parsed successfully.
Definition: optparser.hpp:150
void AddVertexParents(int i, int p1, int p2)
Mark vertex i as nonconforming, with parent vertices p1 and p2.
Definition: mesh.cpp:1630