130int main (
int argc,
char *argv[])
138 const char *mesh_file =
"icf.mesh";
139 int mesh_poly_deg = 1;
146 real_t adapt_lim_const = 0.0;
150 int solver_iter = 20;
151#ifdef MFEM_USE_SINGLE
152 real_t solver_rtol = 1e-4;
154 real_t solver_rtol = 1e-10;
156 int solver_art_type = 0;
158 int max_lin_iter = 100;
159 bool move_bnd =
true;
161 bool bal_expl_combo =
false;
162 bool hradaptivity =
false;
163 int h_metric_id = -1;
164 bool normalization =
false;
165 bool visualization =
true;
166 int verbosity_level = 0;
167 bool fdscheme =
false;
169 bool exactaction =
false;
170 bool integ_over_targ =
true;
171 const char *devopt =
"cpu";
175 int mesh_node_order = 0;
176 int barrier_type = 0;
177 int worst_case_type = 0;
178 bool detj_bound =
false;
182 args.
AddOption(&mesh_file,
"-m",
"--mesh",
183 "Mesh file to use.");
184 args.
AddOption(&mesh_poly_deg,
"-o",
"--order",
185 "Polynomial degree of mesh finite element space.");
186 args.
AddOption(&rs_levels,
"-rs",
"--refine-serial",
187 "Number of times to refine the mesh uniformly in serial.");
188 args.
AddOption(&rp_levels,
"-rp",
"--refine-parallel",
189 "Number of times to refine the mesh uniformly in parallel.");
190 args.
AddOption(&jitter,
"-ji",
"--jitter",
191 "Random perturbation scaling factor.");
192 args.
AddOption(&metric_id,
"-mid",
"--metric-id",
193 "Mesh optimization metric:\n\t"
195 "1 : |T|^2 -- 2D no type\n\t"
196 "2 : 0.5|T|^2/tau-1 -- 2D shape (condition number)\n\t"
197 "7 : |T-T^-t|^2 -- 2D shape+size\n\t"
198 "9 : tau*|T-T^-t|^2 -- 2D shape+size\n\t"
199 "14 : |T-I|^2 -- 2D shape+size+orientation\n\t"
200 "22 : 0.5(|T|^2-2*tau)/(tau-tau_0) -- 2D untangling\n\t"
201 "50 : 0.5|T^tT|^2/tau^2-1 -- 2D shape\n\t"
202 "55 : (tau-1)^2 -- 2D size\n\t"
203 "56 : 0.5(sqrt(tau)-1/sqrt(tau))^2 -- 2D size\n\t"
204 "58 : |T^tT|^2/(tau^2)-2*|T|^2/tau+2 -- 2D shape\n\t"
205 "77 : 0.5(tau-1/tau)^2 -- 2D size\n\t"
206 "80 : (1-gamma)mu_2 + gamma mu_77 -- 2D shape+size\n\t"
207 "85 : |T-|T|/sqrt(2)I|^2 -- 2D shape+orientation\n\t"
208 "90 : balanced combo mu_50 & mu_77 -- 2D shape+size\n\t"
209 "94 : balanced combo mu_2 & mu_56 -- 2D shape+size\n\t"
210 "98 : (1/tau)|T-I|^2 -- 2D shape+size+orientation\n\t"
213 "301: (|T||T^-1|)/3-1 -- 3D shape\n\t"
214 "302: (|T|^2|T^-1|^2)/9-1 -- 3D shape\n\t"
215 "303: (|T|^2)/3/tau^(2/3)-1 -- 3D shape\n\t"
216 "304: (|T|^3)/3^{3/2}/tau-1 -- 3D shape\n\t"
218 "313: (|T|^2)(tau-tau0)^(-2/3)/3 -- 3D untangling\n\t"
219 "315: (tau-1)^2 -- 3D no type\n\t"
220 "316: 0.5(sqrt(tau)-1/sqrt(tau))^2 -- 3D no type\n\t"
221 "321: |T-T^-t|^2 -- 3D shape+size\n\t"
222 "322: |T-adjT^-t|^2 -- 3D shape+size\n\t"
223 "323: |J|^3-3sqrt(3)ln(det(J))-3sqrt(3) -- 3D shape+size\n\t"
224 "328: balanced combo mu_301 & mu_316 -- 3D shape+size\n\t"
225 "332: (1-gamma) mu_302 + gamma mu_315 -- 3D shape+size\n\t"
226 "333: (1-gamma) mu_302 + gamma mu_316 -- 3D shape+size\n\t"
227 "334: (1-gamma) mu_303 + gamma mu_316 -- 3D shape+size\n\t"
228 "328: balanced combo mu_302 & mu_318 -- 3D shape+size\n\t"
229 "347: (1-gamma) mu_304 + gamma mu_316 -- 3D shape+size\n\t"
231 "360: (|T|^3)/3^{3/2}-tau -- 3D shape\n\t"
233 "11 : (1/4*alpha)|A-(adjA)^T(W^TW)/omega|^2 -- 2D shape\n\t"
234 "36 : (1/alpha)|A-W|^2 -- 2D shape+size+orientation\n\t"
235 "49 : (1-gamma) mu_2 + gamma nu_50 -- 2D shape+skew\n\t"
236 "51 : see fem/tmop.hpp -- 2D size+skew\n\t"
237 "107: (1/2*alpha)|A-|A|/|W|W|^2 -- 2D shape+orientation\n\t"
238 "126: (1-gamma)nu_11 + gamma*nu_14a -- 2D shape+size\n\t"
240 args.
AddOption(&target_id,
"-tid",
"--target-id",
241 "Target (ideal element) type:\n\t"
242 "1: Ideal shape, unit size\n\t"
243 "2: Ideal shape, equal size\n\t"
244 "3: Ideal shape, initial size\n\t"
245 "4: Given full analytic Jacobian (in physical space)\n\t"
246 "5: Ideal shape, given size (in physical space)");
247 args.
AddOption(&lim_const,
"-lc",
"--limit-const",
"Limiting constant.");
248 args.
AddOption(&adapt_lim_const,
"-alc",
"--adapt-limit-const",
249 "Adaptive limiting coefficient constant.");
250 args.
AddOption(&quad_type,
"-qt",
"--quad-type",
251 "Quadrature rule type:\n\t"
252 "1: Gauss-Lobatto\n\t"
253 "2: Gauss-Legendre\n\t"
254 "3: Closed uniform points");
255 args.
AddOption(&quad_order,
"-qo",
"--quad_order",
256 "Order of the quadrature rule.");
257 args.
AddOption(&solver_type,
"-st",
"--solver-type",
258 " Type of solver: (default) 0: Newton, 1: LBFGS");
259 args.
AddOption(&solver_iter,
"-ni",
"--newton-iters",
260 "Maximum number of Newton iterations.");
261 args.
AddOption(&solver_rtol,
"-rtol",
"--newton-rel-tolerance",
262 "Relative tolerance for the Newton solver.");
263 args.
AddOption(&solver_art_type,
"-art",
"--adaptive-rel-tol",
264 "Type of adaptive relative linear solver tolerance:\n\t"
265 "0: None (default)\n\t"
266 "1: Eisenstat-Walker type 1\n\t"
267 "2: Eisenstat-Walker type 2");
268 args.
AddOption(&lin_solver,
"-ls",
"--lin-solver",
273 "3: MINRES + Jacobi preconditioner\n\t"
274 "4: MINRES + l1-Jacobi preconditioner");
275 args.
AddOption(&max_lin_iter,
"-li",
"--lin-iter",
276 "Maximum number of iterations in the linear solve.");
277 args.
AddOption(&move_bnd,
"-bnd",
"--move-boundary",
"-fix-bnd",
279 "Enable motion along horizontal and vertical boundaries.");
280 args.
AddOption(&combomet,
"-cmb",
"--combo-type",
281 "Combination of metrics options:\n\t"
282 "0: Use single metric\n\t"
283 "1: Shape + space-dependent size given analytically\n\t"
284 "2: Shape + adapted size given discretely; shared target");
285 args.
AddOption(&bal_expl_combo,
"-bec",
"--balance-explicit-combo",
286 "-no-bec",
"--balance-explicit-combo",
287 "Automatic balancing of explicit combo metrics.");
288 args.
AddOption(&hradaptivity,
"-hr",
"--hr-adaptivity",
"-no-hr",
289 "--no-hr-adaptivity",
290 "Enable hr-adaptivity.");
291 args.
AddOption(&h_metric_id,
"-hmid",
"--h-metric",
292 "Same options as metric_id. Used to determine refinement"
293 " type for each element if h-adaptivity is enabled.");
294 args.
AddOption(&normalization,
"-nor",
"--normalization",
"-no-nor",
295 "--no-normalization",
296 "Make all terms in the optimization functional unitless.");
297 args.
AddOption(&fdscheme,
"-fd",
"--fd_approximation",
298 "-no-fd",
"--no-fd-approx",
299 "Enable finite difference based derivative computations.");
300 args.
AddOption(&exactaction,
"-ex",
"--exact_action",
301 "-no-ex",
"--no-exact-action",
302 "Enable exact action of TMOP_Integrator.");
303 args.
AddOption(&integ_over_targ,
"-it",
"--integrate-target",
304 "-ir",
"--integrate-reference",
305 "Integrate over target (-it) or reference (-ir) element.");
306 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
307 "--no-visualization",
308 "Enable or disable GLVis visualization.");
309 args.
AddOption(&verbosity_level,
"-vl",
"--verbosity-level",
310 "Verbosity level for the involved iterative solvers:\n\t"
312 "1: Newton iterations\n\t"
313 "2: Newton iterations + linear solver summaries\n\t"
314 "3: newton iterations + linear solver iterations");
315 args.
AddOption(&adapt_eval,
"-ae",
"--adaptivity-evaluator",
316 "0 - Advection based (DEFAULT), 1 - GSLIB.");
317 args.
AddOption(&devopt,
"-d",
"--device",
318 "Device configuration string, see Device::Configure().");
319 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
320 "--no-partial-assembly",
"Enable Partial Assembly.");
321 args.
AddOption(&n_hr_iter,
"-nhr",
"--n_hr_iter",
322 "Number of hr-adaptivity iterations.");
323 args.
AddOption(&n_h_iter,
"-nh",
"--n_h_iter",
324 "Number of h-adaptivity iterations per r-adaptivity"
326 args.
AddOption(&mesh_node_order,
"-mno",
"--mesh_node_ordering",
327 "Ordering of mesh nodes."
328 "0 (default): byNodes, 1: byVDIM");
329 args.
AddOption(&barrier_type,
"-btype",
"--barrier-type",
331 "1 - Shifted Barrier,"
332 "2 - Pseudo Barrier.");
333 args.
AddOption(&worst_case_type,
"-wctype",
"--worst-case-type",
337 args.
AddOption(&detj_bound,
"-db",
"--detj-bound",
338 "-no-db",
"--no-detj-bound",
339 "Enable or disable strict enforcement of positive Jacobian "
340 "determinants to guarantee mesh validity for tensor-product " "elements.");
348 if (h_metric_id < 0) { h_metric_id = metric_id; }
352 MFEM_VERIFY(strcmp(devopt,
"cpu")==0,
"HR-adaptivity is currently only"
353 " supported on cpus.");
356 if (myid == 0) { device.
Print();}
359 Mesh *mesh =
new Mesh(mesh_file, 1, 1,
false);
370 const bool periodic = (s && s->IsDGSpace()) ?
true :
false;
377 if (mesh_poly_deg <= 0) { mesh_poly_deg = 2; }
410 for (
int i = 0; i < pmesh->
GetNE(); i++)
416 for (
int j = 0; j < dofs.
Size(); j++)
418 h0(dofs[j]) = min(h0(dofs[j]), hi);
423 MPI_SUM, MPI_COMM_WORLD);
424 const real_t small_phys_size = pow(mesh_volume, 1.0 /
dim) / 100.0;
441 for (
int i = 0; i < pfes_h1.
GetNDofs(); i++)
443 for (
int d = 0; d <
dim; d++)
451 for (
int i = 0; i < pfes_h1.
GetNBE(); i++)
454 for (
int j = 0; j < vdofs.
Size(); j++) { rdm(vdofs[j]) = 0.0; }
483 ostringstream mesh_name;
484 mesh_name <<
"perturbed.mesh";
485 ofstream mesh_ofs(mesh_name.str().c_str());
486 mesh_ofs.precision(8);
546 if (myid == 0) { cout <<
"Unknown metric_id: " << metric_id << endl; }
565 default: cout <<
"Metric_id not supported for h-adaptivity: " << h_metric_id <<
572 switch (barrier_type)
574 case 0: btype = TMOP_WorstCaseUntangleOptimizer_Metric::BarrierType::None;
576 case 1: btype = TMOP_WorstCaseUntangleOptimizer_Metric::BarrierType::Shifted;
578 case 2: btype = TMOP_WorstCaseUntangleOptimizer_Metric::BarrierType::Pseudo;
580 default: cout <<
"barrier_type not supported: " << barrier_type << endl;
585 switch (worst_case_type)
587 case 0: wctype = TMOP_WorstCaseUntangleOptimizer_Metric::WorstCaseType::None;
589 case 1: wctype = TMOP_WorstCaseUntangleOptimizer_Metric::WorstCaseType::Beta;
591 case 2: wctype = TMOP_WorstCaseUntangleOptimizer_Metric::WorstCaseType::PMean;
593 default: cout <<
"worst_case_type not supported: " << worst_case_type << endl;
598 if (barrier_type > 0 || worst_case_type > 0)
600 if (barrier_type > 0)
602 MFEM_VERIFY(metric_id == 4 || metric_id == 14 || metric_id == 66,
603 "Metric not supported for shifted/pseudo barriers.");
614 if (metric_id < 300 || h_metric_id < 300)
616 MFEM_VERIFY(
dim == 2,
"Incompatible metric for 3D meshes");
618 if (metric_id >= 300 || h_metric_id >= 300)
620 MFEM_VERIFY(
dim == 3,
"Incompatible metric for 2D meshes");
627 int ind_fec_order = (target_id >= 5 && target_id <= 8 && !fdscheme) ?
636 pa ? AssemblyLevel::PARTIAL : AssemblyLevel::LEGACY;
665 MFEM_ABORT(
"MFEM is not built with GSLIB.");
681 disc.ProjectCoefficient(mat_coeff);
691 MFEM_ABORT(
"MFEM is not built with GSLIB.");
698 disc.GetDerivative(1,0,d_x);
699 disc.GetDerivative(1,1,d_y);
702 for (
int i = 0; i < size.Size(); i++)
704 size(i) = std::pow(d_x(i),2)+std::pow(d_y(i),2);
706 const real_t max = size.Max();
709 MPI_MAX, MPI_COMM_WORLD);
711 for (
int i = 0; i < d_x.Size(); i++)
713 d_x(i) = std::abs(d_x(i));
714 d_y(i) = std::abs(d_y(i));
717 const real_t aspr_ratio = 20.0;
718 const real_t size_ratio = 40.0;
720 for (
int i = 0; i < size.Size(); i++)
722 size(i) = (size(i)/max_all);
723 aspr(i) = (d_x(i)+eps)/(d_y(i)+eps);
724 aspr(i) = 0.1 + 0.9*(1-size(i))*(1-size(i));
725 if (aspr(i) > aspr_ratio) {aspr(i) = aspr_ratio;}
726 if (aspr(i) < 1.0/aspr_ratio) {aspr(i) = 1.0/aspr_ratio;}
729 const int NE = pmesh->
GetNE();
730 real_t volume = 0.0, volume_ind = 0.0;
732 for (
int i = 0; i < NE; i++)
737 size.GetValues(i, ir, vals);
746 real_t volume_all, volume_ind_all;
748 MPI_SUM, MPI_COMM_WORLD);
749 MPI_Allreduce(&volume_ind, &volume_ind_all, 1,
753 const real_t avg_zone_size = volume_all / NE_ALL;
755 const real_t small_avg_ratio =
756 (volume_ind_all + (volume_all - volume_ind_all) / size_ratio)
759 const real_t small_zone_size = small_avg_ratio * avg_zone_size;
760 const real_t big_zone_size = size_ratio * small_zone_size;
762 for (
int i = 0; i < size.Size(); i++)
764 const real_t val = size(i);
765 const real_t a = (big_zone_size - small_zone_size) / small_zone_size;
766 size(i) = big_zone_size / (1.0+
a*val);
791 MFEM_ABORT(
"MFEM is not built with GSLIB.");
813 MFEM_ABORT(
"MFEM is not built with GSLIB.");
818 size.ProjectCoefficient(size_coeff);
841 if (myid == 0) { cout <<
"Unknown target_id: " << target_id << endl; }
844 if (target_c == NULL)
853 auto tmop_integ =
new TMOP_Integrator(metric_to_use, target_c, h_metric);
854 tmop_integ->IntegrateOverTarget(integ_over_targ);
855 if (barrier_type > 0 || worst_case_type > 0)
857 tmop_integ->ComputeUntangleMetricQuantiles(x, *pfespace);
863 MFEM_VERIFY(pa ==
false,
"PA for finite differences is not implemented.");
864 tmop_integ->EnableFiniteDifferences(x);
866 tmop_integ->SetExactActionFlag(exactaction);
876 if (myid == 0) { cout <<
"Unknown quad_type: " << quad_type << endl; }
879 tmop_integ->SetIntegrationRules(*irules, quad_order);
880 if (myid == 0 &&
dim == 2)
882 cout <<
"Triangle quadrature points: "
884 <<
"\nQuadrilateral quadrature points: "
887 if (myid == 0 &&
dim == 3)
889 cout <<
"Tetrahedron quadrature points: "
891 <<
"\nHexahedron quadrature points: "
893 <<
"\nPrism quadrature points: "
899 if (metric_combo && bal_expl_combo)
903 metric_combo->ComputeBalancedWeights(x, *target_c, bal_weights, pa, &ir);
904 metric_combo->SetWeights(bal_weights);
913 if (normalization) { dist = small_phys_size; }
915 if (lim_const != 0.0) { tmop_integ->EnableLimiting(x0, dist, lim_coeff); }
921 const real_t adapt_lim_const_2 = 0.5 * adapt_lim_const;
924 if (adapt_lim_const > 0.0)
931 if (adapt_eval == 0) { adapt_lim_eval =
new AdvectorCG(al); }
932 else if (adapt_eval == 1)
937 MFEM_ABORT(
"MFEM is not built with GSLIB support!");
940 else { MFEM_ABORT(
"Bad interpolation option."); }
945 z0[0] = &adapt_lim_gf0_1;
946 z0[1] = &adapt_lim_gf0_2;
947 coeff[0] = &adapt_lim_coeff_1;
948 coeff[1] = &adapt_lim_coeff_2;
951 tmop_integ->EnableAdaptiveLimiting(z0, coeff, *adapt_lim_eval, delta_max);
956 "Zeta0(1) - initial mesh", 300, 600, 300, 300);
958 "Zeta0(2) - initial mesh", 300, 900, 300, 300);
969 if (pa) {
a.SetAssemblyLevel(AssemblyLevel::PARTIAL); }
983 tmop_integ->SetCoefficient(*metric_coeff1);
998 else { tmop_integ2 =
new TMOP_Integrator(metric2, target_c, h_metric); }
1007 if (lim_const != 0.0) { combo->
EnableLimiting(x0, dist, lim_coeff); }
1009 a.AddDomainIntegrator(combo);
1011 else {
a.AddDomainIntegrator(tmop_integ); }
1013 if (pa) {
a.Setup(); }
1019 tmop_integ->ParEnableNormalization(x0);
1025 const int NE = pmesh->
GetNE();
1026 for (
int i = 0; i < NE; i++)
1029 irules->
Get(pfespace->GetFE(i)->GetGeomType(), quad_order);
1034 min_detJ = min(min_detJ, transf->
Jacobian().
Det());
1039 MPI_MIN, MPI_COMM_WORLD);
1042 { cout <<
"Minimum det(J) of the original mesh is " << min_detJ << endl; }
1044 if (min_detJ < 0.0 && barrier_type == 0
1045 && metric_id != 22 && metric_id != 211 && metric_id != 252
1046 && metric_id != 311 && metric_id != 313 && metric_id != 352)
1048 MFEM_ABORT(
"The input mesh is inverted! Try an untangling metric.");
1053 "Untangling is supported only for ideal targets.");
1057 min_detJ /= Wideal.
Det();
1061 MPI_MIN, MPI_COMM_WORLD);
1063 min_detJ -= 0.01 * h0_min;
1067 if (periodic) { tmop_integ->SetInitialMeshPos(&x0); }
1068 const real_t init_energy =
a.GetParGridFunctionEnergy(periodic ? dx : x) /
1070 real_t init_metric_energy = init_energy;
1071 if (lim_const > 0.0 || adapt_lim_const > 0.0)
1076 init_metric_energy =
a.GetParGridFunctionEnergy(periodic ? dx : x) /
1079 adapt_lim_coeff_1.
constant = adapt_lim_const;
1080 adapt_lim_coeff_2.
constant = adapt_lim_const_2;
1087 char title[] =
"Initial metric values";
1096 if (move_bnd ==
false)
1100 a.SetEssentialBC(ess_bdr);
1105 for (
int i = 0; i < pmesh->
GetNBE(); i++)
1109 MFEM_VERIFY(!(
dim == 2 && attr == 3),
1110 "Boundary attribute 3 must be used only for 3D meshes. "
1111 "Adjust the attributes (1/2/3/4 for fixed x/y/z/all "
1112 "components, rest for free nodes), or use -fix-bnd.");
1113 if (attr == 1 || attr == 2 || attr == 3) { n += nd; }
1114 if (attr == 4) { n += nd *
dim; }
1118 for (
int i = 0; i < pmesh->
GetNBE(); i++)
1125 for (
int j = 0; j < nd; j++)
1126 { ess_vdofs[n++] = vdofs[j]; }
1130 for (
int j = 0; j < nd; j++)
1131 { ess_vdofs[n++] = vdofs[j+nd]; }
1135 for (
int j = 0; j < nd; j++)
1136 { ess_vdofs[n++] = vdofs[j+2*nd]; }
1140 for (
int j = 0; j < vdofs.
Size(); j++)
1141 { ess_vdofs[n++] = vdofs[j]; }
1144 a.SetEssentialVDofs(ess_vdofs);
1149 Solver *S = NULL, *S_prec = NULL;
1150#ifdef MFEM_USE_SINGLE
1151 const real_t linsol_rtol = 1e-5;
1153 const real_t linsol_rtol = 1e-12;
1157 if (verbosity_level == 2)
1159 if (verbosity_level > 2)
1161 if (lin_solver == 0)
1163 S =
new DSmoother(1, 1.0, max_lin_iter);
1165 else if (lin_solver == 1)
1168 cg->SetMaxIter(max_lin_iter);
1169 cg->SetRelTol(linsol_rtol);
1171 cg->SetPrintLevel(linsolver_print);
1181 if (lin_solver == 3 || lin_solver == 4)
1185 MFEM_VERIFY(lin_solver != 4,
"PA l1-Jacobi is not implemented");
1195 hs->SetPositiveDiagonal(
true);
1218 if (solver_art_type > 0)
1224 const int bound_refs = 4;
1225 const int bound_recs = 4;
1241 x, move_bnd, hradaptivity,
1242 mesh_poly_deg, h_metric_id,
1243 n_hr_iter, n_h_iter);
1246 if (adapt_lim_const > 0.)
1257 ostringstream mesh_name;
1258 mesh_name <<
"optimized.mesh";
1259 ofstream mesh_ofs(mesh_name.str().c_str());
1260 mesh_ofs.precision(8);
1271 if (periodic) { tmop_integ->SetInitialMeshPos(&x0); }
1272 const real_t fin_energy =
a.GetParGridFunctionEnergy(periodic ? dx : x) /
1274 real_t fin_metric_energy = fin_energy;
1275 if (lim_const > 0.0 || adapt_lim_const > 0.0)
1280 fin_metric_energy =
a.GetParGridFunctionEnergy(periodic ? dx : x) /
1283 adapt_lim_coeff_1.
constant = adapt_lim_const;
1284 adapt_lim_coeff_2.
constant = adapt_lim_const_2;
1288 std::cout << std::scientific << std::setprecision(4);
1289 cout <<
"Initial strain energy: " << init_energy
1290 <<
" = metrics: " << init_metric_energy
1291 <<
" + extra terms: " << init_energy - init_metric_energy << endl;
1292 cout <<
" Final strain energy: " << fin_energy
1293 <<
" = metrics: " << fin_metric_energy
1294 <<
" + extra terms: " << fin_energy - fin_metric_energy << endl;
1295 cout <<
"The strain energy decreased by: "
1296 << (init_energy - fin_energy) * 100.0 / init_energy <<
" %." << endl;
1302 char title[] =
"Final metric values";
1306 if (adapt_lim_const > 0.0 && visualization)
1310 "Zeta0(1) - final mesh", 600, 600, 300, 300);
1312 "Zeta0(2) - final mesh", 600, 900, 300, 300);
1322 sock.
open(
"localhost", 19916);
1323 sock <<
"solution\n";
1329 sock <<
"window_title 'Displacements'\n"
1330 <<
"window_geometry "
1331 << 1200 <<
" " << 0 <<
" " << 600 <<
" " << 600 <<
"\n"
1332 <<
"keys jRmclA" << endl;
1340 delete metric_coeff1;
1341 delete adapt_lim_eval;
1343 delete hr_adapt_coeff;
1347 delete untangler_metric;
virtual void SetAnalyticTargetSpec(Coefficient *sspec, VectorCoefficient *vspec, TMOPMatrixCoefficient *mspec)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
int Size() const
Return the logical size of the array.
@ GaussLobatto
Closed type.
Conjugate gradient method.
A coefficient that is constant across space and time.
Jacobi-type diagonal smoother of a sparse matrix.
Data type dense matrix using column-major storage.
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
void Print(std::ostream &os=mfem::out)
Print the configuration of the MFEM virtual device object.
virtual void SetParDiscreteTargetAspectRatio(const ParGridFunction &tspec_)
void SetMinSizeForTargets(real_t min_size_)
virtual void SetParDiscreteTargetSize(const ParGridFunction &tspec_)
void SetAdaptivityEvaluator(AdaptivityEvaluator *ae)
virtual void SetParDiscreteTargetOrientation(const ParGridFunction &tspec_)
int GetAttribute() const
Return element's attribute.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th boundary fac...
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
int GetNBE() const
Returns number of boundary elements in the mesh.
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...
int DofToVDof(int dof, int vd, int ndofs=-1) const
Compute a single vdof corresponding to the index dof and the vector index vd.
int GetDof() const
Returns the number of degrees of freedom in the finite element.
A general function coefficient.
const DenseMatrix & GetGeomToPerfGeomJac(int GeomType) const
void SetFromTrueVector()
Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
void ProjectGridFunction(const GridFunction &src)
Project the src GridFunction to this GridFunction, both of which must be on the same mesh.
Arbitrary order H1-conforming (continuous) finite elements.
Parallel smoothers in hypre.
void SetType(HypreSmoother::Type type, int relax_times=1)
Set the relaxation type and number of sweeps.
@ l1Jacobi
l1-scaled Jacobi
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Class for integration point with weight.
Class for an integration rule - an Array of IntegrationPoint.
int GetNPoints() const
Returns the number of the points in the integration rule.
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Container class for integration rules.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void SetRelTol(real_t rtol)
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void SetMaxIter(int max_it)
void SetAbsTol(real_t atol)
Arbitrary order "L2-conforming" discontinuous finite elements.
void SetPreconditioner(Solver &pr) override
This should be called before SetOperator.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
const FiniteElementSpace * GetNodalFESpace() const
Geometry::Type GetTypicalElementGeometry() const
If the local mesh is not empty, return GetElementGeometry(0); otherwise, return a typical Geometry pr...
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
real_t GetElementSize(int i, int type=0)
Get the size of the i-th element relative to the perfect reference element.
void GetElementTransformation(int i, IsoparametricTransformation *ElTr) const
Builds the transformation defining the i-th element in ElTr. ElTr must be allocated in advance and wi...
void SetNodalGridFunction(GridFunction *nodes, bool make_owner=false)
real_t GetElementVolume(int i)
int GetNBE() const
Returns number of boundary elements.
long long GetGlobalNE() const
Return the total (global) number of elements.
void EnsureNCMesh(bool simplices_nonconforming=false)
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Geometry::Type GetElementBaseGeometry(int i) const
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 SetAdaptiveLinRtol(const int type=2, const real_t rtol0=0.5, const real_t rtol_max=0.9, const real_t alpha=0.5 *(1.0+sqrt(5.0)), const real_t gamma=1.0)
Enable adaptive linear solver relative tolerance algorithm.
Jacobi smoothing for a given bilinear form (no matrix necessary).
void SetPositiveDiagonal(bool pos_diag=true)
Replace diagonal entries with their absolute values.
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...
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
void GetElementDofs(int i, Array< int > &dofs, DofTransformation &doftrans) const override
The same as GetElementDofs(), but with a user-provided DofTransformation object.
Class for parallel grid function.
void ProjectCoefficient(Coefficient &coeff, ProjectType type=ProjectType::DEFAULT) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
void SaveAsOne(const char *fname, int precision=16) const
Class for parallel meshes.
void SetNodalFESpace(FiniteElementSpace *nfes) override
void PrintAsOne(std::ostream &out=mfem::out, const std::string &comments="") const
Write the mesh to the stream 'out' on Process 0 in a form suitable for visualization.
void ParEnableNormalization(const ParGridFunction &x)
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.
void AddTMOPIntegrator(TMOP_Integrator *ti)
Adds a new TMOP_Integrator to the combination.
void AddGridFunctionForUpdate(GridFunction *gf)
void AddFESpaceForUpdate(FiniteElementSpace *fes)
void SetPreconditioner(Solver &pr) override
This should be called before SetOperator.
void EnsurePositiveDeterminantBound(Mesh &mesh, int ref_factor, int max_recursion_depth=0)
Ensure a positive lower bound for the Jacobian determinant in tensor-product elements during line-sea...
void SetIntegrationRules(IntegrationRules &irules, int order)
Prescribe a set of integration rules; relevant for mixed meshes.
void SetMinDetPtr(real_t *md_ptr)
2D barrier Shape+Size+Orientation (VOS) metric (polyconvex).
2D barrier Size+Skew (VQ) metric.
2D barrier Shape+Orientation (OS) metric (polyconvex).
2D barrier Shape+Size (VS) metric (polyconvex).
A TMOP integrator class based on any given TMOP_QualityMetric and TargetConstructor.
void SetExactActionFlag(bool flag_)
Flag to control if exact action of Integration is effected.
void SetCoefficient(Coefficient &w1)
Sets a scaling Coefficient for the quality metric term of the integrator.
void EnableFiniteDifferences(const GridFunction &x)
Enables FD-based approximation and computes dx.
void SetIntegrationRules(IntegrationRules &irules, int order)
Prescribe a set of integration rules; relevant for mixed meshes.
void IntegrateOverTarget(bool integ_over_target_)
2D non-barrier metric without a type.
2D barrier Shape+Size (VS) metric (not polyconvex).
2D barrier Shape+Size (VS) metric (not polyconvex).
2D non-barrier Shape+Size+Orientation (VOS) metric (polyconvex).
2D Shifted barrier form of shape metric (mu_2).
2D barrier shape (S) metric (not polyconvex).
2D barrier Shape+Orientation (OS) metric (polyconvex).
2D compound barrier Shape+Size (VS) metric (balanced).
2D compound barrier Shape+Size (VS) metric (balanced).
2D barrier Shape+Size+Orientation (VOS) metric (polyconvex).
3D barrier Shape (S) metric, well-posed (polyconvex & invex).
3D barrier Shape (S) metric, well-posed (polyconvex & invex).
3D barrier Shape (S) metric, well-posed (polyconvex & invex).
3D barrier Shape (S) metric, well-posed (polyconvex & invex).
3D Shape (S) metric, untangling version of 303.
3D barrier Shape+Size (VS) metric, well-posed (invex).
3D barrier Shape+Size (VS) metric, well-posed (invex).
3D barrier Shape+Size (VS) metric, well-posed (invex).
3D compound barrier Shape+Size (VS) metric (polyconvex, balanced).
3D compound barrier Shape+Size (VS) metric (polyconvex).
3D barrier Shape+Size (VS) metric, well-posed (polyconvex).
3D barrier Shape+Size (VS) metric, well-posed (polyconvex).
3D compound barrier Shape+Size (VS) metric (polyconvex, balanced).
3D barrier Shape+Size (VS) metric, well-posed (polyconvex).
3D non-barrier Shape (S) metric.
Abstract class for local mesh quality metrics in the target-matrix optimization paradigm (TMOP) by P....
Base class representing target-matrix construction algorithms for mesh optimization via the target-ma...
void SetVolumeScale(real_t vol_scale)
Used by target type IDEAL_SHAPE_EQUAL_SIZE. The default volume scale is 1.
void SetNodes(const GridFunction &n)
Set the nodes to be used in the target-matrix construction.
TargetType
Target-matrix construction algorithms supported by this class.
A general vector function coefficient.
void Randomize(int seed=0)
Set random values in the vector.
virtual real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
real_t Min() const
Returns the minimal element of the vector.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
real_t adapt_lim_fun(const Vector &x)
IntegrationRules IntRulesCU(0, Quadrature1D::ClosedUniform)
real_t weight_fun(const Vector &x)
real_t adapt_lim_fun2(const Vector &x)
real_t material_indicator_2d(const Vector &x)
IntegrationRules IntRulesLo(0, Quadrature1D::GaussLobatto)
void ConstructSizeGF(GridFunction &size)
real_t discrete_ori_2d(const Vector &x)
void discrete_aspr_3d(const Vector &x, Vector &v)
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 DiffuseField(ParGridFunction &field, int smooth_steps)
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)
AssemblyLevel
Enumeration defining the assembly level for bilinear and nonlinear form classes derived from Operator...
void vis_tmop_metric_p(int order, TMOP_QualityMetric &qm, const TargetConstructor &tc, ParMesh &pmesh, char *title, int position)
constexpr real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Settings for the output behavior of the IterativeSolver.
PrintLevel & Iterations()
PrintLevel & FirstAndLast()
Helper struct to convert a C++ type to an MPI type.