MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
mesh-explorer.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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 bool refine = true;
269
270 OptionsParser args(argc, argv);
271 args.AddOption(&mesh_file, "-m", "--mesh",
272 "Mesh file to visualize.");
273 args.AddOption(&np, "-np", "--num-proc",
274 "Load mesh from multiple processors.");
275 args.AddOption(&refine, "-ref", "--refinement", "-no-ref", "--no-refinement",
276 "Prepare the mesh for refinement or not.");
277 args.Parse();
278 if (!args.Good())
279 {
280 if (!args.Help())
281 {
282 args.PrintError(cout);
283 cout << endl;
284 }
285 cout << "Visualize and manipulate a serial mesh:\n"
286 << " mesh-explorer -m <mesh_file>\n"
287 << "Visualize and manipulate a parallel mesh:\n"
288 << " mesh-explorer -np <#proc> -m <mesh_prefix>\n" << endl
289 << "All Options:\n";
290 args.PrintHelp(cout);
291 return 1;
292 }
293 args.PrintOptions(cout);
294
295 Mesh *mesh;
296 Mesh *bdr_mesh = NULL;
297
298 // Helper to distinguish whether we use a parallel or serial mesh.
299 const bool use_par_mesh = np > 0;
300
301 // Helper for visualizing the partitioning.
302 Array<int> partitioning;
303 Array<int> bdr_partitioning;
304 if (!use_par_mesh)
305 {
306 mesh = new Mesh(mesh_file, 1, refine);
307 partitioning.SetSize(mesh->GetNE());
308 partitioning = 0;
309 bdr_partitioning.SetSize(mesh->GetNBE());
310 bdr_partitioning = 0;
311 np = 1;
312 }
313 else
314 {
315 mesh = read_par_mesh(np, mesh_file, partitioning, bdr_partitioning);
316 if (mesh == NULL)
317 {
318 return 3;
319 }
320 }
321 int dim = mesh->Dimension();
322 int sdim = mesh->SpaceDimension();
323
324 FiniteElementCollection *bdr_attr_fec = NULL;
325 FiniteElementCollection *attr_fec;
326 if (dim == 2)
327 {
328 attr_fec = new Const2DFECollection;
329 }
330 else
331 {
332 bdr_attr_fec = new Const2DFECollection;
333 attr_fec = new Const3DFECollection;
334 }
335
336 int print_char = 1;
337 while (1)
338 {
339 if (print_char)
340 {
341 cout << endl;
342 mesh->PrintCharacteristics();
343 cout << "boundary attribs :";
344 for (int i = 0; i < mesh->bdr_attributes.Size(); i++)
345 {
346 cout << ' ' << mesh->bdr_attributes[i];
347 }
348 cout << '\n' << "material attribs :";
349 for (int i = 0; i < mesh->attributes.Size(); i++)
350 {
351 cout << ' ' << mesh->attributes[i];
352 }
353 cout << endl;
354 cout << "mesh curvature : ";
355 if (mesh->GetNodalFESpace() != NULL)
356 {
357 cout << mesh->GetNodalFESpace()->FEColl()->Name() << endl;
358 }
359 else
360 {
361 cout << "NONE" << endl;
362 }
363 }
364 print_char = 0;
365 cout << endl;
366 cout << "What would you like to do?\n"
367 "r) Refine\n"
368 "c) Change curvature\n"
369 "s) Scale\n"
370 "t) Transform\n"
371 "j) Jitter\n"
372 "v) View mesh\n"
373 "P) View partitioning\n"
374 "m) View materials\n"
375 "b) View boundary\n"
376 "B) View boundary partitioning\n"
377 "e) View elements\n"
378 "h) View element sizes, h\n"
379 "k) View element ratios, kappa\n"
380 "J) View scaled Jacobian\n"
381 "l) Plot a function\n"
382 "x) Print sub-element stats\n"
383 "f) Find physical point in reference space\n"
384 "p) Generate a partitioning\n"
385 "o) Reorder elements\n"
386 "S) Save in MFEM serial format\n"
387 "T) Save in MFEM parallel format using the current partitioning\n"
388 "V) Save in VTK format (only linear and quadratic meshes)\n"
389 "D) Save as a DataCollection\n"
390 "q) Quit\n"
391#ifdef MFEM_USE_ZLIB
392 "Z) Save in MFEM format with compression\n"
393#endif
394 "--> " << flush;
395 char mk;
396 cin >> mk;
397 if (!cin) { break; }
398
399 if (mk == 'q')
400 {
401 break;
402 }
403
404 if (mk == 'r')
405 {
406 cout <<
407 "Choose type of refinement:\n"
408 "s) standard refinement with Mesh::UniformRefinement()\n"
409 "b) Mesh::UniformRefinement() (bisection for tet meshes)\n"
410 "u) uniform refinement with a factor\n"
411 "g) non-uniform refinement (Gauss-Lobatto) with a factor\n"
412 "n) NURBS refinement (uniform or by formula) with a factor\n"
413 "c) NURBS coarsening (uniform or by formula) with a factor\n"
414 "l) refine locally using the region() function\n"
415 "r) random refinement with a probability\n"
416 "--> " << flush;
417 char sk;
418 cin >> sk;
419 switch (sk)
420 {
421 case 's':
422 mesh->UniformRefinement();
423 // Make sure tet-only meshes are marked for local refinement.
424 mesh->Finalize(true);
425 break;
426 case 'b':
427 mesh->UniformRefinement(1); // ref_algo = 1
428 break;
429 case 'u':
430 case 'g':
431 {
432 cout << "enter refinement factor --> " << flush;
433 int ref_factor;
434 cin >> ref_factor;
435 if (ref_factor <= 1 || ref_factor > 32) { break; }
436 int ref_type = (sk == 'u') ? BasisType::ClosedUniform :
438 *mesh = Mesh::MakeRefined(*mesh, ref_factor, ref_type);
439 break;
440 }
441 case 'n':
442 {
443 Array<int> ref_factors(dim);
444 cout << "enter refinement factor, 1st dimension --> " << flush;
445 cin >> ref_factors[0];
446 cout << "enter refinement factor, 2nd dimension --> " << flush;
447 cin >> ref_factors[1];
448 if (dim == 3)
449 {
450 cout << "enter refinement factor, 3rd dimension --> "
451 << flush;
452 cin >> ref_factors[2];
453 }
454 for (auto ref_factor : ref_factors)
455 if (ref_factor <= 1 || ref_factor > 32) { break; }
456
457 char input_tol = 'n';
458 cout << "enter NURBS tolerance? [y/n] ---> " << flush;
459 cin >> input_tol;
460
461 real_t tol = 1.0e-12; // Default value
462 if (input_tol == 'y')
463 {
464 cout << "enter NURBS tolerance ---> " << flush;
465 cin >> tol;
466 }
467
468 mesh->NURBSUniformRefinement(ref_factors, tol);
469 break;
470 }
471 case 'c':
472 {
473 cout << "enter coarsening factor --> " << flush;
474 int coarsen_factor;
475 cin >> coarsen_factor;
476 if (coarsen_factor <= 1 || coarsen_factor > 32) { break; }
477
478 char input_tol = 'n';
479 cout << "enter NURBS tolerance? [y/n] ---> " << flush;
480 cin >> input_tol;
481
482 real_t tol = 1.0e-12; // Default value
483 if (input_tol == 'y')
484 {
485 cout << "enter NURBS tolerance ---> " << flush;
486 cin >> tol;
487 }
488
489 mesh->NURBSCoarsening(coarsen_factor, tol);
490 break;
491 }
492 case 'l':
493 {
494 Vector pt;
495 Array<int> marked_elements;
496 for (int i = 0; i < mesh->GetNE(); i++)
497 {
498 // check all nodes of the element
500 mesh->GetElementTransformation(i, &T);
501 for (int j = 0; j < T.GetPointMat().Width(); j++)
502 {
504 if (region(pt) <= region_eps)
505 {
506 marked_elements.Append(i);
507 break;
508 }
509 }
510 }
511 mesh->GeneralRefinement(marked_elements);
512 break;
513 }
514 case 'r':
515 {
516 bool nc_simplices = true;
517 mesh->EnsureNCMesh(nc_simplices);
518 cout << "enter probability --> " << flush;
519 real_t probability;
520 cin >> probability;
521 if (probability < 0.0 || probability > 1.0) { break; }
522 mesh->RandomRefinement(probability);
523 break;
524 }
525 }
526 print_char = 1;
527 }
528
529 if (mk == 'c')
530 {
531 int p;
532 cout << "enter new order for mesh curvature --> " << flush;
533 cin >> p;
534 mesh->SetCurvature(p > 0 ? p : -p, p <= 0);
535 print_char = 1;
536 }
537
538 if (mk == 's')
539 {
540 real_t factor;
541 cout << "scaling factor ---> " << flush;
542 cin >> factor;
543
544 GridFunction *nodes = mesh->GetNodes();
545 if (nodes == NULL)
546 {
547 for (int i = 0; i < mesh->GetNV(); i++)
548 {
549 real_t *v = mesh->GetVertex(i);
550 v[0] *= factor;
551 v[1] *= factor;
552 if (dim == 3)
553 {
554 v[2] *= factor;
555 }
556 }
557 }
558 else
559 {
560 *nodes *= factor;
561 }
562
563 print_char = 1;
564 }
565
566 if (mk == 't')
567 {
568 char type;
569 cout << "Choose a transformation:\n"
570 "u) User-defined transform through mesh-explorer::transformation()\n"
571 "k) Kershaw transform\n"<< "---> " << flush;
572 cin >> type;
573 if (type == 'u')
574 {
576 }
577 else if (type == 'k')
578 {
579 cout << "Note: For Kershaw transformation, the input must be "
580 "Cartesian aligned with nx multiple of 6 and "
581 "both ny and nz multiples of 2."
582 "Kershaw transform works for 2D meshes also.\n" << flush;
583
584 real_t epsy, epsz = 0.0;
585 cout << "Kershaw transform factor, epsy in (0, 1]) ---> " << flush;
586 cin >> epsy;
587 if (mesh->Dimension() == 3)
588 {
589 cout << "Kershaw transform factor, epsz in (0, 1]) ---> " << flush;
590 cin >> epsz;
591 }
592 common::KershawTransformation kershawT(mesh->Dimension(), epsy, epsz);
593 mesh->Transform(kershawT);
594 }
595 else
596 {
597 MFEM_ABORT("Transformation type not supported.");
598 }
599 print_char = 1;
600 }
601
602 if (mk == 'j')
603 {
604 real_t jitter;
605 cout << "jitter factor ---> " << flush;
606 cin >> jitter;
607
608 GridFunction *nodes = mesh->GetNodes();
609
610 if (nodes == NULL)
611 {
612 cerr << "The mesh should have nodes, introduce curvature first!\n";
613 }
614 else
615 {
616 FiniteElementSpace *fespace = nodes->FESpace();
617
618 GridFunction rdm(fespace);
619 rdm.Randomize();
620 rdm -= 0.5; // shift to random values in [-0.5,0.5]
621 rdm *= jitter;
622
623 // compute minimal local mesh size
624 Vector h0(fespace->GetNDofs());
625 h0 = infinity();
626 {
627 Array<int> dofs;
628 for (int i = 0; i < fespace->GetNE(); i++)
629 {
630 fespace->GetElementDofs(i, dofs);
631 for (int j = 0; j < dofs.Size(); j++)
632 {
633 h0(dofs[j]) = std::min(h0(dofs[j]), mesh->GetElementSize(i));
634 }
635 }
636 }
637
638 // scale the random values to be of order of the local mesh size
639 for (int i = 0; i < fespace->GetNDofs(); i++)
640 {
641 for (int d = 0; d < dim; d++)
642 {
643 rdm(fespace->DofToVDof(i,d)) *= h0(i);
644 }
645 }
646
647 char move_bdr = 'n';
648 cout << "move boundary nodes? [y/n] ---> " << flush;
649 cin >> move_bdr;
650
651 // don't perturb the boundary
652 if (move_bdr == 'n')
653 {
654 Array<int> vdofs;
655 for (int i = 0; i < fespace->GetNBE(); i++)
656 {
657 fespace->GetBdrElementVDofs(i, vdofs);
658 for (int j = 0; j < vdofs.Size(); j++)
659 {
660 rdm(vdofs[j]) = 0.0;
661 }
662 }
663 }
664
665 *nodes += rdm;
666 }
667
668 print_char = 1;
669 }
670
671 if (mk == 'x')
672 {
673 int sd, nz = 0;
674 DenseMatrix J(dim);
675 real_t min_det_J, max_det_J, min_det_J_z, max_det_J_z;
676 real_t min_kappa, max_kappa, max_ratio_det_J_z;
677 min_det_J = min_kappa = infinity();
678 max_det_J = max_kappa = max_ratio_det_J_z = -infinity();
679 cout << "subdivision factor ---> " << flush;
680 cin >> sd;
681 Array<int> bad_elems_by_geom(Geometry::NumGeom);
682 bad_elems_by_geom = 0;
683 // Only print so many to keep output compact
684 const int max_to_print = 10;
685 for (int i = 0; i < mesh->GetNE(); i++)
686 {
689
690 RefinedGeometry *RefG = GlobGeometryRefiner.Refine(geom, sd, 1);
691 IntegrationRule &ir = RefG->RefPts;
692
693 min_det_J_z = infinity();
694 max_det_J_z = -infinity();
695 for (int j = 0; j < ir.GetNPoints(); j++)
696 {
697 T->SetIntPoint(&ir.IntPoint(j));
698 Geometries.JacToPerfJac(geom, T->Jacobian(), J);
699
700 real_t det_J = J.Det();
701 real_t kappa =
703
704 min_det_J_z = std::min(min_det_J_z, det_J);
705 max_det_J_z = std::max(max_det_J_z, det_J);
706
707 min_kappa = std::min(min_kappa, kappa);
708 max_kappa = std::max(max_kappa, kappa);
709 }
710 max_ratio_det_J_z =
711 std::max(max_ratio_det_J_z, max_det_J_z/min_det_J_z);
712 min_det_J = std::min(min_det_J, min_det_J_z);
713 max_det_J = std::max(max_det_J, max_det_J_z);
714 if (min_det_J_z <= 0.0)
715 {
716 if (nz < max_to_print)
717 {
718 Vector center;
719 mesh->GetElementCenter(i, center);
720 cout << "det(J) < 0 = " << min_det_J_z << " in element "
721 << i << ", centered at: ";
722 center.Print();
723 }
724 nz++;
725 bad_elems_by_geom[geom]++;
726 }
727 }
728 if (nz >= max_to_print)
729 {
730 cout << "det(J) < 0 for " << nz - max_to_print << " more elements "
731 << "not printed.\n";
732 }
733 cout << "\nbad elements = " << nz;
734 if (nz)
735 {
736 cout << " -- ";
737 Mesh::PrintElementsByGeometry(dim, bad_elems_by_geom, cout);
738 }
739 cout << "\nmin det(J) = " << min_det_J
740 << "\nmax det(J) = " << max_det_J
741 << "\nglobal ratio = " << max_det_J/min_det_J
742 << "\nmax el ratio = " << max_ratio_det_J_z
743 << "\nmin kappa = " << min_kappa
744 << "\nmax kappa = " << max_kappa << endl;
745 }
746
747 if (mk == 'f')
748 {
749 DenseMatrix point_mat(sdim,1);
750 cout << "\npoint in physical space ---> " << flush;
751 for (int i = 0; i < sdim; i++)
752 {
753 cin >> point_mat(i,0);
754 }
755 Array<int> elem_ids;
757
758 // physical -> reference space
759 mesh->FindPoints(point_mat, elem_ids, ips);
760
761 cout << "point in reference space:";
762 if (elem_ids[0] == -1)
763 {
764 cout << " NOT FOUND!\n";
765 }
766 else
767 {
768 cout << " element " << elem_ids[0] << ", ip =";
769 cout << " " << ips[0].x;
770 if (sdim > 1)
771 {
772 cout << " " << ips[0].y;
773 if (sdim > 2)
774 {
775 cout << " " << ips[0].z;
776 }
777 }
778 cout << endl;
779 }
780 }
781
782 if (mk == 'o')
783 {
784 cout << "What type of reordering?\n"
785 "g) Gecko edge-product minimization\n"
786 "h) Hilbert spatial sort\n"
787 "--> " << flush;
788 char rk;
789 cin >> rk;
790
791 Array<int> ordering, tentative;
792 if (rk == 'h')
793 {
794 mesh->GetHilbertElementOrdering(ordering);
795 mesh->ReorderElements(ordering);
796 }
797 else if (rk == 'g')
798 {
799 int outer, inner, window, period;
800 cout << "Enter number of outer iterations (default 5): " << flush;
801 cin >> outer;
802 cout << "Enter number of inner iterations (default 4): " << flush;
803 cin >> inner;
804 cout << "Enter window size (default 4, beware of exponential cost): "
805 << flush;
806 cin >> window;
807 cout << "Enter period for window size increment (default 2): "
808 << flush;
809 cin >> period;
810
811 real_t best_cost = infinity();
812 for (int i = 0; i < outer; i++)
813 {
814 int seed = i+1;
815 real_t cost = mesh->GetGeckoElementOrdering(
816 tentative, inner, window, period, seed, true);
817
818 if (cost < best_cost)
819 {
820 ordering = tentative;
821 best_cost = cost;
822 }
823 }
824 cout << "Final cost: " << best_cost << endl;
825
826 mesh->ReorderElements(ordering);
827 }
828 }
829
830 // These are most of the cases that open a new GLVis window
831 if (mk == 'm' || mk == 'b' || mk == 'e' || mk == 'v' || mk == 'h' ||
832 mk == 'k' || mk == 'J' || mk == 'p' || mk == 'B' || mk == 'P')
833 {
834 FiniteElementSpace *bdr_attr_fespace = NULL;
835 FiniteElementSpace *attr_fespace =
836 new FiniteElementSpace(mesh, attr_fec);
837 GridFunction bdr_attr;
838 GridFunction attr(attr_fespace);
839
840 if (mk == 'm')
841 {
842 for (int i = 0; i < mesh->GetNE(); i++)
843 {
844 attr(i) = mesh->GetAttribute(i);
845 }
846 }
847
848 if (mk == 'P')
849 {
850 for (int i = 0; i < mesh->GetNE(); i++)
851 {
852 attr(i) = partitioning[i] + 1;
853 }
854 }
855
856 if (mk == 'b' || mk == 'B')
857 {
858 if (dim == 3)
859 {
860 delete bdr_mesh;
861 bdr_mesh = skin_mesh(mesh);
862 bdr_attr_fespace =
863 new FiniteElementSpace(bdr_mesh, bdr_attr_fec);
864 bdr_attr.SetSpace(bdr_attr_fespace);
865 if (mk == 'b')
866 {
867 for (int i = 0; i < bdr_mesh->GetNE(); i++)
868 {
869 bdr_attr(i) = bdr_mesh->GetAttribute(i);
870 }
871 }
872 else if (mk == 'B')
873 {
874 for (int i = 0; i < bdr_mesh->GetNE(); i++)
875 {
876 bdr_attr(i) = bdr_partitioning[i] + 1;
877 }
878 }
879 else
880 {
881 MFEM_WARNING("Unimplemented case.");
882 }
883 }
884 else
885 {
886 MFEM_WARNING("Unsupported mesh dimension.");
887 attr = 1.0;
888 }
889 }
890
891 if (mk == 'v')
892 {
893 attr = 1.0;
894 }
895
896 if (mk == 'e')
897 {
898 Array<int> coloring;
899 srand(time(0));
900 real_t a = rand_real();
901 int el0 = (int)floor(a * mesh->GetNE());
902 cout << "Generating coloring starting with element " << el0+1
903 << " / " << mesh->GetNE() << endl;
904 mesh->GetElementColoring(coloring, el0);
905 for (int i = 0; i < coloring.Size(); i++)
906 {
907 attr(i) = coloring[i];
908 }
909 cout << "Number of colors: " << attr.Max() + 1 << endl;
910 for (int i = 0; i < mesh->GetNE(); i++)
911 {
912 attr(i) = i; // coloring by element number
913 }
914 }
915
916 if (mk == 'h')
917 {
918 DenseMatrix J(dim);
919 real_t h_min, h_max;
920 h_min = infinity();
921 h_max = -h_min;
922 for (int i = 0; i < mesh->GetNE(); i++)
923 {
927 Geometries.JacToPerfJac(geom, T->Jacobian(), J);
928
929 attr(i) = J.Det();
930 if (attr(i) < 0.0)
931 {
932 attr(i) = -pow(-attr(i), 1.0/real_t(dim));
933 }
934 else
935 {
936 attr(i) = pow(attr(i), 1.0/real_t(dim));
937 }
938 h_min = min(h_min, attr(i));
939 h_max = max(h_max, attr(i));
940 }
941 cout << "h_min = " << h_min << ", h_max = " << h_max << endl;
942 }
943
944 if (mk == 'k')
945 {
946 DenseMatrix J(dim);
947 for (int i = 0; i < mesh->GetNE(); i++)
948 {
952 Geometries.JacToPerfJac(geom, T->Jacobian(), J);
953 attr(i) = J.CalcSingularvalue(0) / J.CalcSingularvalue(dim-1);
954 }
955 }
956
957 if (mk == 'J')
958 {
959 // The "scaled Jacobian" is the determinant of the Jacobian scaled
960 // by the l2 norms of its columns. It can be used to identify badly
961 // skewed elements, since it takes values between 0 and 1, with 0
962 // corresponding to a flat element, and 1 to orthogonal columns.
963 DenseMatrix J(dim);
964 int sd;
965 cout << "subdivision factor ---> " << flush;
966 cin >> sd;
967 for (int i = 0; i < mesh->GetNE(); i++)
968 {
971
972 RefinedGeometry *RefG = GlobGeometryRefiner.Refine(geom, sd, 1);
973 IntegrationRule &ir = RefG->RefPts;
974
975 // For each element, find the minimal scaled Jacobian in a
976 // lattice of points with the given subdivision factor.
977 attr(i) = infinity();
978 for (int j = 0; j < ir.GetNPoints(); j++)
979 {
980 T->SetIntPoint(&ir.IntPoint(j));
981 Geometries.JacToPerfJac(geom, T->Jacobian(), J);
982
983 // Jacobian determinant
984 real_t sJ = J.Det();
985
986 for (int k = 0; k < J.Width(); k++)
987 {
988 Vector col;
989 J.GetColumnReference(k,col);
990 // Scale by column norms
991 sJ /= col.Norml2();
992 }
993
994 attr(i) = std::min(sJ, attr(i));
995 }
996 }
997 }
998
999 if (mk == 'p')
1000 {
1001 cout << "What type of partitioning?\n"
1002 "c) Cartesian\n"
1003 "s) Simple 1D split of the element sequence\n"
1004 "0) METIS_PartGraphRecursive (sorted neighbor lists)\n"
1005 "1) METIS_PartGraphKway (sorted neighbor lists)"
1006 " (default)\n"
1007 "2) METIS_PartGraphVKway (sorted neighbor lists)\n"
1008 "3) METIS_PartGraphRecursive\n"
1009 "4) METIS_PartGraphKway\n"
1010 "5) METIS_PartGraphVKway\n"
1011 "--> " << flush;
1012 char pk;
1013 cin >> pk;
1014 if (pk == 'c')
1015 {
1016 int nxyz[3];
1017 cout << "Enter nx: " << flush;
1018 cin >> nxyz[0]; np = nxyz[0];
1019 if (mesh->Dimension() > 1)
1020 {
1021 cout << "Enter ny: " << flush;
1022 cin >> nxyz[1]; np *= nxyz[1];
1023 if (mesh->Dimension() > 2)
1024 {
1025 cout << "Enter nz: " << flush;
1026 cin >> nxyz[2]; np *= nxyz[2];
1027 }
1028 }
1029 int *part = mesh->CartesianPartitioning(nxyz);
1030 partitioning = Array<int>(part, mesh->GetNE());
1031 delete [] part;
1032 recover_bdr_partitioning(mesh, partitioning, bdr_partitioning);
1033 }
1034 else if (pk == 's')
1035 {
1036 cout << "Enter number of processors: " << flush;
1037 cin >> np;
1038
1039 partitioning.SetSize(mesh->GetNE());
1040 for (int i = 0; i < mesh->GetNE(); i++)
1041 {
1042 partitioning[i] = (long long)i * np / mesh->GetNE();
1043 }
1044 recover_bdr_partitioning(mesh, partitioning, bdr_partitioning);
1045 }
1046 else
1047 {
1048 int part_method = pk - '0';
1049 if (part_method < 0 || part_method > 5)
1050 {
1051 continue;
1052 }
1053 cout << "Enter number of processors: " << flush;
1054 cin >> np;
1055 int *part = mesh->GeneratePartitioning(np, part_method);
1056 partitioning = Array<int>(part, mesh->GetNE());
1057 delete [] part;
1058 recover_bdr_partitioning(mesh, partitioning, bdr_partitioning);
1059 }
1060 if (partitioning)
1061 {
1062 const char part_file[] = "partitioning.txt";
1063 ofstream opart(part_file);
1064 opart << "number_of_elements " << mesh->GetNE() << '\n'
1065 << "number_of_processors " << np << '\n';
1066 for (int i = 0; i < mesh->GetNE(); i++)
1067 {
1068 opart << partitioning[i] << '\n';
1069 }
1070 cout << "Partitioning file: " << part_file << endl;
1071
1072 Array<int> proc_el(np);
1073 proc_el = 0;
1074 for (int i = 0; i < mesh->GetNE(); i++)
1075 {
1076 proc_el[partitioning[i]]++;
1077 }
1078 int min_el = proc_el[0], max_el = proc_el[0];
1079 for (int i = 1; i < np; i++)
1080 {
1081 if (min_el > proc_el[i])
1082 {
1083 min_el = proc_el[i];
1084 }
1085 if (max_el < proc_el[i])
1086 {
1087 max_el = proc_el[i];
1088 }
1089 }
1090 cout << "Partitioning stats:\n"
1091 << " "
1092 << setw(12) << "minimum"
1093 << setw(12) << "average"
1094 << setw(12) << "maximum"
1095 << setw(12) << "total" << '\n';
1096 cout << " elements "
1097 << setw(12) << min_el
1098 << setw(12) << real_t(mesh->GetNE())/np
1099 << setw(12) << max_el
1100 << setw(12) << mesh->GetNE() << endl;
1101 }
1102 else
1103 {
1104 continue;
1105 }
1106
1107 for (int i = 0; i < mesh->GetNE(); i++)
1108 {
1109 attr(i) = partitioning[i] + 1;
1110 }
1111 }
1112
1113 char vishost[] = "localhost";
1114 int visport = 19916;
1115 socketstream sol_sock(vishost, visport);
1116 if (sol_sock.is_open())
1117 {
1118 sol_sock.precision(14);
1119 if (sdim == 2)
1120 {
1121 sol_sock << "fem2d_gf_data_keys\n";
1122 if (mk != 'p')
1123 {
1124 mesh->Print(sol_sock);
1125 }
1126 else
1127 {
1128 // NURBS meshes do not support PrintWithPartitioning
1129 if (mesh->NURBSext)
1130 {
1131 mesh->Print(sol_sock);
1132 for (int i = 0; i < mesh->GetNE(); i++)
1133 {
1134 attr(i) = partitioning[i];
1135 }
1136 }
1137 else
1138 {
1139 mesh->PrintWithPartitioning(partitioning, sol_sock, 1);
1140 }
1141 }
1142 attr.Save(sol_sock);
1143 sol_sock << "RjlmAb***********";
1144 if (mk == 'v')
1145 {
1146 sol_sock << "e";
1147 }
1148 else
1149 {
1150 sol_sock << "\n";
1151 }
1152 }
1153 else
1154 {
1155 sol_sock << "fem3d_gf_data_keys\n";
1156 if (mk == 'v' || mk == 'h' || mk == 'k' || mk == 'J')
1157 {
1158 mesh->Print(sol_sock);
1159 }
1160 else if (mk == 'b' || mk == 'B')
1161 {
1162 bdr_mesh->Print(sol_sock);
1163 bdr_attr.Save(sol_sock);
1164 sol_sock << "mcaaA";
1165 // Switch to a discrete color scale
1166 sol_sock << "pppppp" << "pppppp" << "pppppp";
1167 }
1168 else
1169 {
1170 // NURBS meshes do not support PrintWithPartitioning
1171 if (mesh->NURBSext)
1172 {
1173 mesh->Print(sol_sock);
1174 for (int i = 0; i < mesh->GetNE(); i++)
1175 {
1176 attr(i) = partitioning[i];
1177 }
1178 }
1179 else
1180 {
1181 mesh->PrintWithPartitioning(partitioning, sol_sock);
1182 }
1183 }
1184 if (mk != 'b' && mk != 'B')
1185 {
1186 attr.Save(sol_sock);
1187 sol_sock << "maaA";
1188 if (mk == 'v')
1189 {
1190 sol_sock << "aa";
1191 }
1192 else
1193 {
1194 sol_sock << "\n";
1195 }
1196 }
1197 }
1198 sol_sock << flush;
1199 }
1200 else
1201 {
1202 cout << "Unable to connect to "
1203 << vishost << ':' << visport << endl;
1204 }
1205 delete attr_fespace;
1206 delete bdr_attr_fespace;
1207 }
1208
1209 if (mk == 'l')
1210 {
1211 // Project and plot the function 'f'
1212 int p;
1213 FiniteElementCollection *fec = NULL;
1214 cout << "Enter projection space order: " << flush;
1215 cin >> p;
1216 if (p >= 1)
1217 {
1218 fec = new H1_FECollection(p, mesh->Dimension(),
1220 }
1221 else
1222 {
1223 fec = new DG_FECollection(-p, mesh->Dimension(),
1225 }
1226 FiniteElementSpace fes(mesh, fec);
1227 GridFunction level(&fes);
1228 FunctionCoefficient coeff(f);
1229 level.ProjectCoefficient(coeff);
1230 char vishost[] = "localhost";
1231 int visport = 19916;
1232 socketstream sol_sock(vishost, visport);
1233 if (sol_sock.is_open())
1234 {
1235 sol_sock.precision(14);
1236 sol_sock << "solution\n" << *mesh << level << flush;
1237 }
1238 else
1239 {
1240 cout << "Unable to connect to "
1241 << vishost << ':' << visport << endl;
1242 }
1243 delete fec;
1244 }
1245
1246 if (mk == 'S')
1247 {
1248 const char omesh_file[] = "mesh-explorer.mesh";
1249 ofstream omesh(omesh_file);
1250 omesh.precision(14);
1251 mesh->Print(omesh);
1252 cout << "New mesh file: " << omesh_file << endl;
1253 }
1254
1255 if (mk == 'T')
1256 {
1257 string mesh_prefix("mesh-explorer.mesh."), line;
1258 MeshPartitioner partitioner(*mesh, np, partitioning);
1259 MeshPart mesh_part;
1260 cout << "Enter mesh file prefix or press <enter> to use \""
1261 << mesh_prefix << "\": " << flush;
1262 // extract and ignore all characters after 'T' up to and including the
1263 // new line:
1264 cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
1265 getline(cin, line);
1266 if (!line.empty()) { mesh_prefix = line; }
1267 int precision;
1268 cout << "Enter floating point output precision (num. digits): "
1269 << flush;
1270 cin >> precision;
1271 for (int i = 0; i < np; i++)
1272 {
1273 partitioner.ExtractPart(i, mesh_part);
1274
1275 ofstream omesh(MakeParFilename(mesh_prefix, i));
1276 omesh.precision(precision);
1277 mesh_part.Print(omesh);
1278 }
1279 cout << "New parallel mesh files: " << mesh_prefix << "<rank>" << endl;
1280 }
1281
1282 if (mk == 'V')
1283 {
1284 const char omesh_file[] = "mesh-explorer.vtk";
1285 ofstream omesh(omesh_file);
1286 omesh.precision(14);
1287 mesh->PrintVTK(omesh);
1288 cout << "New VTK mesh file: " << omesh_file << endl;
1289 }
1290
1291 if (mk == 'D')
1292 {
1293 cout << "What type of DataCollection?\n"
1294 "p) ParaView Data Collection\n"
1295 "v) VisIt Data Collection\n"
1296 "--> " << flush;
1297 char dk;
1298 cin >> dk;
1299 if (dk == 'p' || dk == 'P')
1300 {
1301 const char omesh_file[] = "mesh-explorer-paraview";
1302 ParaViewDataCollection dc(omesh_file, mesh);
1303 if (mesh->GetNodes())
1304 {
1305 int order = mesh->GetNodes()->FESpace()->GetMaxElementOrder();
1306 if (order > 1)
1307 {
1308 dc.SetHighOrderOutput(true);
1309 dc.SetLevelsOfDetail(order);
1310 }
1311 }
1312 dc.Save();
1313 cout << "New ParaView mesh file: " << omesh_file << endl;
1314 }
1315 else if (dk == 'v' || dk == 'V')
1316 {
1317 const char omesh_file[] = "mesh-explorer-visit";
1318 VisItDataCollection dc(omesh_file, mesh);
1319 dc.SetPrecision(14);
1320 dc.Save();
1321 cout << "New VisIt mesh file: " << omesh_file << "_000000.mfem_root"
1322 << endl;
1323 }
1324 else
1325 {
1326 cout << "Unrecognized DataCollection type: \"" << dk << "\""
1327 << endl;
1328 }
1329 }
1330
1331#ifdef MFEM_USE_ZLIB
1332 if (mk == 'Z')
1333 {
1334 const char omesh_file[] = "mesh-explorer.mesh.gz";
1335 ofgzstream omesh(omesh_file, "zwb9");
1336 omesh.precision(14);
1337 mesh->Print(omesh);
1338 cout << "New mesh file: " << omesh_file << endl;
1339 }
1340#endif
1341
1342 }
1343
1344 delete bdr_attr_fec;
1345 delete attr_fec;
1346 delete bdr_mesh;
1347 delete mesh;
1348 return 0;
1349}
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:697
int Size() const
Return the logical size of the array.
Definition array.hpp:144
void DeleteAll()
Delete the whole array.
Definition array.hpp:864
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Definition array.hpp:769
@ GaussLobatto
Closed type.
Definition fe_base.hpp:32
@ GaussLegendre
Open type.
Definition fe_base.hpp:31
@ ClosedUniform
Nodes: x_i = i/(n-1), i=0,...,n-1.
Definition fe_base.hpp:35
Piecewise-constant discontinuous finite elements in 2D. This class is kept only for backward compatib...
Definition fe_coll.hpp:972
Piecewise-constant discontinuous finite elements in 3D. This class is kept only for backward compatib...
Definition fe_coll.hpp:1163
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:312
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:535
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint,...
Definition eltrans.hpp:119
void SetIntPoint(const IntegrationPoint *ip)
Set the integration point ip that weights and Jacobians will be evaluated at.
Definition eltrans.hpp:93
Abstract data type element.
Definition element.hpp:29
Geometry::Type GetGeometryType() const
Definition element.hpp:52
virtual void GetVertices(Array< int > &v) const =0
Get the indices defining the vertices.
int GetAttribute() const
Return element's attribute.
Definition element.hpp:55
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:126
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:220
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:2846
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
Definition fespace.hpp:710
int GetNBE() const
Returns number of boundary elements in the mesh.
Definition fespace.hpp:749
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:287
int GetNE() const
Returns number of elements in the mesh.
Definition fespace.hpp:740
const FiniteElementCollection * FEColl() const
Definition fespace.hpp:727
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:303
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:249
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:42
const IntegrationPoint & GetCenter(int GeomType) const
Return the center of the given Geometry::Type, GeomType.
Definition geom.hpp:71
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 and fes.
Definition gridfunc.hpp:122
FiniteElementSpace * FESpace()
Definition gridfunc.hpp:696
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:195
Arbitrary order H1-conforming (continuous) finite elements.
Definition fe_coll.hpp:260
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:363
const DenseMatrix & GetPointMat() const
Return the stored point matrix.
Definition eltrans.hpp:405
Class containing a minimal description of a part (a subset of the elements) of a Mesh and its connect...
Definition mesh.hpp:2479
void Print(std::ostream &os) const
Write the MeshPart to a stream using the parallel format "MFEM mesh v1.2".
Definition mesh.cpp:13338
Class that allows serial meshes to be partitioned into MeshPart objects, typically one MeshPart at a ...
Definition mesh.hpp:2707
void ExtractPart(int part_id, MeshPart &mesh_part) const
Construct a MeshPart corresponding to the given part_id.
Definition mesh.cpp:13672
Mesh data type.
Definition mesh.hpp:56
void NURBSCoarsening(int cf=2, real_t tol=1.0e-12)
Definition mesh.cpp:10502
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:1715
void GetElementColoring(Array< int > &colors, int el0=0)
Definition mesh.cpp:12047
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition mesh.hpp:282
NURBSExtension * NURBSext
Optional NURBS mesh extension.
Definition mesh.hpp:290
int * CartesianPartitioning(int nxyz[])
Definition mesh.cpp:8054
void GeneralRefinement(const Array< Refinement > &refinements, int nonconforming=-1, int nc_limit=0)
Definition mesh.cpp:10558
int GetAttribute(int i) const
Return the attribute of element i.
Definition mesh.hpp:1333
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:1743
const FiniteElementSpace * GetNodalFESpace() const
Definition mesh.cpp:6206
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:1729
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:2239
void FinalizeTopology(bool generate_bdr=true)
Finalize the construction of the secondary topology (connectivity) data of a Mesh.
Definition mesh.cpp:3135
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
Definition mesh.hpp:2288
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:12122
int AddVertex(real_t x, real_t y=0.0, real_t z=0.0)
Definition mesh.cpp:1658
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1226
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1160
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:10650
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
Definition mesh.hpp:1298
void ReorderElements(const Array< int > &ordering, bool reorder_vertices=true)
Definition mesh.cpp:2458
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:4290
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:1163
void GetNodes(Vector &node_coord) const
Definition mesh.cpp:8973
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
Definition mesh.hpp:1223
void GetHilbertElementOrdering(Array< int > &ordering)
Definition mesh.cpp:2406
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:7271
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:1229
virtual void Finalize(bool refine=false, bool fix_orientation=false)
Finalize the construction of a general Mesh.
Definition mesh.cpp:3241
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:13081
void NewNodes(GridFunction &nodes, bool make_owner=false)
Replace the internal node GridFunction with the given GridFunction.
Definition mesh.cpp:9000
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:5730
void EnsureNCMesh(bool simplices_nonconforming=false)
Definition mesh.cpp:10626
void PrintVTK(std::ostream &os)
Definition mesh.cpp:11495
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:6211
void Transform(void(*f)(const Vector &, Vector &))
Definition mesh.cpp:12821
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Definition mesh.cpp:10970
Geometry::Type GetElementBaseGeometry(int i) const
Definition mesh.hpp:1385
int * GeneratePartitioning(int nparts, int part_method=1)
Definition mesh.cpp:8098
Array< int > attributes
A list of all unique element attributes used by the Mesh.
Definition mesh.hpp:280
const real_t * GetVertex(int i) const
Return pointer to vertex i's coordinates.
Definition mesh.hpp:1265
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_)
virtual void Save() override
IntegrationRule RefPts
Definition geom.hpp:317
Vector data type.
Definition vector.hpp:80
void Randomize(int seed=0)
Set random values in the vector.
Definition vector.cpp:816
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
Definition vector.cpp:755
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
Definition vector.cpp:604
real_t Norml2() const
Returns the l2 norm of the vector.
Definition vector.cpp:832
real_t Max() const
Returns the maximal element of the vector.
Definition vector.cpp:922
Data collection with VisIt I/O routines.
virtual 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)
const int visport
real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
Definition vector.hpp:45
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:43
GeometryRefiner GlobGeometryRefiner
Definition geom.cpp:1891
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:59
L2_FECollection DG_FECollection
Declare an alternative name for L2_FECollection = DG_FECollection.
Definition fe_coll.hpp:382
float real_t
Definition config.hpp:43
const char vishost[]
real_t p(const Vector &x, real_t t)
RefCoord s[3]