72 const double small = 0.001, big = 0.01;
77 const double X = x(0), Y = x(1);
78 const double ind = std::tanh((10*(Y-0.5) + std::sin(4.0*M_PI*X)) + 1) -
79 std::tanh((10*(Y-0.5) + std::sin(4.0*M_PI*X)) - 1);
81 return ind * small + (1.0 - ind) * big;
88 const double xc = x(0) - 0.5, yc = x(1) - 0.5;
89 const double r = sqrt(xc*xc + yc*yc);
90 double r1 = 0.15;
double r2 = 0.35;
double sf=30.0;
91 val = 0.5*(std::tanh(sf*(r-r1)) - std::tanh(sf*(r-r2)));
92 if (val > 1.) {val = 1;}
94 return val * small + (1.0 - val) * big;
100 const double X = x(0), Y = x(1);
101 const double r1 = 0.45, r2 = 0.55;
102 const double sf = 40.0;
104 double val = 0.5 * ( std::tanh(sf*(X-r1)) - std::tanh(sf*(X-r2)) +
105 std::tanh(sf*(Y-r1)) - std::tanh(sf*(Y-r2)) );
106 if (val > 1.) { val = 1.0; }
108 return val * small + (1.0 - val) * big;
114 double r1,r2,val,rval;
118 r1= 0.25; r2 = 0.25; rval = 0.1;
119 double xc = x(0) - r1, yc = x(1) - r2;
120 double r = sqrt(xc*xc+yc*yc);
121 val = 0.5*(1+std::tanh(sf*(r+rval))) - 0.5*(1+std::tanh(sf*
125 xc = x(0) - r1, yc = x(1) - r2;
126 r = sqrt(xc*xc+yc*yc);
127 val += (0.5*(1+std::tanh(sf*(r+rval))) - 0.5*(1+std::tanh(sf*
131 xc = x(0) - r1, yc = x(1) - r2;
132 r = sqrt(xc*xc+yc*yc);
133 val += 0.5*(1+std::tanh(sf*(r+rval))) - 0.5*(1+std::tanh(sf*
137 xc = x(0) - r1, yc = x(1) - r2;
138 r = sqrt(xc*xc+yc*yc);
139 val += 0.5*(1+std::tanh(sf*(r+rval))) - 0.5*(1+std::tanh(sf*(r-rval)));
140 if (val > 1.0) {val = 1.;}
141 if (val < 0.0) {val = 0.;}
143 return val * small + (1.0 - val) * big;
150 double X = x(0)-0.5, Y = x(1)-0.5;
151 double rval = std::sqrt(X*X + Y*Y);
152 double thval = 60.*M_PI/180.;
154 Xmod = X*std::cos(thval) + Y*std::sin(thval);
155 Ymod= -X*std::sin(thval) + Y*std::cos(thval);
156 X = Xmod+0.5; Y = Ymod+0.5;
157 double r1 = 0.45;
double r2 = 0.55;
double sf=30.0;
158 val = ( 0.5*(1+std::tanh(sf*(X-r1))) - 0.5*(1+std::tanh(sf*(X-r2)))
159 + 0.5*(1+std::tanh(sf*(Y-r1))) - 0.5*(1+std::tanh(sf*(Y-r2))) );
160 if (rval > 0.4) {val = 0.;}
161 if (val > 1.0) {val = 1.;}
162 if (val < 0.0) {val = 0.;}
164 return val * small + (1.0 - val) * big;
170 const double xc = x(0) - 0.0, yc = x(1) - 0.5;
171 const double r = sqrt(xc*xc + yc*yc);
172 double r1 = 0.45;
double r2 = 0.55;
double sf=30.0;
173 val = 0.5*(1+std::tanh(sf*(r-r1))) - 0.5*(1+std::tanh(sf*(r-r2)));
174 if (val > 1.) {val = 1;}
175 if (val < 0.) {val = 0;}
177 return val * small + (1.0 - val) * big;
189 HessianCoefficient(
int dim,
int type_)
200 K(0, 0) = 1.0 + 3.0 * std::sin(M_PI*pos(0));
207 const double xc = pos(0) - 0.5, yc = pos(1) - 0.5;
208 const double r = sqrt(xc*xc + yc*yc);
209 double r1 = 0.15;
double r2 = 0.35;
double sf=30.0;
210 const double eps = 0.5;
212 const double tan1 = std::tanh(sf*(r-r1)),
213 tan2 = std::tanh(sf*(r-r2));
215 K(0, 0) = eps + 1.0 * (tan1 - tan2);
228 int main (
int argc,
char *argv[])
231 const char *mesh_file =
"icf.mesh";
232 int mesh_poly_deg = 1;
237 double lim_const = 0.0;
240 int newton_iter = 10;
241 double newton_rtol = 1e-12;
243 int max_lin_iter = 100;
244 bool move_bnd =
true;
246 bool normalization =
false;
247 bool visualization =
true;
248 int verbosity_level = 0;
252 args.
AddOption(&mesh_file,
"-m",
"--mesh",
253 "Mesh file to use.");
254 args.
AddOption(&mesh_poly_deg,
"-o",
"--order",
255 "Polynomial degree of mesh finite element space.");
256 args.
AddOption(&rs_levels,
"-rs",
"--refine-serial",
257 "Number of times to refine the mesh uniformly in serial.");
258 args.
AddOption(&jitter,
"-ji",
"--jitter",
259 "Random perturbation scaling factor.");
260 args.
AddOption(&metric_id,
"-mid",
"--metric-id",
261 "Mesh optimization metric:\n\t"
262 "1 : |T|^2 -- 2D shape\n\t"
263 "2 : 0.5|T|^2/tau-1 -- 2D shape (condition number)\n\t"
264 "7 : |T-T^-t|^2 -- 2D shape+size\n\t"
265 "9 : tau*|T-T^-t|^2 -- 2D shape+size\n\t"
266 "22 : 0.5(|T|^2-2*tau)/(tau-tau_0) -- 2D untangling\n\t"
267 "50 : 0.5|T^tT|^2/tau^2-1 -- 2D shape\n\t"
268 "55 : (tau-1)^2 -- 2D size\n\t"
269 "56 : 0.5(sqrt(tau)-1/sqrt(tau))^2 -- 2D size\n\t"
270 "58 : |T^tT|^2/(tau^2)-2*|T|^2/tau+2 -- 2D shape\n\t"
271 "77 : 0.5(tau-1/tau)^2 -- 2D size\n\t"
272 "211: (tau-1)^2-tau+sqrt(tau^2) -- 2D untangling\n\t"
273 "252: 0.5(tau-1)^2/(tau-tau_0) -- 2D untangling\n\t"
274 "301: (|T||T^-1|)/3-1 -- 3D shape\n\t"
275 "302: (|T|^2|T^-1|^2)/9-1 -- 3D shape\n\t"
276 "303: (|T|^2)/3*tau^(2/3)-1 -- 3D shape\n\t"
277 "315: (tau-1)^2 -- 3D size\n\t"
278 "316: 0.5(sqrt(tau)-1/sqrt(tau))^2 -- 3D size\n\t"
279 "321: |T-T^-t|^2 -- 3D shape+size\n\t"
280 "352: 0.5(tau-1)^2/(tau-tau_0) -- 3D untangling");
281 args.
AddOption(&target_id,
"-tid",
"--target-id",
282 "Target (ideal element) type:\n\t"
283 "1: Ideal shape, unit size\n\t"
284 "2: Ideal shape, equal size\n\t"
285 "3: Ideal shape, initial size\n\t"
286 "4: Given full analytic Jacobian (in physical space)\n\t"
287 "5: Ideal shape, given size (in physical space)");
288 args.
AddOption(&lim_const,
"-lc",
"--limit-const",
"Limiting constant.");
289 args.
AddOption(&quad_type,
"-qt",
"--quad-type",
290 "Quadrature rule type:\n\t"
291 "1: Gauss-Lobatto\n\t"
292 "2: Gauss-Legendre\n\t"
293 "3: Closed uniform points");
294 args.
AddOption(&quad_order,
"-qo",
"--quad_order",
295 "Order of the quadrature rule.");
296 args.
AddOption(&newton_iter,
"-ni",
"--newton-iters",
297 "Maximum number of Newton iterations.");
298 args.
AddOption(&newton_rtol,
"-rtol",
"--newton-rel-tolerance",
299 "Relative tolerance for the Newton solver.");
300 args.
AddOption(&lin_solver,
"-ls",
"--lin-solver",
301 "Linear solver: 0 - l1-Jacobi, 1 - CG, 2 - MINRES.");
302 args.
AddOption(&max_lin_iter,
"-li",
"--lin-iter",
303 "Maximum number of iterations in the linear solve.");
304 args.
AddOption(&move_bnd,
"-bnd",
"--move-boundary",
"-fix-bnd",
306 "Enable motion along horizontal and vertical boundaries.");
307 args.
AddOption(&combomet,
"-cmb",
"--combo-met",
"-no-cmb",
"--no-combo-met",
308 "Combination of metrics.");
309 args.
AddOption(&normalization,
"-nor",
"--normalization",
"-no-nor",
310 "--no-normalization",
311 "Make all terms in the optimization functional unitless.");
312 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
313 "--no-visualization",
314 "Enable or disable GLVis visualization.");
315 args.
AddOption(&verbosity_level,
"-vl",
"--verbosity-level",
316 "Set the verbosity level - 0, 1, or 2.");
326 Mesh *mesh =
new Mesh(mesh_file, 1, 1,
false);
329 cout <<
"Mesh curvature: ";
331 else { cout <<
"(NONE)"; }
339 if (mesh_poly_deg <= 0)
370 for (
int i = 0; i < mesh->
GetNE(); i++)
376 for (
int j = 0; j < dofs.
Size(); j++)
378 h0(dofs[j]) = min(h0(dofs[j]), hi);
382 const double small_phys_size = pow(volume, 1.0 / dim) / 100.0;
394 for (
int i = 0; i < fespace->
GetNDofs(); i++)
396 for (
int d = 0; d <
dim; d++)
402 for (
int i = 0; i < fespace->
GetNBE(); i++)
407 for (
int j = 0; j < vdofs.
Size(); j++) { rdm(vdofs[j]) = 0.0; }
416 ofstream mesh_ofs(
"perturbed.mesh");
417 mesh->
Print(mesh_ofs);
425 double tauval = -0.1;
448 default: cout <<
"Unknown metric_id: " << metric_id << endl;
return 3;
452 HessianCoefficient *adapt_coeff = NULL;
465 adapt_coeff =
new HessianCoefficient(dim, 1);
481 default: cout <<
"Unknown target_id: " << target_id << endl;
return 3;
484 if (target_c == NULL)
497 case 2: ir = &
IntRules.
Get(geom_type, quad_order);
break;
499 default: cout <<
"Unknown quad_type: " << quad_type << endl;
500 delete he_nlf_integ;
return 3;
502 cout <<
"Quadrature points per cell: " << ir->
GetNPoints() << endl;
512 if (normalization) { dist = small_phys_size; }
514 if (lim_const != 0.0) { he_nlf_integ->
EnableLimiting(x0, dist, lim_coeff); }
532 if (normalization) { MFEM_ABORT(
"Not implemented."); }
558 char title[] =
"Initial metric values";
567 if (move_bnd ==
false)
577 for (
int i = 0; i < mesh->
GetNBE(); i++)
580 MFEM_VERIFY(!(dim == 2 && attr == 3),
581 "Boundary attribute 3 must be used only for 3D meshes. "
582 "Adjust the attributes (1/2/3/4 for fixed x/y/z/all "
583 "components, rest for free nodes), or use -fix-bnd.");
584 if (attr == 1 || attr == 2 || attr == 3) { n += nd; }
585 if (attr == 4) { n += nd *
dim; }
589 for (
int i = 0; i < mesh->
GetNBE(); i++)
595 for (
int j = 0; j < nd; j++)
596 { ess_vdofs[n++] = vdofs[j]; }
600 for (
int j = 0; j < nd; j++)
601 { ess_vdofs[n++] = vdofs[j+nd]; }
605 for (
int j = 0; j < nd; j++)
606 { ess_vdofs[n++] = vdofs[j+2*nd]; }
610 for (
int j = 0; j < vdofs.
Size(); j++)
611 { ess_vdofs[n++] = vdofs[j]; }
620 const double linsol_rtol = 1e-12;
625 else if (lin_solver == 1)
646 const int NE = mesh->
GetNE();
647 for (
int i = 0; i < NE; i++)
656 cout <<
"Minimum det(J) of the original mesh is " << tauval << endl;
669 cout <<
"TMOPNewtonSolver is used (as all det(J) > 0).\n";
673 if ( (dim == 2 && metric_id != 22 && metric_id != 252) ||
674 (dim == 3 && metric_id != 352) )
676 cout <<
"The mesh is inverted. Use an untangling metric." << endl;
679 tauval -= 0.01 * h0.Min();
681 cout <<
"The TMOPDescentNewtonSolver is used (as some det(J) < 0).\n";
694 cout <<
"NewtonIteration: rtol = " << newton_rtol <<
" not achieved."
702 ofstream mesh_ofs(
"optimized.mesh");
703 mesh_ofs.precision(14);
704 mesh->
Print(mesh_ofs);
709 double metric_part = fin_energy;
710 if (lim_const != 0.0)
716 cout <<
"Initial strain energy: " << init_energy
717 <<
" = metrics: " << init_energy
718 <<
" + limiting term: " << 0.0 << endl;
719 cout <<
" Final strain energy: " << fin_energy
720 <<
" = metrics: " << metric_part
721 <<
" + limiting term: " << fin_energy - metric_part << endl;
722 cout <<
"The strain energy decreased by: " << setprecision(12)
723 << (init_energy - fin_energy) * 100.0 / init_energy <<
" %." << endl;
728 char title[] =
"Final metric values";
737 sock <<
"solution\n";
741 sock <<
"window_title 'Displacements'\n"
742 <<
"window_geometry "
743 << 1200 <<
" " << 0 <<
" " << 600 <<
" " << 600 <<
"\n"
744 <<
"keys jRmclA" << endl;
764 const double r = sqrt(x(0)*x(0) + x(1)*x(1) + 1e-12);
765 const double den = 0.002;
766 double l2 = 0.2 + 0.5*std::tanh((r-0.16)/den) - 0.5*std::tanh((r-0.17)/den)
767 + 0.5*std::tanh((r-0.23)/den) - 0.5*std::tanh((r-0.24)/den);
int GetNPoints() const
Returns the number of the points in the integration rule.
int Size() const
Logical size of the array.
Shifted barrier form of metric 56 (area, ideal barrier metric), 2D.
Shifted barrier form of 3D metric 16 (volume, ideal barrier metric), 3D.
virtual void Print(std::ostream &out=mfem::out) const
Conjugate gradient method.
int GetNDofs() const
Returns number of degrees of freedom.
Class for an integration rule - an Array of IntegrationPoint.
Class for grid function - Vector with associated FE space.
int DofToVDof(int dof, int vd, int ndofs=-1) const
Shape & volume, ideal barrier metric, 3D.
Data type for scaled Jacobi-type smoother of sparse matrix.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void SetFromTrueVector()
Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
Subclass constant coefficient.
void EnableNormalization(const GridFunction &x)
Computes the normalization factors of the metric and limiting integrals using the mesh position given...
int GetNBE() const
Returns number of boundary elements.
Shape, ideal barrier metric, 3D.
Allows negative Jacobians. Used for untangling.
Container class for integration rules.
Data type dense matrix using column-major storage.
Shape, ideal barrier metric, 3D.
void SetVolumeScale(double vol_scale)
Used by target type IDEAL_SHAPE_EQUAL_SIZE. The default volume scale is 1.
Shape, ideal barrier metric, 2D.
Area, ideal barrier metric, 2D.
int GetNE() const
Returns number of elements.
virtual void SetSerialDiscreteTargetSpec(GridFunction &tspec)
void vis_tmop_metric_s(int order, TMOP_QualityMetric &qm, const TargetConstructor &tc, Mesh &mesh, char *title, int position)
void Randomize(int seed=0)
Set random values in the vector.
int main(int argc, char *argv[])
double weight_fun(const Vector &x)
Shape & area, ideal barrier metric, 2D.
Shifted barrier form of metric 2 (shape, ideal barrier metric), 2D.
Shape, ideal barrier metric, 2D.
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Abstract class for local mesh quality metrics in the target-matrix optimization paradigm (TMOP) by P...
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
void SetTrueVector()
Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
void SetPrintLevel(int print_lvl)
void EnableLimiting(const GridFunction &n0, const GridFunction &dist, Coefficient &w0, TMOP_LimiterFunction *lfunc=NULL)
Adds a limiting term to the integrator (general version).
int GetNBE() const
Returns number of boundary elements in the mesh.
void SetCoefficient(Coefficient &w1)
Sets a scaling Coefficient for the quality metric term of the integrator.
Volume, ideal barrier metric, 3D.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
IntegrationRules IntRulesLo(0, Quadrature1D::GaussLobatto)
void SetNodes(const GridFunction &n)
Set the nodes to be used in the target-matrix construction.
void SetMaxIter(int max_it)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
virtual void GetElementDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
Newton's method for solving F(x)=b for a given operator F.
Version of QuadraticFECollection with positive basis functions.
int GetAttribute() const
Return element's attribute.
double ind_values(const Vector &x)
void SetNodalFESpace(FiniteElementSpace *nfes)
void PrintUsage(std::ostream &out) const
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
double GetElementSize(int i, int type=0)
Get the size of the i-th element relative to the perfect reference element.
void SetAbsTol(double atol)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void SetRelTol(double rtol)
Shape, ideal barrier metric, 2D.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Area, ideal barrier metric, 2D.
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)
virtual void SetAnalyticTargetSpec(Coefficient *sspec, VectorCoefficient *vspec, MatrixCoefficient *mspec)
Shape & area metric, 2D.
Class for integration point with weight.
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement associated with i'th element.
void PrintOptions(std::ostream &out) const
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
virtual void ProjectCoefficient(Coefficient &coeff)
virtual void SetSpace(FiniteElementSpace *f)
Associate a new FiniteElementSpace with the GridFunction.
class for C-function coefficient
IntegrationRules IntRulesCU(0, Quadrature1D::ClosedUniform)
void GetNodes(Vector &node_coord) const
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Arbitrary order H1-conforming (continuous) finite elements.
TargetType
Target-matrix construction algorithms supported by this class.
void SetDiscreteAdaptTC(DiscreteAdaptTC *tc)
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement for the i'th boundary element.
void GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i'th boundary element.
void SetNodalGridFunction(GridFunction *nodes, bool make_owner=false)
Base class representing target-matrix construction algorithms for mesh optimization via the target-ma...
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
double GetElementVolume(int i)
const Element * GetBdrElement(int i) const
Shape, ideal barrier metric, 3D.
Metric without a type, 2D.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
A TMOP integrator class based on any given TMOP_QualityMetric and TargetConstructor.