MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
extruder.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// 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
43using namespace mfem;
44using namespace std;
45
46void trans2D(const Vector&, Vector&);
47void trans3D(const Vector&, Vector&);
48
49int 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 real_t wy = 1.0, hz = 1.0;
55 bool trans = false;
56 bool visualization = 1;
57 int visport = 19916;
58
59 // Parse command line
60 OptionsParser args(argc, argv);
61 args.AddOption(&mesh_file, "-m", "--mesh",
62 "Input mesh to extrude.");
63 args.AddOption(&order, "-o", "--mesh-order",
64 "Order (polynomial degree) of the mesh elements.");
65 args.AddOption(&ny, "-ny", "--num-elem-in-y",
66 "Extrude a 1D mesh into ny elements in the y-direction.");
67 args.AddOption(&wy, "-wy", "--width-in-y",
68 "Extrude a 1D mesh to a width wy in the y-direction.");
69 args.AddOption(&nz, "-nz", "--num-elem-in-z",
70 "Extrude a 2D mesh into nz elements in the z-direction.");
71 args.AddOption(&hz, "-hz", "--height-in-z",
72 "Extrude a 2D mesh to a height hz in the z-direction.");
73 args.AddOption(&trans, "-trans", "--transform", "-no-trans",
74 "--no-transform",
75 "Enable or disable mesh transformation after extrusion.");
76 args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
77 "--no-visualization",
78 "Enable or disable GLVis visualization.");
79 args.AddOption(&visport, "-p", "--send-port", "Socket for GLVis.");
80 args.Parse();
81 if (!args.Good()) { args.PrintUsage(cout); return 1; }
82 args.PrintOptions(cout);
83
84 // Read the initial mesh
85 Mesh *mesh = new Mesh(mesh_file, 1, 1);
86 int dim = mesh->Dimension();
87
88 // Autoselect ny and nz if not set on the command line or set to < 0 values
89 switch (dim)
90 {
91 case 1:
92 ny = (ny < 0) ? 1 : ny;
93 nz = (nz < 0) ? 0 : nz;
94 break;
95 case 2:
96 // ny is not used
97 nz = (nz < 0) ? 1 : nz;
98 break;
99 default:
100 cout << "Extruding " << dim << "D meshes is not (yet) supported."
101 << endl;
102 delete mesh;
103 return 1;
104 }
105
106 // Determine the order to use for a transformed mesh
107 int meshOrder = 1;
108 if (mesh->GetNodalFESpace() != NULL)
109 {
110 meshOrder = mesh->GetNodalFESpace()->GetElementOrder(0);
111 }
112 if (order < 0 && trans)
113 {
114 order = meshOrder;
115 }
116
117 bool newMesh = false;
118
119 if (dim == 1 && ny > 0)
120 {
121 cout << "Extruding 1D mesh to a width of " << wy
122 << " using " << ny << " elements." << endl;
123
124 Mesh *mesh2d = Extrude1D(mesh, ny, wy);
125 delete mesh;
126 mesh = mesh2d;
127 dim = 2;
128 if (trans)
129 {
130 if (order != meshOrder)
131 {
132 mesh->SetCurvature(order, false, 2, Ordering::byVDIM);
133 }
134 mesh->Transform(trans2D);
135 }
136 newMesh = true;
137 }
138 if (dim == 2 && nz > 0)
139 {
140 cout << "Extruding 2D mesh to a height of " << hz
141 << " using " << nz << " elements." << endl;
142
143 Mesh *mesh3d = Extrude2D(mesh, nz, hz);
144 delete mesh;
145 mesh = mesh3d;
146 dim = 3;
147 if (trans)
148 {
149 if (order != meshOrder)
150 {
151 mesh->SetCurvature(order, false, 3, Ordering::byVDIM);
152 }
153 mesh->Transform(trans3D);
154 }
155 newMesh = true;
156 }
157
158 if (newMesh)
159 {
160 if (visualization)
161 {
162 // GLVis server to visualize to
163 char vishost[] = "localhost";
164 socketstream sol_sock(vishost, visport);
165 sol_sock.precision(8);
166 sol_sock << "mesh\n" << *mesh << flush;
167 }
168
169 // Save the final mesh
170 ofstream mesh_ofs("extruder.mesh");
171 mesh_ofs.precision(8);
172 mesh->Print(mesh_ofs);
173 }
174 else
175 {
176 cout << "No mesh extrusion performed." << endl;
177 }
178
179 delete mesh;
180}
181
182void trans2D(const Vector&x, Vector&p)
183{
184 p[0] = x[0] + 0.25 * sin(M_PI * x[1]);
185 p[1] = x[1];
186}
187
188void trans3D(const Vector&x, Vector&p)
189{
190 real_t r = sqrt(x[0] * x[0] + x[1] * x[1]);
191 real_t theta = atan2(x[1], x[0]);
192 p[0] = r * cos(theta + 0.25 * M_PI * x[2]);
193 p[1] = r * sin(theta + 0.25 * M_PI * x[2]);
194 p[2] = x[2];
195}
196
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
Definition fespace.cpp:221
Mesh data type.
Definition mesh.hpp:64
const FiniteElementSpace * GetNodalFESpace() const
Definition mesh.cpp:6479
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
Definition mesh.hpp:2433
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1216
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 Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
Definition optparser.hpp:82
bool Good() const
Return true if the command line options were parsed successfully.
Vector data type.
Definition vector.hpp:82
int dim
Definition ex24.cpp:53
void trans(const Vector &u, Vector &x)
Definition ex27.cpp:412
void trans3D(const Vector &, Vector &)
Definition extruder.cpp:188
void trans2D(const Vector &, Vector &)
Definition extruder.cpp:182
int main()
Mesh * Extrude1D(Mesh *mesh, const int ny, const real_t sy, const bool closed)
Extrude a 1D mesh.
Definition mesh.cpp:14674
Mesh * Extrude2D(Mesh *mesh, const int nz, const real_t sz)
Extrude a 2D mesh.
Definition mesh.cpp:14834
float real_t
Definition config.hpp:43
const char vishost[]
real_t p(const Vector &x, real_t t)