MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
fit-node-position.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, 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// Fitting of Selected Mesh Nodes to Specified Physical Positions
14// ------------------------------------------------------------------
15//
16// This example fits a selected set of the mesh nodes to given physical
17// positions while maintaining a valid mesh with good quality.
18//
19// Sample runs:
20// mpirun -np 4 fit-node-position
21// mpirun -np 4 fit-node-position -m square01-tri.mesh
22// mpirun -np 4 fit-node-position -m ./cube.mesh
23// mpirun -np 4 fit-node-position -m ./cube-tet.mesh -rs 0
24
25#include "mfem.hpp"
27
28using namespace mfem;
29using namespace std;
30
31char vishost[] = "localhost";
32int wsize = 350;
33
34int main (int argc, char *argv[])
35{
36 // Initialize MPI.
37 Mpi::Init();
38 int myid = Mpi::WorldRank();
40
41 const char *mesh_file = "square01.mesh";
42 int rs_levels = 2;
43 int mesh_poly_deg = 2;
44 int quad_order = 5;
45 bool glvis = true;
46 int visport = 19916;
47
48 // Parse command-line options.
49 OptionsParser args(argc, argv);
50 args.AddOption(&mesh_file, "-m", "--mesh",
51 "Mesh file to use.");
52 args.AddOption(&rs_levels, "-rs", "--refine-serial",
53 "Number of times to refine the mesh uniformly in serial.");
54 args.AddOption(&mesh_poly_deg, "-o", "--order",
55 "Polynomial degree of mesh finite element space.");
56 args.AddOption(&quad_order, "-qo", "--quad_order",
57 "Order of the quadrature rule.");
58 args.AddOption(&glvis, "-vis", "--visualization", "-no-vis",
59 "--no-visualization",
60 "Enable or disable GLVis visualization.");
61 args.AddOption(&visport, "-p", "--send-port", "Socket for GLVis.");
62 args.Parse();
63 if (!args.Good())
64 {
65 if (myid == 0) { args.PrintUsage(cout); }
66 return 1;
67 }
68 if (myid == 0) { args.PrintOptions(cout); }
69
70 // Read and refine the mesh.
71 Mesh *mesh = new Mesh(mesh_file, 1, 1, false);
72 for (int lev = 0; lev < rs_levels; lev++) { mesh->UniformRefinement(); }
73 ParMesh pmesh(MPI_COMM_WORLD, *mesh);
74 delete mesh;
75 const int dim = pmesh.Dimension();
76
77 // Setup mesh curvature and GridFunction that stores the coordinates.
79 if (mesh_poly_deg <= 0)
80 {
81 fec_mesh = new QuadraticPosFECollection;
82 mesh_poly_deg = 2;
83 }
84 else { fec_mesh = new H1_FECollection(mesh_poly_deg, dim); }
85 ParFiniteElementSpace pfes_mesh(&pmesh, fec_mesh, dim);
86 pmesh.SetNodalFESpace(&pfes_mesh);
87 ParGridFunction coord(&pfes_mesh);
88 pmesh.SetNodalGridFunction(&coord);
89 ParGridFunction x0(coord);
90
91 // Pick which nodes to fit and select the target positions.
92 // (attribute 2 would have a prescribed deformation in y-direction, same x).
93 Array<bool> fit_marker(pfes_mesh.GetNDofs());
94 ParGridFunction fit_marker_vis_gf(&pfes_mesh);
95 ParGridFunction coord_target(&pfes_mesh);
96 Array<int> vdofs;
97 fit_marker = false;
98 coord_target = coord;
99 fit_marker_vis_gf = 0.0;
100 for (int e = 0; e < pmesh.GetNBE(); e++)
101 {
102 const int nd = pfes_mesh.GetBE(e)->GetDof();
103 const int attr = pmesh.GetBdrElement(e)->GetAttribute();
104 if (attr != 2) { continue; }
105
106 pfes_mesh.GetBdrElementVDofs(e, vdofs);
107 for (int j = 0; j < nd; j++)
108 {
109 int j_x = vdofs[j], j_y = vdofs[nd+j];
110 const real_t x = coord(j_x),
111 z = (dim == 2) ? 0.0 : coord(vdofs[2*nd + j]);
112 fit_marker[pfes_mesh.VDofToDof(j_x)] = true;
113 fit_marker_vis_gf(j_x) = 1.0;
114 if (coord(j_y) < 0.5)
115 {
116 coord_target(j_y) = 0.1 * sin(4 * M_PI * x) * cos(M_PI * z);
117 }
118 else
119 {
120 if (coord(j_x) < 0.5)
121 {
122 coord_target(j_y) = 1.0 + 0.1 * sin(2 * M_PI * x);
123 }
124 else
125 {
126 coord_target(j_y) = 1.0 + 0.1 * sin(2 * M_PI * (x + 0.5));
127 }
128
129 }
130 }
131 }
132
133 // Visualize the selected nodes and their target positions.
134 if (glvis)
135 {
136 socketstream vis1;
137 coord = coord_target;
138 common::VisualizeField(vis1, "localhost", 19916, fit_marker_vis_gf,
139 "Target positions (DOFS with value 1)",
140 0, 0, 400, 400, (dim == 2) ? "Rjm" : "");
141 coord = x0;
142 }
143
144 // Allow slipping along the remaining boundaries.
145 // (attributes 1 and 3 would slip, while 4 is completely fixed).
146 int n = 0;
147 for (int i = 0; i < pmesh.GetNBE(); i++)
148 {
149 const int nd = pfes_mesh.GetBE(i)->GetDof();
150 const int attr = pmesh.GetBdrElement(i)->GetAttribute();
151 MFEM_VERIFY(!(dim == 2 && attr == 3),
152 "Boundary attribute 3 must be used only for 3D meshes. "
153 "Adjust the attributes (1/2/3/4 for fixed x/y/z/all "
154 "components, rest for free nodes), or use -fix-bnd.");
155 if (attr == 1 || attr == 3) { n += nd; }
156 if (attr == 4) { n += nd * dim; }
157 }
158 Array<int> ess_vdofs(n);
159 n = 0;
160 for (int i = 0; i < pmesh.GetNBE(); i++)
161 {
162 const int nd = pfes_mesh.GetBE(i)->GetDof();
163 const int attr = pmesh.GetBdrElement(i)->GetAttribute();
164 pfes_mesh.GetBdrElementVDofs(i, vdofs);
165 if (attr == 1) // Fix x components.
166 {
167 for (int j = 0; j < nd; j++)
168 { ess_vdofs[n++] = vdofs[j]; }
169 }
170 else if (attr == 3) // Fix z components.
171 {
172 for (int j = 0; j < nd; j++)
173 { ess_vdofs[n++] = vdofs[j+2*nd]; }
174 }
175 else if (attr == 4) // Fix all components.
176 {
177 for (int j = 0; j < vdofs.Size(); j++)
178 { ess_vdofs[n++] = vdofs[j]; }
179 }
180 }
181
182 // TMOP setup.
183 TMOP_QualityMetric *metric;
184 if (dim == 2) { metric = new TMOP_Metric_002; }
185 else { metric = new TMOP_Metric_302; }
187 pfes_mesh.GetComm());
188 ConstantCoefficient fit_weight(100.0);
189 auto integ = new TMOP_Integrator(metric, &target, nullptr);
190 integ->EnableSurfaceFitting(coord_target, fit_marker, fit_weight);
191
192 // Linear solver.
193 MINRESSolver minres(pfes_mesh.GetComm());
194 minres.SetMaxIter(100);
195 minres.SetRelTol(1e-12);
196 minres.SetAbsTol(0.0);
197
198 // Nonlinear solver.
199 ParNonlinearForm a(&pfes_mesh);
200 a.SetEssentialVDofs(ess_vdofs);
201 a.AddDomainIntegrator(integ);
202 const IntegrationRule &ir =
203 IntRules.Get(pmesh.GetTypicalElementGeometry(), quad_order);
204 TMOPNewtonSolver solver(pfes_mesh.GetComm(), ir, 0);
205 solver.SetOperator(a);
206 solver.SetPreconditioner(minres);
207 solver.SetPrintLevel(1);
208 solver.SetMaxIter(200);
209 solver.SetRelTol(1e-10);
210 solver.SetAbsTol(0.0);
213
214 // Solve.
215 Vector b(0);
216 coord.SetTrueVector();
217 solver.Mult(b, coord.GetTrueVector());
218 coord.SetFromTrueVector();
219
220 if (glvis)
221 {
222 socketstream vis2;
223 common::VisualizeMesh(vis2, "localhost", 19916, pmesh, "Final mesh",
224 400, 0, 400, 400);
225 }
226
227 delete metric;
228 delete fec_mesh;
229 return 0;
230}
int Size() const
Return the logical size of the array.
Definition array.hpp:192
A coefficient that is constant across space and time.
int GetAttribute() const
Return element's attribute.
Definition element.hpp:58
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition fe_coll.hpp:27
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th boundary fac...
Definition fespace.cpp:3906
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
Definition fespace.hpp:821
int VDofToDof(int vdof) const
Compute the inverse of the Dof to VDof mapping for a single index vdof.
Definition fespace.hpp:1131
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:314
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition fe_base.hpp:410
void SetTrueVector()
Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
Definition gridfunc.hpp:187
void SetFromTrueVector()
Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
Definition gridfunc.hpp:193
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
Definition gridfunc.hpp:173
Arbitrary order H1-conforming (continuous) finite elements.
Definition fe_coll.hpp:291
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Definition hypre.cpp:33
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:96
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void SetRelTol(real_t rtol)
Definition solvers.hpp:238
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
Definition solvers.cpp:76
void SetMaxIter(int max_it)
Definition solvers.hpp:240
void SetAbsTol(real_t atol)
Definition solvers.hpp:239
void SetOperator(const Operator &op) override
Also calls SetOperator for the preconditioner if there is one.
Definition solvers.hpp:901
MINRES method.
Definition solvers.hpp:742
Mesh data type.
Definition mesh.hpp:67
Geometry::Type GetTypicalElementGeometry() const
If the local mesh is not empty, return GetElementGeometry(0); otherwise, return a typical Geometry pr...
Definition mesh.cpp:1705
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1314
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
Definition mesh.hpp:1462
void SetNodalGridFunction(GridFunction *nodes, bool make_owner=false)
Definition mesh.cpp:7200
int GetNBE() const
Returns number of boundary elements.
Definition mesh.hpp:1393
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Definition mesh.cpp:12125
static int WorldRank()
Return the MPI rank in MPI_COMM_WORLD.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
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.
Abstract parallel finite element space.
Definition pfespace.hpp:31
MPI_Comm GetComm() const
Definition pfespace.hpp:337
Class for parallel grid function.
Definition pgridfunc.hpp:50
Class for parallel meshes.
Definition pmesh.hpp:35
void SetNodalFESpace(FiniteElementSpace *nfes) override
Definition pmesh.cpp:2057
Parallel non-linear operator on the true dofs.
Version of QuadraticFECollection with positive basis functions.
Definition fe_coll.hpp:968
void SetAdaptiveSurfaceFittingScalingFactor(real_t factor)
void Mult(const Vector &b, Vector &x) const override
Optimizes the mesh positions given by x.
void SetPreconditioner(Solver &pr) override
This should be called before SetOperator.
void SetTerminationWithMaxSurfaceFittingError(real_t max_error)
Used for error-based surface fitting termination.
A TMOP integrator class based on any given TMOP_QualityMetric and TargetConstructor.
Definition tmop.hpp:1995
3D barrier Shape (S) metric, well-posed (polyconvex & invex).
Definition tmop.hpp:815
Abstract class for local mesh quality metrics in the target-matrix optimization paradigm (TMOP) by P....
Definition tmop.hpp:28
Base class representing target-matrix construction algorithms for mesh optimization via the target-ma...
Definition tmop.hpp:1586
Vector data type.
Definition vector.hpp:82
int dim
Definition ex24.cpp:53
int wsize
char vishost[]
int main()
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
void VisualizeMesh(socketstream &sock, const char *vishost, int visport, Mesh &mesh, const char *title, int x, int y, int w, int h, const char *keys)
void VisualizeField(socketstream &sock, const char *vishost, int visport, GridFunction &gf, const char *title, int x, int y, int w, int h, const char *keys, bool vec)
float real_t
Definition config.hpp:46
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition intrules.hpp:549
STL namespace.