MFEM  v4.3.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
extruder.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2021, 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 // Extruder Miniapp: Extrude a low-dimensional mesh into a higher dimension
14 // ------------------------------------------------------------------------
15 //
16 // This miniapp creates higher-dimensional meshes from lower-dimensional meshes
17 // by extrusion. Simple coordinate transformations can also be applied if
18 // desired. The initial mesh can be 1D or 2D. 1D meshes can be extruded in the
19 // y-direction first and then in the z-direction. 2D meshes can be triangular,
20 // quadrilateral, or contain both element types. The initial mesh can also be
21 // curved although NURBS meshes are not supported.
22 //
23 // The resulting mesh is displayed with GLVis (unless explicitly disabled) and
24 // is also written to the file "extruder.mesh".
25 //
26 // Compile with: make extruder
27 //
28 // Sample runs:
29 // extruder
30 // extruder -m ../../data/inline-segment.mesh -ny 8 -wy 2
31 // extruder -m ../../data/inline-segment.mesh -ny 8 -wy 2 -nz 12 -hz 3
32 // extruder -m ../../data/star.mesh -nz 3
33 // extruder -m ../../data/star-mixed.mesh -nz 3
34 // extruder -m ../../data/square-disc.mesh -nz 3
35 // extruder -m ../../data/inline-segment.mesh -ny 8 -wy 2 -trans
36 // extruder -m ../../data/inline-segment.mesh -ny 8 -wy 2 -nz 12 -hz 3 -trans
37 // extruder -m ../../data/square-disc-p2.mesh -nz 16 -hz 2 -trans
38 
39 #include "mfem.hpp"
40 #include <fstream>
41 #include <iostream>
42 
43 using namespace mfem;
44 using namespace std;
45 
46 void trans2D(const Vector&, Vector&);
47 void trans3D(const Vector&, Vector&);
48 
49 int main(int argc, char *argv[])
50 {
51  const char *mesh_file = "../../data/inline-quad.mesh";
52  int order = -1;
53  int ny = -1, nz = -1; // < 0: autoselect based on the initial mesh dimension
54  double wy = 1.0, hz = 1.0;
55  bool trans = false;
56  bool visualization = 1;
57 
58  // Parse command line
59  OptionsParser args(argc, argv);
60  args.AddOption(&mesh_file, "-m", "--mesh",
61  "Input mesh to extrude.");
62  args.AddOption(&order, "-o", "--mesh-order",
63  "Order (polynomial degree) of the mesh elements.");
64  args.AddOption(&ny, "-ny", "--num-elem-in-y",
65  "Extrude a 1D mesh into ny elements in the y-direction.");
66  args.AddOption(&wy, "-wy", "--width-in-y",
67  "Extrude a 1D mesh to a width wy in the y-direction.");
68  args.AddOption(&nz, "-nz", "--num-elem-in-z",
69  "Extrude a 2D mesh into nz elements in the z-direction.");
70  args.AddOption(&hz, "-hz", "--height-in-z",
71  "Extrude a 2D mesh to a height hz in the z-direction.");
72  args.AddOption(&trans, "-trans", "--transform", "-no-trans",
73  "--no-transform",
74  "Enable or disable mesh transformation after extrusion.");
75  args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
76  "--no-visualization",
77  "Enable or disable GLVis visualization.");
78  args.Parse();
79  if (!args.Good()) { args.PrintUsage(cout); return 1; }
80  args.PrintOptions(cout);
81 
82  // Read the initial mesh
83  Mesh *mesh = new Mesh(mesh_file, 1, 1);
84  int dim = mesh->Dimension();
85 
86  // Autoselect ny and nz if not set on the command line or set to < 0 values
87  switch (dim)
88  {
89  case 1:
90  ny = (ny < 0) ? 1 : ny;
91  nz = (nz < 0) ? 0 : nz;
92  break;
93  case 2:
94  // ny is not used
95  nz = (nz < 0) ? 1 : nz;
96  break;
97  default:
98  cout << "Extruding " << dim << "D meshes is not (yet) supported."
99  << endl;
100  delete mesh;
101  return 1;
102  }
103 
104  // Determine the order to use for a transformed mesh
105  int meshOrder = 1;
106  if (mesh->GetNodalFESpace() != NULL)
107  {
108  meshOrder = mesh->GetNodalFESpace()->GetElementOrder(0);
109  }
110  if (order < 0 && trans)
111  {
112  order = meshOrder;
113  }
114 
115  bool newMesh = false;
116 
117  if (dim == 1 && ny > 0)
118  {
119  cout << "Extruding 1D mesh to a width of " << wy
120  << " using " << ny << " elements." << endl;
121 
122  Mesh *mesh2d = Extrude1D(mesh, ny, wy);
123  delete mesh;
124  mesh = mesh2d;
125  dim = 2;
126  if (trans)
127  {
128  if (order != meshOrder)
129  {
130  mesh->SetCurvature(order, false, 2, Ordering::byVDIM);
131  }
132  mesh->Transform(trans2D);
133  }
134  newMesh = true;
135  }
136  if (dim == 2 && nz > 0)
137  {
138  cout << "Extruding 2D mesh to a height of " << hz
139  << " using " << nz << " elements." << endl;
140 
141  Mesh *mesh3d = Extrude2D(mesh, nz, hz);
142  delete mesh;
143  mesh = mesh3d;
144  dim = 3;
145  if (trans)
146  {
147  if (order != meshOrder)
148  {
149  mesh->SetCurvature(order, false, 3, Ordering::byVDIM);
150  }
151  mesh->Transform(trans3D);
152  }
153  newMesh = true;
154  }
155 
156  if (newMesh)
157  {
158  if (visualization)
159  {
160  // GLVis server to visualize to
161  char vishost[] = "localhost";
162  int visport = 19916;
163  socketstream sol_sock(vishost, visport);
164  sol_sock.precision(8);
165  sol_sock << "mesh\n" << *mesh << flush;
166  }
167 
168  // Save the final mesh
169  ofstream mesh_ofs("extruder.mesh");
170  mesh_ofs.precision(8);
171  mesh->Print(mesh_ofs);
172  }
173  else
174  {
175  cout << "No mesh extrusion performed." << endl;
176  }
177 
178  delete mesh;
179 }
180 
181 void trans2D(const Vector&x, Vector&p)
182 {
183  p[0] = x[0] + 0.25 * sin(M_PI * x[1]);
184  p[1] = x[1];
185 }
186 
187 void trans3D(const Vector&x, Vector&p)
188 {
189  double r = sqrt(x[0] * x[0] + x[1] * x[1]);
190  double theta = atan2(x[1], x[0]);
191  p[0] = r * cos(theta + 0.25 * M_PI * x[2]);
192  p[1] = r * sin(theta + 0.25 * M_PI * x[2]);
193  p[2] = x[2];
194 }
195 
virtual void Print(std::ostream &out=mfem::out) const
Definition: mesh.hpp:1387
void trans(const Vector &u, Vector &x)
Definition: ex27.cpp:421
void trans2D(const Vector &, Vector &)
Definition: extruder.cpp:181
Mesh * Extrude1D(Mesh *mesh, const int ny, const double sy, const bool closed)
Extrude a 1D mesh.
Definition: mesh.cpp:11545
int GetElementOrder(int i) const
Returns the order of the i&#39;th finite element.
Definition: fespace.cpp:160
void Transform(void(*f)(const Vector &, Vector &))
Definition: mesh.cpp:11008
Mesh * Extrude2D(Mesh *mesh, const int nz, const double sz)
Extrude a 2D mesh.
Definition: mesh.cpp:11705
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
Definition: optparser.cpp:150
constexpr char vishost[]
constexpr int visport
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
Definition: mesh.cpp:4882
int Dimension() const
Definition: mesh.hpp:911
void PrintUsage(std::ostream &out) const
Print the usage message.
Definition: optparser.cpp:457
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set &#39;var&#39; to receive the value. Enable/disable tags are used to set the bool...
Definition: optparser.hpp:82
void trans3D(const Vector &, Vector &)
Definition: extruder.cpp:187
const FiniteElementSpace * GetNodalFESpace() const
Definition: mesh.cpp:4877
int dim
Definition: ex24.cpp:53
void PrintOptions(std::ostream &out) const
Print the options.
Definition: optparser.cpp:327
Vector data type.
Definition: vector.hpp:60
int main()
bool Good() const
Return true if the command line options were parsed successfully.
Definition: optparser.hpp:150