50 Mesh &mesh,
char *title,
int position)
61 sock <<
"window_title '"<< title <<
"'\n"
63 << position <<
" " << 0 <<
" " << 600 <<
" " << 600 <<
"\n"
64 <<
"keys jRmclA" << endl;
76 virtual double ComputeScalingFactor(
const Vector &x,
const Vector &b)
const;
79 double RelaxedNewtonSolver::ComputeScalingFactor(
const Vector &x,
83 MFEM_VERIFY(nlf != NULL,
"invalid Operator subclass");
84 const bool have_b = (b.
Size() == Height());
88 dof = fes->
GetFE(0)->
GetDof(), nsp = ir.GetNPoints();
94 bool x_out_ok =
false;
95 const double energy_in = nlf->
GetEnergy(x);
96 double scale = 1.0, energy_out;
97 double norm0 = Norm(r);
99 for (
int i = 0; i < 12; i++)
101 add(x, -scale, c, x_out);
104 if (energy_out > 1.2*energy_in || isnan(energy_out) != 0)
106 if (print_level >= 0)
107 { cout <<
"Scale = " << scale <<
" Increasing energy." << endl; }
108 scale *= 0.5;
continue;
112 for (
int i = 0; i < NE; i++)
115 x_out.GetSubVector(xdofs, posV);
116 for (
int j = 0; j < nsp; j++)
120 if (Jpr.Det() <= 0.0) { jac_ok = 0;
goto break2; }
126 if (print_level >= 0)
127 { cout <<
"Scale = " << scale <<
" Neg det(J) found." << endl; }
128 scale *= 0.5;
continue;
131 oper->Mult(x_out, r);
132 if (have_b) { r -= b; }
133 double norm = Norm(r);
135 if (norm > 1.2*norm0)
137 if (print_level >= 0)
138 { cout <<
"Scale = " << scale <<
" Norm increased." << endl; }
139 scale *= 0.5;
continue;
141 else { x_out_ok =
true;
break; }
144 if (print_level >= 0)
146 cout <<
"Energy decrease: "
147 << (energy_in - energy_out) / energy_in * 100.0
148 <<
"% with " << scale <<
" scaling." << endl;
151 if (x_out_ok ==
false) { scale = 0.0; }
166 virtual double ComputeScalingFactor(
const Vector &x,
const Vector &b)
const;
169 double DescentNewtonSolver::ComputeScalingFactor(
const Vector &x,
173 MFEM_VERIFY(nlf != NULL,
"invalid Operator subclass");
177 dof = fes->
GetFE(0)->
GetDof(), nsp = ir.GetNPoints();
182 double min_detJ = numeric_limits<double>::infinity();
183 for (
int i = 0; i < NE; i++)
187 for (
int j = 0; j < nsp; j++)
191 min_detJ = min(min_detJ, Jpr.Det());
194 cout <<
"Minimum det(J) = " << min_detJ << endl;
197 bool x_out_ok =
false;
198 const double energy_in = nlf->
GetEnergy(x);
199 double scale = 1.0, energy_out;
201 for (
int i = 0; i < 7; i++)
203 add(x, -scale, c, x_out);
206 if (energy_out > energy_in || isnan(energy_out) != 0)
210 else { x_out_ok =
true;
break; }
213 cout <<
"Energy decrease: " << (energy_in - energy_out) / energy_in * 100.0
214 <<
"% with " << scale <<
" scaling." << endl;
216 if (x_out_ok ==
false) {
return 0.0;}
226 int main (
int argc,
char *argv[])
229 const char *mesh_file =
"icf.mesh";
230 int mesh_poly_deg = 1;
235 double lim_const = 0.0;
238 int newton_iter = 10;
239 double newton_rtol = 1e-12;
241 int max_lin_iter = 100;
242 bool move_bnd =
true;
244 bool visualization =
true;
245 int verbosity_level = 0;
249 args.
AddOption(&mesh_file,
"-m",
"--mesh",
250 "Mesh file to use.");
251 args.
AddOption(&mesh_poly_deg,
"-o",
"--order",
252 "Polynomial degree of mesh finite element space.");
253 args.
AddOption(&rs_levels,
"-rs",
"--refine-serial",
254 "Number of times to refine the mesh uniformly in serial.");
255 args.
AddOption(&jitter,
"-ji",
"--jitter",
256 "Random perturbation scaling factor.");
257 args.
AddOption(&metric_id,
"-mid",
"--metric-id",
258 "Mesh optimization metric:\n\t"
259 "1 : |T|^2 -- 2D shape\n\t"
260 "2 : 0.5|T|^2/tau-1 -- 2D shape (condition number)\n\t"
261 "7 : |T-T^-t|^2 -- 2D shape+size\n\t"
262 "9 : tau*|T-T^-t|^2 -- 2D shape+size\n\t"
263 "22 : 0.5(|T|^2-2*tau)/(tau-tau_0) -- 2D untangling\n\t"
264 "50 : 0.5|T^tT|^2/tau^2-1 -- 2D shape\n\t"
265 "55 : (tau-1)^2 -- 2D size\n\t"
266 "56 : 0.5(sqrt(tau)-1/sqrt(tau))^2 -- 2D size\n\t"
267 "58 : |T^tT|^2/(tau^2)-2*|T|^2/tau+2 -- 2D shape\n\t"
268 "77 : 0.5(tau-1/tau)^2 -- 2D size\n\t"
269 "211: (tau-1)^2-tau+sqrt(tau^2) -- 2D untangling\n\t"
270 "252: 0.5(tau-1)^2/(tau-tau_0) -- 2D untangling\n\t"
271 "301: (|T||T^-1|)/3-1 -- 3D shape\n\t"
272 "302: (|T|^2|T^-1|^2)/9-1 -- 3D shape\n\t"
273 "303: (|T|^2)/3*tau^(2/3)-1 -- 3D shape\n\t"
274 "315: (tau-1)^2 -- 3D size\n\t"
275 "316: 0.5(sqrt(tau)-1/sqrt(tau))^2 -- 3D size\n\t"
276 "321: |T-T^-t|^2 -- 3D shape+size\n\t"
277 "352: 0.5(tau-1)^2/(tau-tau_0) -- 3D untangling");
278 args.
AddOption(&target_id,
"-tid",
"--target-id",
279 "Target (ideal element) type:\n\t"
280 "1: Ideal shape, unit size\n\t"
281 "2: Ideal shape, equal size\n\t"
282 "3: Ideal shape, initial size");
283 args.
AddOption(&lim_const,
"-lc",
"--limit-const",
"Limiting constant.");
284 args.
AddOption(&quad_type,
"-qt",
"--quad-type",
285 "Quadrature rule type:\n\t"
286 "1: Gauss-Lobatto\n\t"
287 "2: Gauss-Legendre\n\t"
288 "3: Closed uniform points");
289 args.
AddOption(&quad_order,
"-qo",
"--quad_order",
290 "Order of the quadrature rule.");
291 args.
AddOption(&newton_iter,
"-ni",
"--newton-iters",
292 "Maximum number of Newton iterations.");
293 args.
AddOption(&newton_rtol,
"-rtol",
"--newton-rel-tolerance",
294 "Relative tolerance for the Newton solver.");
295 args.
AddOption(&lin_solver,
"-ls",
"--lin-solver",
296 "Linear solver: 0 - l1-Jacobi, 1 - CG, 2 - MINRES.");
297 args.
AddOption(&max_lin_iter,
"-li",
"--lin-iter",
298 "Maximum number of iterations in the linear solve.");
299 args.
AddOption(&move_bnd,
"-bnd",
"--move-boundary",
"-fix-bnd",
301 "Enable motion along horizontal and vertical boundaries.");
302 args.
AddOption(&combomet,
"-cmb",
"--combo-met",
"-no-cmb",
"--no-combo-met",
303 "Combination of metrics.");
304 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
305 "--no-visualization",
306 "Enable or disable GLVis visualization.");
307 args.
AddOption(&verbosity_level,
"-vl",
"--verbosity-level",
308 "Set the verbosity level - 0, 1, or 2.");
318 Mesh *mesh =
new Mesh(mesh_file, 1, 1,
false);
321 cout <<
"Mesh curvature: ";
323 else { cout <<
"(NONE)"; }
331 if (mesh_poly_deg <= 0)
356 h0 = numeric_limits<double>::infinity();
358 for (
int i = 0; i < mesh->
GetNE(); i++)
363 for (
int j = 0; j < dofs.
Size(); j++)
379 for (
int i = 0; i < fespace->
GetNDofs(); i++)
381 for (
int d = 0; d <
dim; d++)
387 for (
int i = 0; i < fespace->
GetNBE(); i++)
392 for (
int j = 0; j < vdofs.
Size(); j++) { rdm(vdofs[j]) = 0.0; }
399 ofstream mesh_ofs(
"perturbed.mesh");
400 mesh->
Print(mesh_ofs);
408 double tauval = -0.1;
431 default: cout <<
"Unknown metric_id: " << metric_id << endl;
return 3;
439 default: cout <<
"Unknown target_id: " << target_id << endl;
return 3;
451 case 2: ir = &
IntRules.
Get(geom_type, quad_order);
break;
453 default: cout <<
"Unknown quad_type: " << quad_type << endl;
return 3;
455 cout <<
"Quadrature points per cell: " << ir->
GetNPoints() << endl;
460 if (lim_const != 0.0) { he_nlf_integ->
EnableLimiting(x0, lim_coeff); }
493 cout <<
"Initial strain energy: " << init_en << endl;
498 char title[] =
"Initial metric values";
499 vis_metric(mesh_poly_deg, *metric, *target_c, *mesh, title, 0);
507 if (move_bnd ==
false)
517 for (
int i = 0; i < mesh->
GetNBE(); i++)
520 if (attr == 1 || attr == 2 || attr == 3) { n += nd; }
521 if (attr == 4) { n += nd *
dim; }
525 for (
int i = 0; i < mesh->
GetNBE(); i++)
531 for (
int j = 0; j < nd; j++)
532 { ess_vdofs[n++] = vdofs[j]; }
536 for (
int j = 0; j < nd; j++)
537 { ess_vdofs[n++] = vdofs[j+nd]; }
541 for (
int j = 0; j < nd; j++)
542 { ess_vdofs[n++] = vdofs[j+2*nd]; }
546 for (
int j = 0; j < vdofs.
Size(); j++)
547 { ess_vdofs[n++] = vdofs[j]; }
556 const double linsol_rtol = 1e-12;
561 else if (lin_solver == 1)
581 tauval = numeric_limits<double>::infinity();
582 const int NE = mesh->
GetNE();
583 for (
int i = 0; i < NE; i++)
592 cout <<
"Minimum det(J) of the original mesh is " << tauval << endl;
599 newton =
new RelaxedNewtonSolver(*ir);
600 cout <<
"The RelaxedNewtonSolver is used (as all det(J)>0)." << endl;
604 if ( (dim == 2 && metric_id != 22 && metric_id != 252) ||
605 (dim == 3 && metric_id != 352) )
607 cout <<
"The mesh is inverted. Use an untangling metric." << endl;
610 tauval -= 0.01 * h0.Min();
611 newton =
new DescentNewtonSolver(*ir);
612 cout <<
"The DescentNewtonSolver is used (as some det(J)<0)." << endl;
623 cout <<
"NewtonIteration: rtol = " << newton_rtol <<
" not achieved."
631 ofstream mesh_ofs(
"optimized.mesh");
632 mesh_ofs.precision(14);
633 mesh->
Print(mesh_ofs);
638 cout <<
"Final strain energy : " << fin_en << endl;
639 cout <<
"The strain energy decreased by: " << setprecision(12)
640 << (init_en - fin_en) * 100.0 / init_en <<
" %." << endl;
645 char title[] =
"Final metric values";
646 vis_metric(mesh_poly_deg, *metric, *target_c, *mesh, title, 600);
654 sock <<
"solution\n";
658 sock <<
"window_title 'Displacements'\n"
659 <<
"window_geometry "
660 << 1200 <<
" " << 0 <<
" " << 600 <<
" " << 600 <<
"\n"
661 <<
"keys jRmclA" << endl;
681 const double r = sqrt(x(0)*x(0) + x(1)*x(1) + 1e-12);
682 const double den = 0.002;
683 double l2 = 0.2 + 0.5*std::tanh((r-0.16)/den) - 0.5*std::tanh((r-0.17)/den)
684 + 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 GetDim() const
Returns the reference space dimension for the finite element.
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.
Subclass constant coefficient.
int GetNBE() const
Returns number of boundary elements.
void InterpolateTMOP_QualityMetric(TMOP_QualityMetric &metric, const TargetConstructor &tc, const Mesh &mesh, GridFunction &metric_gf)
Interpolates the metric's values at the nodes of metric_gf.
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
Shape, ideal barrier metric, 3D.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Container class for integration rules.
Data type dense matrix using column-major storage.
Shape, ideal barrier metric, 3D.
int Size() const
Returns the size of the vector.
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.
void Randomize(int seed=0)
Set random values in the vector.
double weight_fun(const Vector &x)
Shape & area, ideal barrier metric, 2D.
void vis_metric(int order, TMOP_QualityMetric &qm, const TargetConstructor &tc, Mesh &mesh, char *title, int position)
Shifted barrier form of metric 2 (shape, ideal barrier metric), 2D.
void add(const Vector &v1, const Vector &v2, Vector &v)
Shape, ideal barrier metric, 2D.
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
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 SetPrintLevel(int print_lvl)
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.
Mesh * GetMesh() const
Returns the mesh.
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.
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.
int GetGeomType() const
Returns the Geometry::Type of the reference element.
double GetElementSize(int i, int type=0)
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.
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Area, ideal barrier metric, 2D.
Base class Coefficient that may optionally depend on time.
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)
void EnableLimiting(const GridFunction &n0, Coefficient &w0)
Adds a limiting term to the integrator.
Shape & area metric, 2D.
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
class for C-function coefficient
void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
Multiply the transpose of a matrix A with a matrix B: At*B.
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.
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.
Base class representing target-matrix construction algorithms for mesh optimization via the target-ma...
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
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.
Arbitrary order "L2-conforming" discontinuous finite elements.
A TMOP integrator class based on any given TMOP_QualityMetric and TargetConstructor.