MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
extruder.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// 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
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
181void 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
187void trans3D(const Vector&x, Vector&p)
188{
189 real_t r = sqrt(x[0] * x[0] + x[1] * x[1]);
190 real_t 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
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
Definition fespace.cpp:176
Mesh data type.
Definition mesh.hpp:56
const FiniteElementSpace * GetNodalFESpace() const
Definition mesh.cpp:6206
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
Definition mesh.hpp:2288
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1160
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 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:80
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:187
void trans2D(const Vector &, Vector &)
Definition extruder.cpp:181
int main()
const int visport
Mesh * Extrude1D(Mesh *mesh, const int ny, const real_t sy, const bool closed)
Extrude a 1D mesh.
Definition mesh.cpp:14348
Mesh * Extrude2D(Mesh *mesh, const int nz, const real_t sz)
Extrude a 2D mesh.
Definition mesh.cpp:14508
float real_t
Definition config.hpp:43
const char vishost[]
real_t p(const Vector &x, real_t t)