MFEM v4.8.0
Finite element discretization library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
mesh-explorer.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// Mesh Explorer Miniapp: Explore and manipulate meshes
14// -----------------------------------------------------
15//
16// This miniapp is a handy tool to examine, visualize and manipulate a given
17// mesh. Some of its features are:
18//
19// - visualizing of mesh materials and individual mesh elements
20// - mesh scaling, randomization, and general transformation
21// - manipulation of the mesh curvature
22// - the ability to simulate parallel partitioning
23// - quantitative and visual reports of mesh quality
24//
25// Compile with: make mesh-explorer
26//
27// Sample runs: mesh-explorer
28// mesh-explorer -m ../../data/beam-tri.mesh
29// mesh-explorer -m ../../data/star-q2.mesh
30// mesh-explorer -m ../../data/disc-nurbs.mesh
31// mesh-explorer -m ../../data/escher-p3.mesh
32// mesh-explorer -m ../../data/mobius-strip.mesh
33
34#include "mfem.hpp"
36#include <fstream>
37#include <limits>
38#include <cstdlib>
39
40using namespace mfem;
41using namespace std;
42
43// This transformation can be applied to a mesh with the 't' menu option.
44void transformation(const Vector &p, Vector &v)
45{
46 // simple shear transformation
47 real_t s = 0.1;
48
49 if (p.Size() == 3)
50 {
51 v(0) = p(0) + s*p(1) + s*p(2);
52 v(1) = p(1) + s*p(2) + s*p(0);
53 v(2) = p(2);
54 }
55 else if (p.Size() == 2)
56 {
57 v(0) = p(0) + s*p(1);
58 v(1) = p(1) + s*p(0);
59 }
60 else
61 {
62 v = p;
63 }
64}
65
66// This function is used with the 'r' menu option, sub-option 'l' to refine a
67// mesh locally in a region, defined by return values <= region_eps.
70{
71 const real_t x = p(0), y = p(1);
72 // here we describe the region: (x <= 1/4) && (y >= 0) && (y <= 1)
73 return std::max(std::max(x - (real_t) 0.25, -y), y - (real_t) 1.0);
74}
75
76// The projection of this function can be plotted with the 'l' menu option
78{
79 real_t x = p(0);
80 real_t y = p.Size() > 1 ? p(1) : 0.0;
81 real_t z = p.Size() > 2 ? p(2) : 0.0;
82
83 if (1)
84 {
85 // torus in the xy-plane
86 const real_t r_big = 2.0;
87 const real_t r_small = 1.0;
88 return hypot(r_big - hypot(x, y), z) - r_small;
89 }
90 if (0)
91 {
92 // sphere at the origin:
93 const real_t r = 1.0;
94 return hypot(hypot(x, y), z) - r;
95 }
96}
97
98Mesh *read_par_mesh(int np, const char *mesh_prefix, Array<int>& partitioning,
99 Array<int>& bdr_partitioning)
100{
101 Mesh *mesh;
102 Array<Mesh *> mesh_array;
103
104 mesh_array.SetSize(np);
105 for (int p = 0; p < np; p++)
106 {
107 ostringstream fname;
108 fname << mesh_prefix << '.' << setfill('0') << setw(6) << p;
109 ifgzstream meshin(fname.str().c_str());
110 if (!meshin)
111 {
112 cerr << "Can not open mesh file: " << fname.str().c_str()
113 << '!' << endl;
114 for (p--; p >= 0; p--)
115 {
116 delete mesh_array[p];
117 }
118 return NULL;
119 }
120 mesh_array[p] = new Mesh(meshin, 1, 0);
121 // Assign corresponding processor number to element + boundary partitions
122 for (int i = 0; i < mesh_array[p]->GetNE(); i++)
123 {
124 partitioning.Append(p);
125 }
126 for (int i = 0; i < mesh_array[p]->GetNBE(); i++)
127 {
128 bdr_partitioning.Append(p);
129 }
130 }
131 mesh = new Mesh(mesh_array, np);
132
133 for (int p = 0; p < np; p++)
134 {
135 delete mesh_array[np-1-p];
136 }
137 mesh_array.DeleteAll();
138
139 return mesh;
140}
141
142// Given a 3D mesh, produce a 2D mesh consisting of its boundary elements.
143// We guarantee that the skin preserves the boundary index order.
145{
146 // Determine mapping from vertex to boundary vertex
147 Array<int> v2v(mesh->GetNV());
148 v2v = -1;
149 for (int i = 0; i < mesh->GetNBE(); i++)
150 {
151 Element *el = mesh->GetBdrElement(i);
152 int *v = el->GetVertices();
153 int nv = el->GetNVertices();
154 for (int j = 0; j < nv; j++)
155 {
156 v2v[v[j]] = 0;
157 }
158 }
159 int nbvt = 0;
160 for (int i = 0; i < v2v.Size(); i++)
161 {
162 if (v2v[i] == 0)
163 {
164 v2v[i] = nbvt++;
165 }
166 }
167
168 // Create a new mesh for the boundary
169 Mesh * bmesh = new Mesh(mesh->Dimension() - 1, nbvt, mesh->GetNBE(),
170 0, mesh->SpaceDimension());
171
172 // Copy vertices to the boundary mesh
173 nbvt = 0;
174 for (int i = 0; i < v2v.Size(); i++)
175 {
176 if (v2v[i] >= 0)
177 {
178 real_t *c = mesh->GetVertex(i);
179 bmesh->AddVertex(c);
180 nbvt++;
181 }
182 }
183
184 // Copy elements to the boundary mesh
185 int bv[4];
186 for (int i = 0; i < mesh->GetNBE(); i++)
187 {
188 Element *el = mesh->GetBdrElement(i);
189 int *v = el->GetVertices();
190 int nv = el->GetNVertices();
191
192 for (int j = 0; j < nv; j++)
193 {
194 bv[j] = v2v[v[j]];
195 }
196
197 switch (el->GetGeometryType())
198 {
200 bmesh->AddSegment(bv, el->GetAttribute());
201 break;
203 bmesh->AddTriangle(bv, el->GetAttribute());
204 break;
205 case Geometry::SQUARE:
206 bmesh->AddQuad(bv, el->GetAttribute());
207 break;
208 default:
209 break; // This should not happen
210 }
211
212 }
213 bmesh->FinalizeTopology();
214
215 // Copy GridFunction describing nodes if present
216 if (mesh->GetNodes())
217 {
218 FiniteElementSpace *fes = mesh->GetNodes()->FESpace();
219 const FiniteElementCollection *fec = fes->FEColl();
220 if (dynamic_cast<const H1_FECollection*>(fec))
221 {
222 FiniteElementCollection *fec_copy =
224 FiniteElementSpace *fes_copy =
225 new FiniteElementSpace(*fes, bmesh, fec_copy);
226 GridFunction *bdr_nodes = new GridFunction(fes_copy);
227 bdr_nodes->MakeOwner(fec_copy);
228
229 bmesh->NewNodes(*bdr_nodes, true);
230
231 Array<int> vdofs;
232 Array<int> bvdofs;
233 Vector v;
234 for (int i=0; i<mesh->GetNBE(); i++)
235 {
236 fes->GetBdrElementVDofs(i, vdofs);
237 mesh->GetNodes()->GetSubVector(vdofs, v);
238
239 fes_copy->GetElementVDofs(i, bvdofs);
240 bdr_nodes->SetSubVector(bvdofs, v);
241 }
242 }
243 else
244 {
245 cout << "\nDiscontinuous nodes not yet supported" << endl;
246 }
247 }
248
249 return bmesh;
250}
251
252void recover_bdr_partitioning(const Mesh* mesh, const Array<int>& partitioning,
253 Array<int>& bdr_partitioning)
254{
255 bdr_partitioning.SetSize(mesh->GetNBE());
256 int info, e;
257 for (int be = 0; be < mesh->GetNBE(); be++)
258 {
259 mesh->GetBdrElementAdjacentElement(be, e, info);
260 bdr_partitioning[be] = partitioning[e];
261 }
262}
263
264int main (int argc, char *argv[])
265{
266 int np = 0;
267 const char *mesh_file = "../../data/beam-hex.mesh";
268 int visport = 19916;
269 bool refine = true;
270
271 OptionsParser args(argc, argv);
272 args.AddOption(&mesh_file, "-m", "--mesh",
273 "Mesh file to visualize.");
274 args.AddOption(&np, "-np", "--num-proc",
275 "Load mesh from multiple processors.");
276 args.AddOption(&refine, "-ref", "--refinement", "-no-ref", "--no-refinement",
277 "Prepare the mesh for refinement or not.");
278 args.AddOption(&visport, "-p", "--send-port", "Socket for GLVis.");
279 args.Parse();
280 if (!args.Good())
281 {
282 if (!args.Help())
283 {
284 args.PrintError(cout);
285 cout << endl;
286 }
287 cout << "Visualize and manipulate a serial mesh:\n"
288 << " mesh-explorer -m <mesh_file>\n"
289 << "Visualize and manipulate a parallel mesh:\n"
290 << " mesh-explorer -np <#proc> -m <mesh_prefix>\n" << endl
291 << "All Options:\n";
292 args.PrintHelp(cout);
293 return 1;
294 }
295 args.PrintOptions(cout);
296
297 Mesh *mesh;
298 Mesh *bdr_mesh = NULL;
299
300 // Helper to distinguish whether we use a parallel or serial mesh.
301 const bool use_par_mesh = np > 0;
302
303 // Helper for visualizing the partitioning.
304 Array<int> partitioning;
305 Array<int> bdr_partitioning;
306 Array<int> elem_partitioning;
307 if (!use_par_mesh)
308 {
309 mesh = new Mesh(mesh_file, 1, refine);
310 partitioning.SetSize(mesh->GetNE());
311 partitioning = 0;
312 bdr_partitioning.SetSize(mesh->GetNBE());
313 bdr_partitioning = 0;
314 elem_partitioning.SetSize(mesh->GetNE());
315 elem_partitioning = 0;
316 np = 1;
317 }
318 else
319 {
320 mesh = read_par_mesh(np, mesh_file, partitioning, bdr_partitioning);
321 if (mesh == NULL)
322 {
323 return 3;
324 }
325 }
326 int dim = mesh->Dimension();
327 int sdim = mesh->SpaceDimension();
328
329 FiniteElementCollection *bdr_attr_fec = NULL;
330 FiniteElementCollection *attr_fec;
331 if (dim == 2)
332 {
333 attr_fec = new Const2DFECollection;
334 }
335 else
336 {
337 bdr_attr_fec = new Const2DFECollection;
338 attr_fec = new Const3DFECollection;
339 }
340
341 int print_char = 1;
342 while (1)
343 {
344 if (print_char)
345 {
346 cout << endl;
347 mesh->PrintCharacteristics();
348 cout << "boundary attribs :";
349 for (int i = 0; i < mesh->bdr_attributes.Size(); i++)
350 {
351 cout << ' ' << mesh->bdr_attributes[i];
352 }
353 cout << '\n' << "material attribs :";
354 for (int i = 0; i < mesh->attributes.Size(); i++)
355 {
356 cout << ' ' << mesh->attributes[i];
357 }
358 cout << endl;
359 cout << "mesh curvature : ";
360 if (mesh->GetNodalFESpace() != NULL)
361 {
362 cout << mesh->GetNodalFESpace()->FEColl()->Name() << endl;
363 }
364 else
365 {
366 cout << "NONE" << endl;
367 }
368 }
369 print_char = 0;
370 cout << endl;
371 cout << "What would you like to do?\n"
372 "r) Refine\n"
373 "c) Change curvature\n"
374 "s) Scale\n"
375 "t) Transform\n"
376 "j) Jitter\n"
377 "v) View mesh\n"
378 "P) View partitioning\n"
379 "m) View materials\n"
380 "b) View boundary\n"
381 "B) View boundary partitioning\n"
382 "e) View elements\n"
383 "h) View element sizes, h\n"
384 "k) View element ratios, kappa\n"
385 "J) View scaled Jacobian\n"
386 "l) Plot a function\n"
387 "x) Print sub-element stats\n"
388 "f) Find physical point in reference space\n"
389 "p) Generate a partitioning\n"
390 "o) Reorder elements\n"
391 "S) Save in MFEM serial format\n"
392 "T) Save in MFEM parallel format using the current partitioning\n"
393 "V) Save in VTK format (only linear and quadratic meshes)\n"
394#ifdef MFEM_USE_NETCDF
395 "X) Save in Exodus II format (only linear and quadratic meshes)\n"
396#endif
397 "D) Save as a DataCollection\n"
398 "q) Quit\n"
399#ifdef MFEM_USE_ZLIB
400 "Z) Save in MFEM format with compression\n"
401#endif
402 "--> " << flush;
403 char mk;
404 cin >> mk;
405 if (!cin) { break; }
406
407 if (mk == 'q')
408 {
409 break;
410 }
411
412 if (mk == 'r')
413 {
414 cout <<
415 "Choose type of refinement:\n"
416 "s) standard refinement with Mesh::UniformRefinement()\n"
417 "b) Mesh::UniformRefinement() (bisection for tet meshes)\n"
418 "u) uniform refinement with a factor\n"
419 "g) non-uniform refinement (Gauss-Lobatto) with a factor\n"
420 "n) NURBS refinement (uniform or by formula) with a factor\n"
421 "c) NURBS coarsening (uniform or by formula) with a factor\n"
422 "l) refine locally using the region() function\n"
423 "r) random refinement with a probability\n"
424 "--> " << flush;
425 char sk;
426 cin >> sk;
427 switch (sk)
428 {
429 case 's':
430 mesh->UniformRefinement();
431 // Make sure tet-only meshes are marked for local refinement.
432 mesh->Finalize(true);
433 break;
434 case 'b':
435 mesh->UniformRefinement(1); // ref_algo = 1
436 break;
437 case 'u':
438 case 'g':
439 {
440 cout << "enter refinement factor --> " << flush;
441 int ref_factor;
442 cin >> ref_factor;
443 if (ref_factor <= 1 || ref_factor > 32) { break; }
444 int ref_type = (sk == 'u') ? BasisType::ClosedUniform :
446 *mesh = Mesh::MakeRefined(*mesh, ref_factor, ref_type);
447 break;
448 }
449 case 'n':
450 {
451 Array<int> ref_factors(dim);
452 cout << "enter refinement factor, 1st dimension --> " << flush;
453 cin >> ref_factors[0];
454 cout << "enter refinement factor, 2nd dimension --> " << flush;
455 cin >> ref_factors[1];
456 if (dim == 3)
457 {
458 cout << "enter refinement factor, 3rd dimension --> "
459 << flush;
460 cin >> ref_factors[2];
461 }
462 for (auto ref_factor : ref_factors)
463 if (ref_factor <= 1 || ref_factor > 32) { break; }
464
465 char input_tol = 'n';
466 cout << "enter NURBS tolerance? [y/n] ---> " << flush;
467 cin >> input_tol;
468
469 real_t tol = 1.0e-12; // Default value
470 if (input_tol == 'y')
471 {
472 cout << "enter NURBS tolerance ---> " << flush;
473 cin >> tol;
474 }
475
476 mesh->NURBSUniformRefinement(ref_factors, tol);
477 break;
478 }
479 case 'c':
480 {
481 cout << "enter coarsening factor --> " << flush;
482 int coarsen_factor;
483 cin >> coarsen_factor;
484 if (coarsen_factor <= 1 || coarsen_factor > 32) { break; }
485
486 char input_tol = 'n';
487 cout << "enter NURBS tolerance? [y/n] ---> " << flush;
488 cin >> input_tol;
489
490 real_t tol = 1.0e-12; // Default value
491 if (input_tol == 'y')
492 {
493 cout << "enter NURBS tolerance ---> " << flush;
494 cin >> tol;
495 }
496
497 mesh->NURBSCoarsening(coarsen_factor, tol);
498 break;
499 }
500 case 'l':
501 {
502 Vector pt;
503 Array<int> marked_elements;
504 for (int i = 0; i < mesh->GetNE(); i++)
505 {
506 // check all nodes of the element
508 mesh->GetElementTransformation(i, &T);
509 for (int j = 0; j < T.GetPointMat().Width(); j++)
510 {
512 if (region(pt) <= region_eps)
513 {
514 marked_elements.Append(i);
515 break;
516 }
517 }
518 }
519 mesh->GeneralRefinement(marked_elements);
520 break;
521 }
522 case 'r':
523 {
524 bool nc_simplices = true;
525 mesh->EnsureNCMesh(nc_simplices);
526 cout << "enter probability --> " << flush;
527 real_t probability;
528 cin >> probability;
529 if (probability < 0.0 || probability > 1.0) { break; }
530 mesh->RandomRefinement(probability);
531 break;
532 }
533 }
534 print_char = 1;
535 }
536
537 if (mk == 'c')
538 {
539 int p;
540 cout << "enter new order for mesh curvature --> " << flush;
541 cin >> p;
542 mesh->SetCurvature(p > 0 ? p : -p, p <= 0);
543 print_char = 1;
544 }
545
546 if (mk == 's')
547 {
548 real_t factor;
549 cout << "scaling factor ---> " << flush;
550 cin >> factor;
551
552 GridFunction *nodes = mesh->GetNodes();
553 if (nodes == NULL)
554 {
555 for (int i = 0; i < mesh->GetNV(); i++)
556 {
557 real_t *v = mesh->GetVertex(i);
558 v[0] *= factor;
559 v[1] *= factor;
560 if (dim == 3)
561 {
562 v[2] *= factor;
563 }
564 }
565 }
566 else
567 {
568 *nodes *= factor;
569 }
570
571 print_char = 1;
572 }
573
574 if (mk == 't')
575 {
576 char type;
577 cout << "Choose a transformation:\n"
578 "u) User-defined transform through mesh-explorer::transformation()\n"
579 "k) Kershaw transform\n"
580 "s) Spiral transform\n"<< "---> " << flush;
581 cin >> type;
582 if (type == 'u')
583 {
585 }
586 else if (type == 'k')
587 {
588 cout << "Note: For Kershaw transformation, the input must be "
589 "Cartesian aligned with nx multiple of 6 and "
590 "both ny and nz multiples of 2."
591 "Kershaw transform works for 2D meshes also.\n" << flush;
592
593 real_t epsy, epsz = 0.0;
594 cout << "Kershaw transform factor, epsy in (0, 1]) ---> " << flush;
595 cin >> epsy;
596 if (mesh->Dimension() == 3)
597 {
598 cout << "Kershaw transform factor, epsz in (0, 1]) ---> " << flush;
599 cin >> epsz;
600 }
601 common::KershawTransformation kershawT(mesh->Dimension(), epsy, epsz);
602 mesh->Transform(kershawT);
603 }
604 else if (type == 's')
605 {
606 MFEM_VERIFY(mesh->SpaceDimension() >= 2,
607 "Mesh space dimension must be at least 2 "
608 "for spiral transformation.\n");
609 cout << "Note: For Spiral transformation, the input mesh is "
610 "assumed to be in [0,1]^D.\n" << flush;
611 real_t turns, width, gap, height = 1.0;
612 cout << "Number of turns: ---> " << flush;
613 cin >> turns;
614 cout << "Width of spiral arm (e.g. 0.1) ---> " << flush;
615 cin >> width;
616 cout << "Gap between adjacent spiral arms at the end of each turn (e.g. 0.05) ---> "
617 << flush;
618 cin >> gap;
619 if (mesh->SpaceDimension() == 3)
620 {
621 cout << "Maximum spiral height ---> " << flush;
622 cin >> height;
623 }
624 common::SpiralTransformation spiralT(mesh->SpaceDimension(), turns,
625 width, gap, height);
626 mesh->Transform(spiralT);
627 }
628 else
629 {
630 MFEM_ABORT("Transformation type not supported.");
631 }
632 print_char = 1;
633 }
634
635 if (mk == 'j')
636 {
637 real_t jitter;
638 cout << "jitter factor ---> " << flush;
639 cin >> jitter;
640
641 GridFunction *nodes = mesh->GetNodes();
642
643 if (nodes == NULL)
644 {
645 cerr << "The mesh should have nodes, introduce curvature first!\n";
646 }
647 else
648 {
649 FiniteElementSpace *fespace = nodes->FESpace();
650
651 GridFunction rdm(fespace);
652 rdm.Randomize();
653 rdm -= 0.5; // shift to random values in [-0.5,0.5]
654 rdm *= jitter;
655
656 // compute minimal local mesh size
657 Vector h0(fespace->GetNDofs());
658 h0 = infinity();
659 {
660 Array<int> dofs;
661 for (int i = 0; i < fespace->GetNE(); i++)
662 {
663 fespace->GetElementDofs(i, dofs);
664 for (int j = 0; j < dofs.Size(); j++)
665 {
666 h0(dofs[j]) = std::min(h0(dofs[j]), mesh->GetElementSize(i));
667 }
668 }
669 }
670
671 // scale the random values to be of order of the local mesh size
672 for (int i = 0; i < fespace->GetNDofs(); i++)
673 {
674 for (int d = 0; d < dim; d++)
675 {
676 rdm(fespace->DofToVDof(i,d)) *= h0(i);
677 }
678 }
679
680 char move_bdr = 'n';
681 cout << "move boundary nodes? [y/n] ---> " << flush;
682 cin >> move_bdr;
683
684 // don't perturb the boundary
685 if (move_bdr == 'n')
686 {
687 Array<int> vdofs;
688 for (int i = 0; i < fespace->GetNBE(); i++)
689 {
690 fespace->GetBdrElementVDofs(i, vdofs);
691 for (int j = 0; j < vdofs.Size(); j++)
692 {
693 rdm(vdofs[j]) = 0.0;
694 }
695 }
696 }
697
698 *nodes += rdm;
699 }
700
701 print_char = 1;
702 }
703
704 if (mk == 'x')
705 {
706 int sd, nz = 0;
707 DenseMatrix J(dim);
708 real_t min_det_J, max_det_J, min_det_J_z, max_det_J_z;
709 real_t min_kappa, max_kappa, max_ratio_det_J_z;
710 min_det_J = min_kappa = infinity();
711 max_det_J = max_kappa = max_ratio_det_J_z = -infinity();
712 cout << "subdivision factor ---> " << flush;
713 cin >> sd;
714 Array<int> bad_elems_by_geom(Geometry::NumGeom);
715 bad_elems_by_geom = 0;
716 // Only print so many to keep output compact
717 const int max_to_print = 10;
718 for (int i = 0; i < mesh->GetNE(); i++)
719 {
722
723 RefinedGeometry *RefG = GlobGeometryRefiner.Refine(geom, sd, 1);
724 IntegrationRule &ir = RefG->RefPts;
725
726 min_det_J_z = infinity();
727 max_det_J_z = -infinity();
728 for (int j = 0; j < ir.GetNPoints(); j++)
729 {
730 T->SetIntPoint(&ir.IntPoint(j));
731 Geometries.JacToPerfJac(geom, T->Jacobian(), J);
732
733 real_t det_J = J.Det();
734 real_t kappa =
736
737 min_det_J_z = std::min(min_det_J_z, det_J);
738 max_det_J_z = std::max(max_det_J_z, det_J);
739
740 min_kappa = std::min(min_kappa, kappa);
741 max_kappa = std::max(max_kappa, kappa);
742 }
743 max_ratio_det_J_z =
744 std::max(max_ratio_det_J_z, max_det_J_z/min_det_J_z);
745 min_det_J = std::min(min_det_J, min_det_J_z);
746 max_det_J = std::max(max_det_J, max_det_J_z);
747 if (min_det_J_z <= 0.0)
748 {
749 if (nz < max_to_print)
750 {
751 Vector center;
752 mesh->GetElementCenter(i, center);
753 cout << "det(J) < 0 = " << min_det_J_z << " in element "
754 << i << ", centered at: ";
755 center.Print();
756 }
757 nz++;
758 bad_elems_by_geom[geom]++;
759 }
760 }
761 if (nz >= max_to_print)
762 {
763 cout << "det(J) < 0 for " << nz - max_to_print << " more elements "
764 << "not printed.\n";
765 }
766 cout << "\nbad elements = " << nz;
767 if (nz)
768 {
769 cout << " -- ";
770 Mesh::PrintElementsByGeometry(dim, bad_elems_by_geom, cout);
771 }
772 cout << "\nmin det(J) = " << min_det_J
773 << "\nmax det(J) = " << max_det_J
774 << "\nglobal ratio = " << max_det_J/min_det_J
775 << "\nmax el ratio = " << max_ratio_det_J_z
776 << "\nmin kappa = " << min_kappa
777 << "\nmax kappa = " << max_kappa << endl;
778 }
779
780 if (mk == 'f')
781 {
782 DenseMatrix point_mat(sdim,1);
783 cout << "\npoint in physical space ---> " << flush;
784 for (int i = 0; i < sdim; i++)
785 {
786 cin >> point_mat(i,0);
787 }
788 Array<int> elem_ids;
790
791 // physical -> reference space
792 mesh->FindPoints(point_mat, elem_ids, ips);
793
794 cout << "point in reference space:";
795 if (elem_ids[0] == -1)
796 {
797 cout << " NOT FOUND!\n";
798 }
799 else
800 {
801 cout << " element " << elem_ids[0] << ", ip =";
802 cout << " " << ips[0].x;
803 if (sdim > 1)
804 {
805 cout << " " << ips[0].y;
806 if (sdim > 2)
807 {
808 cout << " " << ips[0].z;
809 }
810 }
811 cout << endl;
812 }
813 }
814
815 if (mk == 'o')
816 {
817 cout << "What type of reordering?\n"
818 "g) Gecko edge-product minimization\n"
819 "h) Hilbert spatial sort\n"
820 "--> " << flush;
821 char rk;
822 cin >> rk;
823
824 Array<int> ordering, tentative;
825 if (rk == 'h')
826 {
827 mesh->GetHilbertElementOrdering(ordering);
828 mesh->ReorderElements(ordering);
829 }
830 else if (rk == 'g')
831 {
832 int outer, inner, window, period;
833 cout << "Enter number of outer iterations (default 5): " << flush;
834 cin >> outer;
835 cout << "Enter number of inner iterations (default 4): " << flush;
836 cin >> inner;
837 cout << "Enter window size (default 4, beware of exponential cost): "
838 << flush;
839 cin >> window;
840 cout << "Enter period for window size increment (default 2): "
841 << flush;
842 cin >> period;
843
844 real_t best_cost = infinity();
845 for (int i = 0; i < outer; i++)
846 {
847 int seed = i+1;
848 real_t cost = mesh->GetGeckoElementOrdering(
849 tentative, inner, window, period, seed, true);
850
851 if (cost < best_cost)
852 {
853 ordering = tentative;
854 best_cost = cost;
855 }
856 }
857 cout << "Final cost: " << best_cost << endl;
858
859 mesh->ReorderElements(ordering);
860 }
861 }
862
863 // These are most of the cases that open a new GLVis window
864 if (mk == 'm' || mk == 'b' || mk == 'e' || mk == 'v' || mk == 'h' ||
865 mk == 'k' || mk == 'J' || mk == 'p' || mk == 'B' || mk == 'P')
866 {
867 FiniteElementSpace *bdr_attr_fespace = NULL;
868 FiniteElementSpace *attr_fespace =
869 new FiniteElementSpace(mesh, attr_fec);
870 GridFunction bdr_attr;
871 GridFunction attr(attr_fespace);
872
873 if (mk == 'm')
874 {
875 for (int i = 0; i < mesh->GetNE(); i++)
876 {
877 attr(i) = mesh->GetAttribute(i);
878 }
879 }
880
881 if (mk == 'P')
882 {
883 for (int i = 0; i < mesh->GetNE(); i++)
884 {
885 attr(i) = partitioning[i] + 1;
886 }
887 }
888
889 if (mk == 'b' || mk == 'B')
890 {
891 if (dim == 3)
892 {
893 delete bdr_mesh;
894 bdr_mesh = skin_mesh(mesh);
895 bdr_attr_fespace =
896 new FiniteElementSpace(bdr_mesh, bdr_attr_fec);
897 bdr_attr.SetSpace(bdr_attr_fespace);
898 if (mk == 'b')
899 {
900 for (int i = 0; i < bdr_mesh->GetNE(); i++)
901 {
902 bdr_attr(i) = bdr_mesh->GetAttribute(i);
903 }
904 }
905 else if (mk == 'B')
906 {
907 for (int i = 0; i < bdr_mesh->GetNE(); i++)
908 {
909 bdr_attr(i) = bdr_partitioning[i] + 1;
910 }
911 }
912 else
913 {
914 MFEM_WARNING("Unimplemented case.");
915 }
916 }
917 else
918 {
919 MFEM_WARNING("Unsupported mesh dimension.");
920 attr = 1.0;
921 }
922 }
923
924 if (mk == 'v')
925 {
926 attr = 1.0;
927 }
928
929 if (mk == 'e')
930 {
931 Array<int> coloring;
932 srand(time(0));
933 real_t a = rand_real();
934 int el0 = (int)floor(a * mesh->GetNE());
935 cout << "Generating coloring starting with element " << el0+1
936 << " / " << mesh->GetNE() << endl;
937 mesh->GetElementColoring(coloring, el0);
938 for (int i = 0; i < coloring.Size(); i++)
939 {
940 attr(i) = coloring[i];
941 }
942 cout << "Number of colors: " << attr.Max() + 1 << endl;
943 for (int i = 0; i < mesh->GetNE(); i++)
944 {
945 attr(i) = elem_partitioning[i] = i; // coloring by element number
946 }
947 cout << "GLVis keystrokes for mesh element visualization:\n"
948 << "- F3/F4 - Shrink/Zoom the elements\n"
949 << "- Ctrl+F3/F4 - 3D: cut holes in element faces \n"
950 << "- F8 - 3D: toggle visible elements\n"
951 << "- F9/F10 - 3D: cycle through visible elements\n";
952 }
953
954 if (mk == 'h')
955 {
956 DenseMatrix J(dim);
957 real_t h_min, h_max;
958 h_min = infinity();
959 h_max = -h_min;
960 for (int i = 0; i < mesh->GetNE(); i++)
961 {
965 Geometries.JacToPerfJac(geom, T->Jacobian(), J);
966
967 attr(i) = J.Det();
968 if (attr(i) < 0.0)
969 {
970 attr(i) = -pow(-attr(i), 1.0/real_t(dim));
971 }
972 else
973 {
974 attr(i) = pow(attr(i), 1.0/real_t(dim));
975 }
976 h_min = min(h_min, attr(i));
977 h_max = max(h_max, attr(i));
978 }
979 cout << "h_min = " << h_min << ", h_max = " << h_max << endl;
980 }
981
982 if (mk == 'k')
983 {
984 DenseMatrix J(dim);
985 for (int i = 0; i < mesh->GetNE(); i++)
986 {
990 Geometries.JacToPerfJac(geom, T->Jacobian(), J);
991 attr(i) = J.CalcSingularvalue(0) / J.CalcSingularvalue(dim-1);
992 }
993 }
994
995 if (mk == 'J')
996 {
997 // The "scaled Jacobian" is the determinant of the Jacobian scaled
998 // by the l2 norms of its columns. It can be used to identify badly
999 // skewed elements, since it takes values between 0 and 1, with 0
1000 // corresponding to a flat element, and 1 to orthogonal columns.
1001 DenseMatrix J(dim);
1002 int sd;
1003 cout << "subdivision factor ---> " << flush;
1004 cin >> sd;
1005 for (int i = 0; i < mesh->GetNE(); i++)
1006 {
1007 Geometry::Type geom = mesh->GetElementBaseGeometry(i);
1009
1010 RefinedGeometry *RefG = GlobGeometryRefiner.Refine(geom, sd, 1);
1011 IntegrationRule &ir = RefG->RefPts;
1012
1013 // For each element, find the minimal scaled Jacobian in a
1014 // lattice of points with the given subdivision factor.
1015 attr(i) = infinity();
1016 for (int j = 0; j < ir.GetNPoints(); j++)
1017 {
1018 T->SetIntPoint(&ir.IntPoint(j));
1019 Geometries.JacToPerfJac(geom, T->Jacobian(), J);
1020
1021 // Jacobian determinant
1022 real_t sJ = J.Det();
1023
1024 for (int k = 0; k < J.Width(); k++)
1025 {
1026 Vector col;
1027 J.GetColumnReference(k,col);
1028 // Scale by column norms
1029 sJ /= col.Norml2();
1030 }
1031
1032 attr(i) = std::min(sJ, attr(i));
1033 }
1034 }
1035 }
1036
1037 if (mk == 'p')
1038 {
1039 cout << "What type of partitioning?\n"
1040 "c) Cartesian\n"
1041 "s) Simple 1D split of the element sequence\n"
1042 "0) METIS_PartGraphRecursive (sorted neighbor lists)\n"
1043 "1) METIS_PartGraphKway (sorted neighbor lists)"
1044 " (default)\n"
1045 "2) METIS_PartGraphVKway (sorted neighbor lists)\n"
1046 "3) METIS_PartGraphRecursive\n"
1047 "4) METIS_PartGraphKway\n"
1048 "5) METIS_PartGraphVKway\n"
1049 "--> " << flush;
1050 char pk;
1051 cin >> pk;
1052 if (pk == 'c')
1053 {
1054 int nxyz[3];
1055 cout << "Enter nx: " << flush;
1056 cin >> nxyz[0]; np = nxyz[0];
1057 if (mesh->Dimension() > 1)
1058 {
1059 cout << "Enter ny: " << flush;
1060 cin >> nxyz[1]; np *= nxyz[1];
1061 if (mesh->Dimension() > 2)
1062 {
1063 cout << "Enter nz: " << flush;
1064 cin >> nxyz[2]; np *= nxyz[2];
1065 }
1066 }
1067 int *part = mesh->CartesianPartitioning(nxyz);
1068 partitioning = Array<int>(part, mesh->GetNE());
1069 delete [] part;
1070 recover_bdr_partitioning(mesh, partitioning, bdr_partitioning);
1071 }
1072 else if (pk == 's')
1073 {
1074 cout << "Enter number of processors: " << flush;
1075 cin >> np;
1076
1077 partitioning.SetSize(mesh->GetNE());
1078 for (int i = 0; i < mesh->GetNE(); i++)
1079 {
1080 partitioning[i] = (long long)i * np / mesh->GetNE();
1081 }
1082 recover_bdr_partitioning(mesh, partitioning, bdr_partitioning);
1083 }
1084 else
1085 {
1086 int part_method = pk - '0';
1087 if (part_method < 0 || part_method > 5)
1088 {
1089 continue;
1090 }
1091 cout << "Enter number of processors: " << flush;
1092 cin >> np;
1093 int *part = mesh->GeneratePartitioning(np, part_method);
1094 partitioning = Array<int>(part, mesh->GetNE());
1095 delete [] part;
1096 recover_bdr_partitioning(mesh, partitioning, bdr_partitioning);
1097 }
1098 if (partitioning)
1099 {
1100 const char part_file[] = "partitioning.txt";
1101 ofstream opart(part_file);
1102 opart << "number_of_elements " << mesh->GetNE() << '\n'
1103 << "number_of_processors " << np << '\n';
1104 for (int i = 0; i < mesh->GetNE(); i++)
1105 {
1106 opart << partitioning[i] << '\n';
1107 }
1108 cout << "Partitioning file: " << part_file << endl;
1109
1110 Array<int> proc_el(np);
1111 proc_el = 0;
1112 for (int i = 0; i < mesh->GetNE(); i++)
1113 {
1114 proc_el[partitioning[i]]++;
1115 }
1116 int min_el = proc_el[0], max_el = proc_el[0];
1117 for (int i = 1; i < np; i++)
1118 {
1119 if (min_el > proc_el[i])
1120 {
1121 min_el = proc_el[i];
1122 }
1123 if (max_el < proc_el[i])
1124 {
1125 max_el = proc_el[i];
1126 }
1127 }
1128 cout << "Partitioning stats:\n"
1129 << " "
1130 << setw(12) << "minimum"
1131 << setw(12) << "average"
1132 << setw(12) << "maximum"
1133 << setw(12) << "total" << '\n';
1134 cout << " elements "
1135 << setw(12) << min_el
1136 << setw(12) << real_t(mesh->GetNE())/np
1137 << setw(12) << max_el
1138 << setw(12) << mesh->GetNE() << endl;
1139 }
1140 else
1141 {
1142 continue;
1143 }
1144
1145 for (int i = 0; i < mesh->GetNE(); i++)
1146 {
1147 attr(i) = partitioning[i] + 1;
1148 }
1149 }
1150
1151 char vishost[] = "localhost";
1152 socketstream sol_sock(vishost, visport);
1153 if (sol_sock.is_open())
1154 {
1155 sol_sock.precision(14);
1156 if (sdim == 2)
1157 {
1158 sol_sock << "fem2d_gf_data_keys\n";
1159 if (mk != 'p')
1160 {
1161 mesh->Print(sol_sock);
1162 }
1163 else
1164 {
1165 // NURBS meshes do not support PrintWithPartitioning
1166 if (mesh->NURBSext)
1167 {
1168 mesh->Print(sol_sock);
1169 for (int i = 0; i < mesh->GetNE(); i++)
1170 {
1171 attr(i) = partitioning[i];
1172 }
1173 }
1174 else
1175 {
1176 if (mk == 'e')
1177 {
1178 mesh->PrintWithPartitioning(elem_partitioning, sol_sock, 1);
1179 }
1180 else
1181 {
1182 mesh->PrintWithPartitioning(partitioning, sol_sock, 1);
1183 }
1184 }
1185 }
1186 attr.Save(sol_sock);
1187 sol_sock << "RjlmAb***********";
1188 if (mk == 'v')
1189 {
1190 sol_sock << "e";
1191 }
1192 else
1193 {
1194 sol_sock << "\n";
1195 }
1196 }
1197 else
1198 {
1199 sol_sock << "fem3d_gf_data_keys\n";
1200 if (mk == 'v' || mk == 'h' || mk == 'k' || mk == 'J')
1201 {
1202 mesh->Print(sol_sock);
1203 }
1204 else if (mk == 'b' || mk == 'B')
1205 {
1206 bdr_mesh->Print(sol_sock);
1207 bdr_attr.Save(sol_sock);
1208 sol_sock << "mcaaA";
1209 // Switch to a discrete color scale
1210 sol_sock << "pppppp" << "pppppp" << "pppppp";
1211 }
1212 else
1213 {
1214 // NURBS meshes do not support PrintWithPartitioning
1215 if (mesh->NURBSext)
1216 {
1217 mesh->Print(sol_sock);
1218 for (int i = 0; i < mesh->GetNE(); i++)
1219 {
1220 attr(i) = partitioning[i];
1221 }
1222 }
1223 else
1224 {
1225 if (mk == 'e')
1226 {
1227 mesh->PrintWithPartitioning(elem_partitioning, sol_sock, 1);
1228 }
1229 else
1230 {
1231 mesh->PrintWithPartitioning(partitioning, sol_sock, 1);
1232 }
1233 }
1234 }
1235 if (mk != 'b' && mk != 'B')
1236 {
1237 attr.Save(sol_sock);
1238 sol_sock << "maaA";
1239 if (mk == 'v')
1240 {
1241 sol_sock << "aa";
1242 }
1243 else
1244 {
1245 sol_sock << "\n";
1246 }
1247 }
1248 }
1249 sol_sock << flush;
1250 }
1251 else
1252 {
1253 cout << "Unable to connect to "
1254 << vishost << ':' << visport << endl;
1255 }
1256 delete attr_fespace;
1257 delete bdr_attr_fespace;
1258 }
1259
1260 if (mk == 'l')
1261 {
1262 // Project and plot the function 'f'
1263 int p;
1264 FiniteElementCollection *fec = NULL;
1265 cout << "Enter projection space order: " << flush;
1266 cin >> p;
1267 if (p >= 1)
1268 {
1269 fec = new H1_FECollection(p, mesh->Dimension(),
1271 }
1272 else
1273 {
1274 fec = new DG_FECollection(-p, mesh->Dimension(),
1276 }
1277 FiniteElementSpace fes(mesh, fec);
1278 GridFunction level(&fes);
1279 FunctionCoefficient coeff(f);
1280 level.ProjectCoefficient(coeff);
1281 char vishost[] = "localhost";
1282 socketstream sol_sock(vishost, visport);
1283 if (sol_sock.is_open())
1284 {
1285 sol_sock.precision(14);
1286 sol_sock << "solution\n" << *mesh << level << flush;
1287 }
1288 else
1289 {
1290 cout << "Unable to connect to "
1291 << vishost << ':' << visport << endl;
1292 }
1293 delete fec;
1294 }
1295
1296 if (mk == 'S')
1297 {
1298 const char omesh_file[] = "mesh-explorer.mesh";
1299 ofstream omesh(omesh_file);
1300 omesh.precision(14);
1301 mesh->Print(omesh);
1302 cout << "New mesh file: " << omesh_file << endl;
1303 }
1304
1305 if (mk == 'T')
1306 {
1307 string mesh_prefix("mesh-explorer.mesh."), line;
1308 MeshPartitioner partitioner(*mesh, np, partitioning);
1309 MeshPart mesh_part;
1310 cout << "Enter mesh file prefix or press <enter> to use \""
1311 << mesh_prefix << "\": " << flush;
1312 // extract and ignore all characters after 'T' up to and including the
1313 // new line:
1314 cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
1315 getline(cin, line);
1316 if (!line.empty()) { mesh_prefix = line; }
1317 int precision;
1318 cout << "Enter floating point output precision (num. digits): "
1319 << flush;
1320 cin >> precision;
1321 for (int i = 0; i < np; i++)
1322 {
1323 partitioner.ExtractPart(i, mesh_part);
1324
1325 ofstream omesh(MakeParFilename(mesh_prefix, i));
1326 omesh.precision(precision);
1327 mesh_part.Print(omesh);
1328 }
1329 cout << "New parallel mesh files: " << mesh_prefix << "<rank>" << endl;
1330 }
1331
1332 if (mk == 'V')
1333 {
1334 const char omesh_file[] = "mesh-explorer.vtk";
1335 ofstream omesh(omesh_file);
1336 omesh.precision(14);
1337 mesh->PrintVTK(omesh);
1338 cout << "New VTK mesh file: " << omesh_file << endl;
1339 }
1340
1341#ifdef MFEM_USE_NETCDF
1342 if (mk == 'X')
1343 {
1344 const char omesh_file[] = "mesh-explorer.e";
1345 mesh->PrintExodusII(omesh_file);
1346 cout << "New Exodus II mesh file: " << omesh_file << endl;
1347 }
1348#endif
1349
1350 if (mk == 'D')
1351 {
1352 cout << "What type of DataCollection?\n"
1353 "p) ParaView Data Collection\n"
1354 "v) VisIt Data Collection\n"
1355 "--> " << flush;
1356 char dk;
1357 cin >> dk;
1358 if (dk == 'p' || dk == 'P')
1359 {
1360 const char omesh_file[] = "mesh-explorer-paraview";
1361 ParaViewDataCollection dc(omesh_file, mesh);
1362 if (mesh->GetNodes())
1363 {
1364 int order = mesh->GetNodes()->FESpace()->GetMaxElementOrder();
1365 if (order > 1)
1366 {
1367 dc.SetHighOrderOutput(true);
1368 dc.SetLevelsOfDetail(order);
1369 }
1370 }
1371 dc.Save();
1372 cout << "New ParaView mesh file: " << omesh_file << endl;
1373 }
1374 else if (dk == 'v' || dk == 'V')
1375 {
1376 const char omesh_file[] = "mesh-explorer-visit";
1377 VisItDataCollection dc(omesh_file, mesh);
1378 dc.SetPrecision(14);
1379 dc.Save();
1380 cout << "New VisIt mesh file: " << omesh_file << "_000000.mfem_root"
1381 << endl;
1382 }
1383 else
1384 {
1385 cout << "Unrecognized DataCollection type: \"" << dk << "\""
1386 << endl;
1387 }
1388 }
1389
1390#ifdef MFEM_USE_ZLIB
1391 if (mk == 'Z')
1392 {
1393 const char omesh_file[] = "mesh-explorer.mesh.gz";
1394 ofgzstream omesh(omesh_file, "zwb9");
1395 omesh.precision(14);
1396 mesh->Print(omesh);
1397 cout << "New mesh file: " << omesh_file << endl;
1398 }
1399#endif
1400
1401 }
1402
1403 delete bdr_attr_fec;
1404 delete attr_fec;
1405 delete bdr_mesh;
1406 delete mesh;
1407 return 0;
1408}
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:758
int Size() const
Return the logical size of the array.
Definition array.hpp:147
void DeleteAll()
Delete the whole array.
Definition array.hpp:925
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Definition array.hpp:830
@ GaussLobatto
Closed type.
Definition fe_base.hpp:36
@ GaussLegendre
Open type.
Definition fe_base.hpp:35
@ ClosedUniform
Nodes: x_i = i/(n-1), i=0,...,n-1.
Definition fe_base.hpp:39
Piecewise-constant discontinuous finite elements in 2D. This class is kept only for backward compatib...
Definition fe_coll.hpp:1094
Piecewise-constant discontinuous finite elements in 3D. This class is kept only for backward compatib...
Definition fe_coll.hpp:1285
void SetPrecision(int prec)
Set the precision (number of digits) used for the text output of doubles.
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void GetColumnReference(int c, Vector &col)
Definition densemat.hpp:319
real_t CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
real_t Det() const
Definition densemat.cpp:516
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint,...
Definition eltrans.hpp:132
void SetIntPoint(const IntegrationPoint *ip)
Set the integration point ip that weights and Jacobians will be evaluated at.
Definition eltrans.hpp:106
Abstract data type element.
Definition element.hpp:29
Geometry::Type GetGeometryType() const
Definition element.hpp:55
virtual void GetVertices(Array< int > &v) const =0
Get the indices defining the vertices.
int GetAttribute() const
Return element's attribute.
Definition element.hpp:58
virtual int GetNVertices() const =0
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition fe_coll.hpp:27
static FiniteElementCollection * New(const char *name)
Factory method: return a newly allocated FiniteElementCollection according to the given name.
Definition fe_coll.cpp:124
virtual const char * Name() const
Definition fe_coll.hpp:79
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:244
DofTransformation * GetElementDofs(int elem, Array< int > &dofs) const
Returns indices of degrees of freedom of element 'elem'. The returned indices are offsets into an ldo...
Definition fespace.cpp:3513
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
Definition fespace.hpp:845
int GetNBE() const
Returns number of boundary elements in the mesh.
Definition fespace.hpp:900
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 ...
Definition fespace.cpp:332
int GetNE() const
Returns number of elements in the mesh.
Definition fespace.hpp:891
const FiniteElementCollection * FEColl() const
Definition fespace.hpp:878
DofTransformation * GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for i'th boundary element. The returned indices are offsets int...
Definition fespace.cpp:348
int DofToVDof(int dof, int vd, int ndofs=-1) const
Compute a single vdof corresponding to the index dof and the vector index vd.
Definition fespace.cpp:294
A general function coefficient.
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
Definition geom.cpp:1136
static const int NumGeom
Definition geom.hpp:46
const IntegrationPoint & GetCenter(int GeomType) const
Return the center of the given Geometry::Type, GeomType.
Definition geom.hpp:75
void JacToPerfJac(int GeomType, const DenseMatrix &J, DenseMatrix &PJ) const
Definition geom.cpp:909
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:31
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
void MakeOwner(FiniteElementCollection *fec_)
Make the GridFunction the owner of fec_owned and fes.
Definition gridfunc.hpp:122
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
virtual void SetSpace(FiniteElementSpace *f)
Associate a new FiniteElementSpace with the GridFunction.
Definition gridfunc.cpp:225
Arbitrary order H1-conforming (continuous) finite elements.
Definition fe_coll.hpp:275
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:100
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition intrules.hpp:256
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition intrules.hpp:259
A standard isoparametric element transformation.
Definition eltrans.hpp:629
const DenseMatrix & GetPointMat() const
Return the stored point matrix.
Definition eltrans.hpp:671
Class containing a minimal description of a part (a subset of the elements) of a Mesh and its connect...
Definition mesh.hpp:2626
void Print(std::ostream &os) const
Write the MeshPart to a stream using the parallel format "MFEM mesh v1.2".
Definition mesh.cpp:13663
Class that allows serial meshes to be partitioned into MeshPart objects, typically one MeshPart at a ...
Definition mesh.hpp:2854
void ExtractPart(int part_id, MeshPart &mesh_part) const
Construct a MeshPart corresponding to the given part_id.
Definition mesh.cpp:13998
Mesh data type.
Definition mesh.hpp:64
void NURBSCoarsening(int cf=2, real_t tol=1.0e-12)
Definition mesh.cpp:10827
int AddSegment(int v1, int v2, int attr=1)
Adds a segment to the mesh given by 2 vertices v1 and v2.
Definition mesh.cpp:1930
void GetElementColoring(Array< int > &colors, int el0=0)
Definition mesh.cpp:12372
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition mesh.hpp:290
NURBSExtension * NURBSext
Optional NURBS mesh extension.
Definition mesh.hpp:298
int * CartesianPartitioning(int nxyz[])
Definition mesh.cpp:8372
void GeneralRefinement(const Array< Refinement > &refinements, int nonconforming=-1, int nc_limit=0)
Definition mesh.cpp:10883
int GetAttribute(int i) const
Return the attribute of element i.
Definition mesh.hpp:1389
int AddQuad(int v1, int v2, int v3, int v4, int attr=1)
Adds a quadrilateral to the mesh given by 4 vertices v1 through v4.
Definition mesh.cpp:1958
const FiniteElementSpace * GetNodalFESpace() const
Definition mesh.cpp:6479
void PrintCharacteristics(Vector *Vh=NULL, Vector *Vk=NULL, std::ostream &os=mfem::out)
Compute and print mesh characteristics such as number of vertices, number of elements,...
Definition mesh.cpp:251
int AddTriangle(int v1, int v2, int v3, int attr=1)
Adds a triangle to the mesh given by 3 vertices v1 through v3.
Definition mesh.cpp:1944
real_t GetGeckoElementOrdering(Array< int > &ordering, int iterations=4, int window=4, int period=2, int seed=0, bool verbose=false, real_t time_limit=0)
Definition mesh.cpp:2466
void FinalizeTopology(bool generate_bdr=true)
Finalize the construction of the secondary topology (connectivity) data of a Mesh.
Definition mesh.cpp:3362
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
Definition mesh.hpp:2433
void PrintWithPartitioning(int *partitioning, std::ostream &os, int elem_attr=0) const
Prints the mesh with boundary elements given by the boundary of the subdomains, so that the boundary ...
Definition mesh.cpp:12447
int AddVertex(real_t x, real_t y=0.0, real_t z=0.0)
Definition mesh.cpp:1873
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1282
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
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
Definition mesh.hpp:1354
void ReorderElements(const Array< int > &ordering, bool reorder_vertices=true)
Definition mesh.cpp:2685
static Mesh MakeRefined(Mesh &orig_mesh, int ref_factor, int ref_type)
Create a refined (by any factor) version of orig_mesh.
Definition mesh.cpp:4518
real_t GetElementSize(int i, int type=0)
Get the size of the i-th element relative to the perfect reference element.
Definition mesh.cpp:107
void GetElementTransformation(int i, IsoparametricTransformation *ElTr) const
Builds the transformation defining the i-th element in ElTr. ElTr must be allocated in advance and wi...
Definition mesh.cpp:357
int SpaceDimension() const
Dimension of the physical space containing the mesh.
Definition mesh.hpp:1219
void GetNodes(Vector &node_coord) const
Definition mesh.cpp:9294
void PrintExodusII(const std::string fpath)
Export a mesh to an Exodus II file.
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
Definition mesh.hpp:1279
void GetHilbertElementOrdering(Array< int > &ordering)
Definition mesh.cpp:2633
void GetBdrElementAdjacentElement(int bdr_el, int &el, int &info) const
For the given boundary element, bdr_el, return its adjacent element and its info, i....
Definition mesh.cpp:7584
void GetElementCenter(int i, Vector &center)
Definition mesh.cpp:77
static void PrintElementsByGeometry(int dim, const Array< int > &num_elems_by_geom, std::ostream &os)
Auxiliary method used by PrintCharacteristics().
Definition mesh.cpp:237
int GetNBE() const
Returns number of boundary elements.
Definition mesh.hpp:1285
virtual void Finalize(bool refine=false, bool fix_orientation=false)
Finalize the construction of a general Mesh.
Definition mesh.cpp:3468
virtual int FindPoints(DenseMatrix &point_mat, Array< int > &elem_ids, Array< IntegrationPoint > &ips, bool warn=true, InverseElementTransformation *inv_trans=NULL)
Find the ids of the elements that contain the given points, and their corresponding reference coordin...
Definition mesh.cpp:13406
void NewNodes(GridFunction &nodes, bool make_owner=false)
Replace the internal node GridFunction with the given GridFunction.
Definition mesh.cpp:9321
virtual void NURBSUniformRefinement(int rf=2, real_t tol=1.0e-12)
Refine NURBS mesh, with an optional refinement factor, generally anisotropic.
Definition mesh.cpp:6003
void EnsureNCMesh(bool simplices_nonconforming=false)
Definition mesh.cpp:10951
void PrintVTK(std::ostream &os)
Definition mesh.cpp:11820
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 Transform(void(*f)(const Vector &, Vector &))
Definition mesh.cpp:13146
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Definition mesh.cpp:11295
Geometry::Type GetElementBaseGeometry(int i) const
Definition mesh.hpp:1455
int * GeneratePartitioning(int nparts, int part_method=1)
Definition mesh.cpp:8416
Array< int > attributes
A list of all unique element attributes used by the Mesh.
Definition mesh.hpp:288
const real_t * GetVertex(int i) const
Return pointer to vertex i's coordinates.
Definition mesh.hpp:1321
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:72
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintOptions(std::ostream &out) const
Print the options.
void PrintHelp(std::ostream &out) const
Print the help message.
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.
bool Help() const
Return true if we are flagged to print the help message.
void PrintError(std::ostream &out) const
Print the error message.
Helper class for ParaView visualization data.
void SetHighOrderOutput(bool high_order_output_)
void SetLevelsOfDetail(int levels_of_detail_)
IntegrationRule RefPts
Definition geom.hpp:321
Vector data type.
Definition vector.hpp:82
void Randomize(int seed=0)
Set random values in the vector.
Definition vector.cpp:915
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
Definition vector.cpp:830
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
Definition vector.cpp:679
real_t Norml2() const
Returns the l2 norm of the vector.
Definition vector.cpp:931
real_t Max() const
Returns the maximal element of the vector.
Definition vector.cpp:1164
Data collection with VisIt I/O routines.
void Save() override
Save the collection and a VisIt root file.
bool is_open()
True if the socketstream is open, false otherwise.
real_t kappa
Definition ex24.cpp:54
int dim
Definition ex24.cpp:53
int main()
real_t a
Definition lissajous.cpp:41
Mesh * skin_mesh(Mesh *mesh)
real_t f(const Vector &p)
real_t region_eps
Mesh * read_par_mesh(int np, const char *mesh_prefix, Array< int > &partitioning, Array< int > &bdr_partitioning)
void transformation(const Vector &p, Vector &v)
void recover_bdr_partitioning(const Mesh *mesh, const Array< int > &partitioning, Array< int > &bdr_partitioning)
real_t region(const Vector &p)
real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
Definition vector.hpp:47
std::string MakeParFilename(const std::string &prefix, const int myid, const std::string suffix, const int width)
Construct a string of the form "<prefix><myid><suffix>" where the integer myid is padded with leading...
Definition globals.cpp:48
GeometryRefiner GlobGeometryRefiner
Definition geom.cpp:2014
Geometry Geometries
Definition fe.cpp:49
real_t rand_real()
Generate a random real_t number in the interval [0,1) using rand().
Definition vector.hpp:61
L2_FECollection DG_FECollection
Declare an alternative name for L2_FECollection = DG_FECollection.
Definition fe_coll.hpp:399
float real_t
Definition config.hpp:43
const char vishost[]
real_t p(const Vector &x, real_t t)
std::array< int, NCMesh::MaxFaceNodes > nodes