MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
tmop-metric-magnitude.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// Metric Magnitude Miniapp: track changes in TMOP metrics
14// -------------------------------------------------------
15//
16// This miniapp can be used to track how TMPOP metrics change under geometric
17// perturbations.
18//
19// Compile with: make tmop-metric-magnitude
20//
21// Sample runs: tmop-metric-magnitude -mid 7 -pv 2.0 -par 0.5 -ps 4.0
22// tmop-metric-magnitude -mid 321 -pv 2.0 -par 0.5 -ps 4.0
23
24#include "mfem.hpp"
26#include <iostream>
27
28using namespace mfem;
29using namespace std;
30
31void Form2DJac(real_t perturb_v, real_t perturb_ar, real_t perturb_s,
32 DenseMatrix &J);
33void Form3DJac(real_t perturb_v, real_t perturb_ar, real_t perturb_s,
34 DenseMatrix &J);
35
36int main(int argc, char *argv[])
37{
38 int metric_id = 2;
39 real_t perturb_v = 1.0;
40 real_t perturb_ar = 1.0;
41 real_t perturb_s = 1.0;
42
43 OptionsParser args(argc, argv);
44 args.AddOption(&metric_id, "-mid", "--metric-id", "Metric id");
45 args.AddOption(&perturb_v, "-pv", "--perturb-factor-volume",
46 "Volume perturbation factor w.r.t. the ideal element.");
47 args.AddOption(&perturb_ar, "-par", "--perturb-factor-aspect-ratio",
48 "Aspect ratio perturbation factor w.r.t. the ideal element.");
49 args.AddOption(&perturb_s, "-ps", "--perturb-factor-skew",
50 "Skew perturbation factor w.r.t. the ideal element.");
51 args.Parse();
52 if (!args.Good()) { args.PrintUsage(cout); return 1; }
53 args.PrintOptions(cout);
54
55 MFEM_VERIFY(perturb_v > 0.0 && perturb_ar > 0.0 && perturb_s >= 1.0,
56 "Invalid input");
57
58 // Setup metric.
59 TMOP_QualityMetric *metric = NULL;
60 switch (metric_id)
61 {
62 // T-metrics
63 case 1: metric = new TMOP_Metric_001; break;
64 case 2: metric = new TMOP_Metric_002; break;
65 case 7: metric = new TMOP_Metric_007; break;
66 case 9: metric = new TMOP_Metric_009; break;
67 case 14: metric = new TMOP_Metric_014; break;
68 case 50: metric = new TMOP_Metric_050; break;
69 case 55: metric = new TMOP_Metric_055; break;
70 case 56: metric = new TMOP_Metric_056; break;
71 case 58: metric = new TMOP_Metric_058; break;
72 case 77: metric = new TMOP_Metric_077; break;
73 case 85: metric = new TMOP_Metric_085; break;
74 case 98: metric = new TMOP_Metric_098; break;
75 // case 211: metric = new TMOP_Metric_211; break;
76 // case 252: metric = new TMOP_Metric_252(tauval); break;
77 case 301: metric = new TMOP_Metric_301; break;
78 case 302: metric = new TMOP_Metric_302; break;
79 case 303: metric = new TMOP_Metric_303; break;
80 case 304: metric = new TMOP_Metric_304; break;
81 // case 311: metric = new TMOP_Metric_311; break;
82 case 315: metric = new TMOP_Metric_315; break;
83 case 316: metric = new TMOP_Metric_316; break;
84 case 321: metric = new TMOP_Metric_321; break;
85 case 322: metric = new TMOP_Metric_322; break;
86 case 323: metric = new TMOP_Metric_323; break;
87 // case 352: metric = new TMOP_Metric_352(tauval); break;
88 case 360: metric = new TMOP_Metric_360; break;
89 // A-metrics
90 case 11: metric = new TMOP_AMetric_011; break;
91 case 36: metric = new TMOP_AMetric_036; break;
92 case 107: metric = new TMOP_AMetric_107a; break;
93 default: cout << "Unknown metric_id: " << metric_id << endl; return 3;
94 }
95
96 const int dim = (metric_id < 300) ? 2 : 3;
97
98 Mesh *mesh;
99 if (dim == 2)
100 {
102 }
103 else
104 {
105 mesh = new Mesh(Mesh::MakeCartesian3D(1, 1, 1, Element::HEXAHEDRON));
106 }
107 H1_FECollection fec(1, dim);
108 FiniteElementSpace fespace(mesh, &fec, dim);
109 mesh->SetNodalFESpace(&fespace);
110 GridFunction x(&fespace);
111 mesh->SetNodalGridFunction(&x);
112
113 socketstream sock1;
114 common::VisualizeMesh(sock1, "localhost", 19916, *mesh, "ideal", 0, 0);
115
116 DenseMatrix J;
117 (dim == 2) ? Form2DJac(perturb_v, perturb_ar, perturb_s, J)
118 /* */ : Form3DJac(perturb_v, perturb_ar, perturb_s, J);
119
120 const int nodes_cnt = x.Size() / dim;
121 for (int i = 0; i < nodes_cnt; i++)
122 {
123 Vector X(dim);
124 for (int d = 0; d < dim; d++) { X(d) = x(i + d * nodes_cnt); }
125 Vector Jx(dim);
126 J.Mult(X, Jx);
127 for (int d = 0; d < dim; d++) { x(i + d * nodes_cnt) = Jx(d); }
128 }
129
130 socketstream sock2;
131 common::VisualizeMesh(sock2, "localhost", 19916, *mesh, "perturbed", 400, 0);
132
133 // Target is always identity -> Jpt = Jpr.
134 cout << "Magnitude of metric " << metric_id << ": " << metric->EvalW(J)
135 << "\n volume perturbation factor: " << perturb_v
136 << "\n aspect ratio pert factor: " << perturb_ar
137 << "\n skew perturbation factor: " << perturb_s << endl;
138
139 delete metric;
140 delete mesh;
141 return 0;
142}
143
144void Form2DJac(real_t perturb_v, real_t perturb_ar, real_t perturb_s,
145 DenseMatrix &J)
146{
147 // Volume.
148 const real_t volume = 1.0 * perturb_v;
149
150 // Aspect Ratio.
151 const real_t a_r = 1.0 * perturb_ar;
152 DenseMatrix M_ar(2); M_ar = 0.0;
153 M_ar(0, 0) = 1.0 / sqrt(a_r);
154 M_ar(1, 1) = sqrt(a_r);
155
156 // Skew.
157 const real_t skew_angle = M_PI / 2.0 / perturb_s;
158 DenseMatrix M_skew(2);
159 M_skew(0, 0) = 1.0; M_skew(0, 1) = cos(skew_angle);
160 M_skew(1, 0) = 0.0; M_skew(1, 1) = sin(skew_angle);
161
162 // Rotation.
163 const real_t rot_angle = 0.0; // not sure how to choose
164 DenseMatrix M_rot(2);
165 M_rot(0, 0) = cos(rot_angle); M_rot(0, 1) = -sin(rot_angle);
166 M_rot(1, 0) = sin(rot_angle); M_rot(1, 1) = cos(rot_angle);
167
168 // Form J.
169 J.SetSize(2);
170 DenseMatrix TMP(2);
171 Mult(M_rot, M_skew, TMP);
172 Mult(TMP, M_ar, J);
173 J *= sqrt(volume / sin(skew_angle));
174}
175
176void Form3DJac(real_t perturb_v, real_t perturb_ar, real_t perturb_s,
177 DenseMatrix &J)
178{
179 // Volume.
180 const real_t volume = 1.0 * perturb_v;
181
182 // Aspect Ratio - only in one direction, the others are uniform.
183 const real_t ar_1 = 1.0 * perturb_ar,
184 ar_2 = 1.0,
185 ar_3 = 1.0;
186
187 // Skew - only in one direction, the others are pi/2.
188 const real_t skew_angle_12 = M_PI / 2.0 / perturb_s,
189 skew_angle_13 = M_PI / 2.0,
190 skew_angle_23 = M_PI / 2.0;
191
192 // Rotation - not done yet.
193
194 J.SetSize(3);
195 //
196 J(0, 0) = pow(ar_1, 1.0/3.0);
197 J(0, 1) = pow(ar_2, 1.0/3.0) * cos(skew_angle_12);
198 J(0, 2) = pow(ar_3, 1.0/3.0) * cos(skew_angle_13);
199 //
200 J(1, 0) = 0.0;
201 J(1, 1) = pow(ar_2, 1.0/3.0) * sin(skew_angle_12);
202 J(1, 2) = pow(ar_3, 1.0/3.0) * sin(skew_angle_13) * cos(skew_angle_23);
203 //
204 J(2, 0) = 0.0;
205 J(2, 1) = 0.0;
206 J(2, 2) = pow(ar_3, 1.0/3.0) * sin(skew_angle_13) * sin(skew_angle_23);
207 //
208
209 real_t sin3 = sin(skew_angle_12)*sin(skew_angle_13)*sin(skew_angle_23),
210 ar3 = pow(ar_1, 1.0/3.0) * pow(ar_2, 1.0/3.0) * pow(ar_3, 1.0/3.0);
211 J *= pow(volume / (sin3 * ar3), 1.0/3.0);
212}
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
Definition densemat.cpp:220
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition densemat.hpp:105
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:220
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:31
Arbitrary order H1-conforming (continuous) finite elements.
Definition fe_coll.hpp:260
Mesh data type.
Definition mesh.hpp:56
static Mesh MakeCartesian3D(int nx, int ny, int nz, Element::Type type, real_t sx=1.0, real_t sy=1.0, real_t sz=1.0, bool sfc_ordering=true)
Creates a mesh for the parallelepiped [0,sx]x[0,sy]x[0,sz], divided into nx*ny*nz hexahedra if type =...
Definition mesh.cpp:4253
void SetNodalGridFunction(GridFunction *nodes, bool make_owner=false)
Definition mesh.cpp:6200
virtual void SetNodalFESpace(FiniteElementSpace *nfes)
Definition mesh.cpp:6153
static Mesh MakeCartesian2D(int nx, int ny, Element::Type type, bool generate_edges=false, real_t sx=1.0, real_t sy=1.0, bool sfc_ordering=true)
Creates mesh for the rectangle [0,sx]x[0,sy], divided into nx*ny quadrilaterals if type = QUADRILATER...
Definition mesh.cpp:4243
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.
2D barrier Shape+Size+Orientation (VOS) metric (polyconvex).
Definition tmop.hpp:1114
2D barrier Shape+Orientation (OS) metric (polyconvex).
Definition tmop.hpp:1132
2D non-barrier metric without a type.
Definition tmop.hpp:222
2D barrier Shape+Size (VS) metric (not polyconvex).
Definition tmop.hpp:341
2D barrier Shape+Size (VS) metric (not polyconvex).
Definition tmop.hpp:359
2D non-barrier Shape+Size+Orientation (VOS) metric (polyconvex).
Definition tmop.hpp:375
2D barrier shape (S) metric (not polyconvex).
Definition tmop.hpp:471
2D barrier Shape+Orientation (OS) metric (polyconvex).
Definition tmop.hpp:557
2D barrier Shape+Size+Orientation (VOS) metric (polyconvex).
Definition tmop.hpp:614
3D barrier Shape (S) metric, well-posed (polyconvex & invex).
Definition tmop.hpp:668
3D barrier Shape (S) metric, well-posed (polyconvex & invex).
Definition tmop.hpp:687
3D barrier Shape (S) metric, well-posed (polyconvex & invex).
Definition tmop.hpp:708
3D barrier Shape (S) metric, well-posed (polyconvex & invex).
Definition tmop.hpp:729
3D Size (V) metric.
Definition tmop.hpp:790
3D Size (V) metric.
Definition tmop.hpp:808
3D barrier Shape+Size (VS) metric, well-posed (invex).
Definition tmop.hpp:848
3D barrier Shape+Size (VS) metric, well-posed (invex).
Definition tmop.hpp:869
3D barrier Shape+Size (VS) metric, well-posed (invex).
Definition tmop.hpp:890
3D non-barrier Shape (S) metric.
Definition tmop.hpp:1056
Abstract class for local mesh quality metrics in the target-matrix optimization paradigm (TMOP) by P....
Definition tmop.hpp:24
virtual real_t EvalW(const DenseMatrix &Jpt) const =0
Evaluate the strain energy density function, W = W(Jpt), by using the 2D or 3D matrix invariants,...
Vector data type.
Definition vector.hpp:80
int Size() const
Returns the size of the vector.
Definition vector.hpp:218
int dim
Definition ex24.cpp:53
int main()
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 Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:476
float real_t
Definition config.hpp:43
void Form3DJac(real_t perturb_v, real_t perturb_ar, real_t perturb_s, DenseMatrix &J)
void Form2DJac(real_t perturb_v, real_t perturb_ar, real_t perturb_s, DenseMatrix &J)