88 #include "../common/mfem-common.hpp"
96 int main(
int argc,
char *argv[])
99 const char *mesh_file =
"icf.mesh";
100 int mesh_poly_deg = 1;
105 double lim_const = 0.0;
106 double adapt_lim_const = 0.0;
110 int solver_iter = 10;
111 double solver_rtol = 1e-10;
113 int max_lin_iter = 100;
114 bool move_bnd =
true;
116 bool normalization =
false;
117 bool visualization =
true;
118 int verbosity_level = 0;
119 bool fdscheme =
false;
121 bool exactaction =
false;
125 args.
AddOption(&mesh_file,
"-m",
"--mesh",
126 "Mesh file to use.");
127 args.
AddOption(&mesh_poly_deg,
"-o",
"--order",
128 "Polynomial degree of mesh finite element space.");
129 args.
AddOption(&rs_levels,
"-rs",
"--refine-serial",
130 "Number of times to refine the mesh uniformly in serial.");
131 args.
AddOption(&jitter,
"-ji",
"--jitter",
132 "Random perturbation scaling factor.");
133 args.
AddOption(&metric_id,
"-mid",
"--metric-id",
134 "Mesh optimization metric:\n\t"
135 "1 : |T|^2 -- 2D shape\n\t"
136 "2 : 0.5|T|^2/tau-1 -- 2D shape (condition number)\n\t"
137 "7 : |T-T^-t|^2 -- 2D shape+size\n\t"
138 "9 : tau*|T-T^-t|^2 -- 2D shape+size\n\t"
139 "14: 0.5*(1-cos(theta_A - theta_W) -- 2D Sh+Sz+Alignment\n\t"
140 "22 : 0.5(|T|^2-2*tau)/(tau-tau_0) -- 2D untangling\n\t"
141 "50 : 0.5|T^tT|^2/tau^2-1 -- 2D shape\n\t"
142 "55 : (tau-1)^2 -- 2D size\n\t"
143 "56 : 0.5(sqrt(tau)-1/sqrt(tau))^2 -- 2D size\n\t"
144 "58 : |T^tT|^2/(tau^2)-2*|T|^2/tau+2 -- 2D shape\n\t"
145 "77 : 0.5(tau-1/tau)^2 -- 2D size\n\t"
146 "211: (tau-1)^2-tau+sqrt(tau^2) -- 2D untangling\n\t"
147 "252: 0.5(tau-1)^2/(tau-tau_0) -- 2D untangling\n\t"
148 "301: (|T||T^-1|)/3-1 -- 3D shape\n\t"
149 "302: (|T|^2|T^-1|^2)/9-1 -- 3D shape\n\t"
150 "303: (|T|^2)/3*tau^(2/3)-1 -- 3D shape\n\t"
151 "315: (tau-1)^2 -- 3D size\n\t"
152 "316: 0.5(sqrt(tau)-1/sqrt(tau))^2 -- 3D size\n\t"
153 "321: |T-T^-t|^2 -- 3D shape+size\n\t"
154 "352: 0.5(tau-1)^2/(tau-tau_0) -- 3D untangling");
155 args.
AddOption(&target_id,
"-tid",
"--target-id",
156 "Target (ideal element) type:\n\t"
157 "1: Ideal shape, unit size\n\t"
158 "2: Ideal shape, equal size\n\t"
159 "3: Ideal shape, initial size\n\t"
160 "4: Given full analytic Jacobian (in physical space)\n\t"
161 "5: Ideal shape, given size (in physical space)");
162 args.
AddOption(&lim_const,
"-lc",
"--limit-const",
"Limiting constant.");
163 args.
AddOption(&adapt_lim_const,
"-alc",
"--adapt-limit-const",
164 "Adaptive limiting coefficient constant.");
165 args.
AddOption(&quad_type,
"-qt",
"--quad-type",
166 "Quadrature rule type:\n\t"
167 "1: Gauss-Lobatto\n\t"
168 "2: Gauss-Legendre\n\t"
169 "3: Closed uniform points");
170 args.
AddOption(&quad_order,
"-qo",
"--quad_order",
171 "Order of the quadrature rule.");
172 args.
AddOption(&solver_type,
"-st",
"--solver-type",
173 " Type of solver: (default) 0: Newton, 1: LBFGS");
174 args.
AddOption(&solver_iter,
"-ni",
"--newton-iters",
175 "Maximum number of Newton iterations.");
176 args.
AddOption(&solver_rtol,
"-rtol",
"--newton-rel-tolerance",
177 "Relative tolerance for the Newton solver.");
178 args.
AddOption(&lin_solver,
"-ls",
"--lin-solver",
179 "Linear solver: 0 - l1-Jacobi, 1 - CG, 2 - MINRES.");
180 args.
AddOption(&max_lin_iter,
"-li",
"--lin-iter",
181 "Maximum number of iterations in the linear solve.");
182 args.
AddOption(&move_bnd,
"-bnd",
"--move-boundary",
"-fix-bnd",
184 "Enable motion along horizontal and vertical boundaries.");
185 args.
AddOption(&combomet,
"-cmb",
"--combo-type",
186 "Combination of metrics options:"
187 "0: Use single metric\n\t"
188 "1: Shape + space-dependent size given analytically\n\t"
189 "2: Shape + adapted size given discretely; shared target");
190 args.
AddOption(&normalization,
"-nor",
"--normalization",
"-no-nor",
191 "--no-normalization",
192 "Make all terms in the optimization functional unitless.");
193 args.
AddOption(&fdscheme,
"-fd",
"--fd_approximation",
194 "-no-fd",
"--no-fd-approx",
195 "Enable finite difference based derivative computations.");
196 args.
AddOption(&exactaction,
"-ex",
"--exact_action",
197 "-no-ex",
"--no-exact-action",
198 "Enable exact action of TMOP_Integrator.");
199 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
200 "--no-visualization",
201 "Enable or disable GLVis visualization.");
202 args.
AddOption(&verbosity_level,
"-vl",
"--verbosity-level",
203 "Set the verbosity level - 0, 1, or 2.");
204 args.
AddOption(&adapt_eval,
"-ae",
"--adaptivity-evaluator",
205 "0 - Advection based (DEFAULT), 1 - GSLIB.");
215 Mesh *mesh =
new Mesh(mesh_file, 1, 1,
false);
218 cout <<
"Mesh curvature: ";
220 else { cout <<
"(NONE)"; }
228 if (mesh_poly_deg <= 0)
259 for (
int i = 0; i < mesh->
GetNE(); i++)
265 for (
int j = 0; j < dofs.
Size(); j++)
267 h0(dofs[j]) = min(h0(dofs[j]), hi);
271 const double small_phys_size = pow(volume, 1.0 / dim) / 100.0;
283 for (
int i = 0; i < fespace->
GetNDofs(); i++)
285 for (
int d = 0; d <
dim; d++)
291 for (
int i = 0; i < fespace->
GetNBE(); i++)
296 for (
int j = 0; j < vdofs.
Size(); j++) { rdm(vdofs[j]) = 0.0; }
305 ofstream mesh_ofs(
"perturbed.mesh");
306 mesh->
Print(mesh_ofs);
314 double tauval = -0.1;
339 default: cout <<
"Unknown metric_id: " << metric_id << endl;
return 3;
373 #ifdef MFEM_USE_GSLIB
376 MFEM_ABORT(
"MFEM is not built with GSLIB.");
380 size.ProjectCoefficient(ind_coeff);
392 disc.ProjectCoefficient(ind_coeff);
399 #ifdef MFEM_USE_GSLIB
402 MFEM_ABORT(
"MFEM is not built with GSLIB.");
410 disc.GetDerivative(1,0,d_x);
411 disc.GetDerivative(1,1,d_y);
414 for (
int i = 0; i < size.Size(); i++)
416 size(i) = std::pow(d_x(i),2)+std::pow(d_y(i),2);
418 const double max = size.Max();
420 for (
int i = 0; i < d_x.Size(); i++)
422 d_x(i) = std::abs(d_x(i));
423 d_y(i) = std::abs(d_y(i));
425 const double eps = 0.01;
426 const double aspr_ratio = 20.0;
427 const double size_ratio = 40.0;
429 for (
int i = 0; i < size.Size(); i++)
431 size(i) = (size(i)/max);
432 aspr(i) = (d_x(i)+eps)/(d_y(i)+eps);
433 aspr(i) = 0.1 + 0.9*(1-size(i))*(1-size(i));
434 if (aspr(i) > aspr_ratio) {aspr(i) = aspr_ratio;}
435 if (aspr(i) < 1.0/aspr_ratio) {aspr(i) = 1.0/aspr_ratio;}
438 const int NE = mesh->
GetNE();
439 double volume = 0.0, volume_ind = 0.0;
441 for (
int i = 0; i < NE; i++)
446 size.GetValues(i, ir, vals);
456 const double avg_zone_size = volume / NE;
458 const double small_avg_ratio = (volume_ind + (volume - volume_ind) /
462 const double small_zone_size = small_avg_ratio * avg_zone_size;
463 const double big_zone_size = size_ratio * small_zone_size;
465 for (
int i = 0; i < size.Size(); i++)
467 const double val = size(i);
468 const double a = (big_zone_size - small_zone_size) / small_zone_size;
469 size(i) = big_zone_size / (1.0+a*val);
490 #ifdef MFEM_USE_GSLIB
493 MFEM_ABORT(
"MFEM is not built with GSLIB.");
497 aspr3d.ProjectCoefficient(fd_aspr3d);
513 #ifdef MFEM_USE_GSLIB
516 MFEM_ABORT(
"MFEM is not built with GSLIB.");
523 size.ProjectCoefficient(ind_coeff);
530 aspr.ProjectCoefficient(aspr_coeff);
541 default: cout <<
"Unknown target_id: " << target_id << endl;
return 3;
543 if (target_c == NULL)
559 default: cout <<
"Unknown quad_type: " << quad_type << endl;
return 3;
564 cout <<
"Triangle quadrature points: "
566 <<
"\nQuadrilateral quadrature points: "
571 cout <<
"Tetrahedron quadrature points: "
573 <<
"\nHexahedron quadrature points: "
575 <<
"\nPrism quadrature points: "
586 if (normalization) { dist = small_phys_size; }
588 if (lim_const != 0.0) { he_nlf_integ->
EnableLimiting(x0, dist, lim_coeff); }
594 if (adapt_lim_const > 0.0)
599 if (adapt_eval == 0) { adapt_evaluator =
new AdvectorCG; }
600 else if (adapt_eval == 1)
602 #ifdef MFEM_USE_GSLIB
605 MFEM_ABORT(
"MFEM is not built with GSLIB support!");
608 else { MFEM_ABORT(
"Bad interpolation option."); }
659 if (lim_const != 0.0) { combo->
EnableLimiting(x0, dist, lim_coeff); }
671 char title[] =
"Initial metric values";
680 if (move_bnd ==
false)
689 for (
int i = 0; i < mesh->
GetNBE(); i++)
693 MFEM_VERIFY(!(dim == 2 && attr == 3),
694 "Boundary attribute 3 must be used only for 3D meshes. "
695 "Adjust the attributes (1/2/3/4 for fixed x/y/z/all "
696 "components, rest for free nodes), or use -fix-bnd.");
697 if (attr == 1 || attr == 2 || attr == 3) { n += nd; }
698 if (attr == 4) { n += nd *
dim; }
702 for (
int i = 0; i < mesh->
GetNBE(); i++)
709 for (
int j = 0; j < nd; j++)
710 { ess_vdofs[n++] = vdofs[j]; }
714 for (
int j = 0; j < nd; j++)
715 { ess_vdofs[n++] = vdofs[j+nd]; }
719 for (
int j = 0; j < nd; j++)
720 { ess_vdofs[n++] = vdofs[j+2*nd]; }
724 for (
int j = 0; j < vdofs.
Size(); j++)
725 { ess_vdofs[n++] = vdofs[j]; }
734 const double linsol_rtol = 1e-12;
739 else if (lin_solver == 1)
760 const int NE = mesh->
GetNE();
761 for (
int i = 0; i < NE; i++)
772 cout <<
"Minimum det(J) of the original mesh is " << tauval << endl;
773 tauval -= 0.01 * h0.Min();
781 if (solver_type == 0)
795 cout <<
"Nonlinear solver: rtol = " << solver_rtol <<
" not achieved.\n";
801 ofstream mesh_ofs(
"optimized.mesh");
802 mesh_ofs.precision(14);
803 mesh->
Print(mesh_ofs);
808 double metric_part = fin_energy;
809 if (lim_const > 0.0 || adapt_lim_const > 0.0)
815 coef_zeta.
constant = adapt_lim_const;
817 cout <<
"Initial strain energy: " << init_energy
818 <<
" = metrics: " << init_energy
819 <<
" + limiting term: " << 0.0 << endl;
820 cout <<
" Final strain energy: " << fin_energy
821 <<
" = metrics: " << metric_part
822 <<
" + limiting term: " << fin_energy - metric_part << endl;
823 cout <<
"The strain energy decreased by: " << setprecision(12)
824 << (init_energy - fin_energy) * 100.0 / init_energy <<
" %." << endl;
829 char title[] =
"Final metric values";
833 if (adapt_lim_const > 0.0 && visualization)
845 sock <<
"solution\n";
849 sock <<
"window_title 'Displacements'\n"
850 <<
"window_geometry "
851 << 1200 <<
" " << 0 <<
" " << 600 <<
" " << 600 <<
"\n"
852 <<
"keys jRmclA" << endl;
860 delete adapt_evaluator;
int GetNPoints() const
Returns the number of the points in the integration rule.
void discrete_aspr_3d(const Vector &x, Vector &v)
int Size() const
Return the 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.
void EnableFiniteDifferences(const GridFunction &x)
Enables FD-based approximation and computes dx.
Class for grid function - Vector with associated FE space.
int DofToVDof(int dof, int vd, int ndofs=-1) const
double discrete_size_2d(const Vector &x)
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.
IntegrationRules IntRulesLo(0, Quadrature1D::GaussLobatto)
void SetIntegrationRules(IntegrationRules &irules, int order)
Prescribe a set of integration rules; relevant for mixed meshes.
void SetFromTrueVector()
Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
A coefficient that is constant across space and time.
virtual void SetSerialDiscreteTargetOrientation(const GridFunction &tspec_)
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.
void SetAdaptivityEvaluator(AdaptivityEvaluator *ae)
void DiffuseField(GridFunction &field, int smooth_steps)
Container class for integration rules.
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.
void EnableAdaptiveLimiting(const GridFunction &z0, Coefficient &coeff, AdaptivityEvaluator &ae)
Restriction of the node positions to certain regions.
Area, ideal barrier metric, 2D.
void SetIntegrationRules(IntegrationRules &irules, int order)
Prescribe a set of integration rules; relevant for mixed meshes.
int GetNE() const
Returns number of elements.
void EnableNormalization(const GridFunction &x)
Normalization factor that considers all integrators in the combination.
void vis_tmop_metric_s(int order, TMOP_QualityMetric &qm, const TargetConstructor &tc, Mesh &mesh, char *title, int position)
void SetExactActionFlag(bool flag_)
Flag to control if exact action of Integration is effected.
void Randomize(int seed=0)
Set random values in the vector.
int main(int argc, char *argv[])
Shape & area, ideal barrier metric, 2D.
Geometry::Type GetElementBaseGeometry(int i) const
void EnableLimiting(const GridFunction &n0, const GridFunction &dist, Coefficient &w0, TMOP_LimiterFunction *lfunc=NULL)
Adds the limiting term to the first integrator. Disables it for the rest.
Shifted barrier form of metric 2 (shape, ideal barrier metric), 2D.
virtual void SetSerialDiscreteTargetAspectRatio(const GridFunction &tspec_)
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)
Limiting of the mesh displacements (general version).
int GetNBE() const
Returns number of boundary elements in the mesh.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
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 *)
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.
Version of QuadraticFECollection with positive basis functions.
int GetAttribute() const
Return element's attribute.
double discrete_ori_2d(const Vector &x)
void SetNodalFESpace(FiniteElementSpace *nfes)
void PrintUsage(std::ostream &out) const
Print the usage message.
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
A general vector function coefficient.
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.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
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.
double weight_fun(const Vector &x)
Area, ideal barrier metric, 2D.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
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...
double adapt_lim_fun(const Vector &x)
void AddTMOPIntegrator(TMOP_Integrator *ti)
Adds a new TMOP_Integrator to the combination.
double material_indicator_2d(const Vector &x)
Shape & area metric, 2D.
double discrete_aspr_2d(const Vector &x)
Class for integration point with weight.
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
IntegrationRules IntRulesCU(0, Quadrature1D::ClosedUniform)
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
void PrintOptions(std::ostream &out) const
Print the options.
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
virtual void ProjectCoefficient(Coefficient &coeff)
A general function coefficient.
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
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)
void GetNodes(Vector &node_coord) const
Shape+Size+Orientation metric, 2D.
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 in the FiniteElementCollection associated with i'th boundary fac...
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...
virtual void SetAnalyticTargetSpec(Coefficient *sspec, VectorCoefficient *vspec, TMOPMatrixCoefficient *mspec)
virtual void SetSerialDiscreteTargetSize(const GridFunction &tspec_)
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Shape & orientation metric, 2D.
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.
bool Good() const
Return true if the command line options were parsed successfully.
A TMOP integrator class based on any given TMOP_QualityMetric and TargetConstructor.