libMesh
adjoints_ex3.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 // <h1>Adjoints Example 3 - Stokes flow and Convection-Diffusion</h1>
20 // \author Vikram Garg
21 // \date 2012
22 //
23 // We solve a coupled Stokes + Convection Diffusion system in an H channel geometry
24 // with 2 inlets and 2 outlets. The QoI is the species
25 // flux from left outlet
26 
27 // Channel Geometry:
28 // Wall
29 // ----------------------------------------------------------------
30 // 0 1
31 // ---------------------------- -------------------------------
32 // | |
33 // Wall | | Wall
34 // | |
35 // ----------------------------- -------------------------------
36 // 2 2
37 // -----------------------------------------------------------------
38 // Wall
39 
40 // The equations governing this flow are:
41 // Stokes: -VectorLaplacian(velocity) + grad(pressure) = vector(0)
42 // Convection-Diffusion: - dot(velocity, grad(concentration) ) + Laplacian(concentration) = 0
43 
44 // The boundary conditions are:
45 // u_1(0) = -(y-2)*(y-3), u_2(0) = 0 ; u_1(1) = (y-2)*(y-3), u_2(1) = 0 ;
46 // u_1(walls) = 0, u_2(walls) = 0;
47 // C(0) = 1 ; C(1) = 0;
48 // grad(C) dot n (walls) = 0 ;
49 // grad(C) dot n (2) = 0 ; grad(C) dot n (3) = 0
50 
51 // The QoI is:
52 // Q((u,v), C) = integral_{left_outlet} - u * C ds
53 
54 // The complete equal order adjoint QoI error estimate is: (Notation for derivatives: grad(C) = C,1 + C,2)
55 // Q(u) - Q(u_h) \leq
56 // |e(u_1)|_{H1} |e(u_1^*)|_{H1} + |e(u_2)|_{H1} |e(u_2^*)|_{H1} + (1/Pe) * |e(C)|_{H1} |e(C^*)|_{H1} +
57 // ||e(u_1,1)||_{L2} ||e(p^*)||_{L2} + ||e(u_2,2)||_{L2} ||e(p^*)||_{L2} + ||e(u_1,1^*)||_{L2} ||e(p)||_{L2} + ||e(u_2,2^*)||_{L2} ||e(p)||_{L2} +
58 // ||e((u_1)_h C,1)||_{L2} ||e(C^*)||_{L2} + ||e(u1 C,1_h)||_{L2} ||e(C^*)||_{L2}
59 // ||e((u_2)_h C,2)||_{L2} ||e(C^*)||_{L2} + ||e(u2 C,2_h)||_{L2} ||e(C^*)||_{L2}
60 // = error_non_pressure + error_with_pressure + error_convection_diffusion_x + error_convection_diffusion_y
61 
62 // C++ includes
63 #include <iostream>
64 #include <sys/time.h>
65 #include <iomanip>
66 
67 // Libmesh includes
68 #include "libmesh/equation_systems.h"
69 #include "libmesh/auto_ptr.h" // libmesh_make_unique
70 #include "libmesh/twostep_time_solver.h"
71 #include "libmesh/euler_solver.h"
72 #include "libmesh/euler2_solver.h"
73 #include "libmesh/steady_solver.h"
74 #include "libmesh/newton_solver.h"
75 #include "libmesh/numeric_vector.h"
76 #include "libmesh/petsc_diff_solver.h"
77 #include "libmesh/mesh.h"
78 #include "libmesh/mesh_tools.h"
79 #include "libmesh/mesh_base.h"
80 #include "libmesh/mesh_refinement.h"
81 #include "libmesh/system.h"
82 #include "libmesh/system_norm.h"
83 #include "libmesh/adjoint_residual_error_estimator.h"
84 #include "libmesh/const_fem_function.h"
85 #include "libmesh/error_vector.h"
86 #include "libmesh/fem_function_base.h"
87 #include "libmesh/getpot.h"
88 #include "libmesh/gmv_io.h"
89 #include "libmesh/exodusII_io.h"
90 #include "libmesh/kelly_error_estimator.h"
91 #include "libmesh/parameter_vector.h"
92 #include "libmesh/patch_recovery_error_estimator.h"
93 #include "libmesh/petsc_vector.h"
94 #include "libmesh/sensitivity_data.h"
95 #include "libmesh/tecplot_io.h"
96 #include "libmesh/uniform_refinement_estimator.h"
97 #include "libmesh/qoi_set.h"
98 #include "libmesh/weighted_patch_recovery_error_estimator.h"
99 #include "libmesh/enum_solver_package.h"
100 #include "libmesh/enum_xdr_mode.h"
101 
102 // Local includes
103 #include "coupled_system.h"
104 #include "domain.h"
105 #include "initial.h"
106 #include "femparameters.h"
107 #include "mysystems.h"
108 #include "output.h"
109 #include "H-qoi.h"
110 
111 
112 // Bring in everything from the libMesh namespace
113 using namespace libMesh;
114 
115 // Number output files
116 
117 std::string numbered_filename(unsigned int t_step, // The timestep count
118  unsigned int a_step, // The adaptive step count
119  std::string solution_type, // primal or adjoint solve
120  std::string type,
121  std::string extension,
122  FEMParameters & param)
123 {
124  std::ostringstream file_name;
125  file_name << solution_type
126  << ".out."
127  << type
128  << '.'
129  << std::setw(3)
130  << std::setfill('0')
131  << std::right
132  << t_step
133  << '.'
134  << std::setw(2)
135  << std::setfill('0')
136  << std::right
137  << a_step
138  << '.'
139  << extension;
140 
141  if (param.output_bz2)
142  file_name << ".bz2";
143  else if (param.output_gz)
144  file_name << ".gz";
145  return file_name.str();
146 }
147 
148 // Possibly write tecplot, gmv, xda/xdr, and exodus output files.
150  unsigned int t_step, // The timestep count
151  unsigned int a_step, // The adaptive step count
152  std::string solution_type, // primal or adjoint solve
153  FEMParameters & param)
154 {
155  MeshBase & mesh = es.get_mesh();
156 
157 #ifdef LIBMESH_HAVE_GMV
158  if (param.output_gmv)
159  {
160  std::ostringstream file_name_gmv;
161  file_name_gmv << solution_type
162  << ".out.gmv."
163  << std::setw(3)
164  << std::setfill('0')
165  << std::right
166  << t_step
167  << '.'
168  << std::setw(2)
169  << std::setfill('0')
170  << std::right
171  << a_step;
172 
174  (file_name_gmv.str(), es);
175  }
176 #endif
177 
178 #ifdef LIBMESH_HAVE_TECPLOT_API
179  if (param.output_tecplot)
180  {
181  std::ostringstream file_name_tecplot;
182  file_name_tecplot << solution_type
183  << ".out."
184  << std::setw(3)
185  << std::setfill('0')
186  << std::right
187  << t_step
188  << '.'
189  << std::setw(2)
190  << std::setfill('0')
191  << std::right
192  << a_step
193  << ".plt";
194 
196  (file_name_tecplot.str(), es);
197  }
198 #endif
199 
200  if (param.output_xda || param.output_xdr)
202  if (param.output_xda)
203  {
204  mesh.write(numbered_filename(t_step, a_step, solution_type, "mesh", "xda", param));
205  es.write(numbered_filename(t_step, a_step, solution_type, "soln", "xda", param),
208  }
209  if (param.output_xdr)
210  {
211  mesh.write(numbered_filename(t_step, a_step, solution_type, "mesh", "xdr", param));
212  es.write(numbered_filename(t_step, a_step, solution_type, "soln", "xdr", param),
215  }
216 
217 #ifdef LIBMESH_HAVE_EXODUS_API
218  if (param.output_exodus)
219  {
220  // We write out one file per adaptive step. The files are named in
221  // the following way:
222  // foo.e
223  // foo.e-s002
224  // foo.e-s003
225  // ...
226  // so that, if you open the first one with Paraview, it actually
227  // opens the entire sequence of adapted files.
228  std::ostringstream file_name_exodus;
229 
230  file_name_exodus << solution_type << ".e";
231  if (a_step > 0)
232  file_name_exodus << "-s"
233  << std::setw(3)
234  << std::setfill('0')
235  << std::right
236  << a_step + 1;
237 
238  // We write each adaptive step as a pseudo "time" step, where the
239  // time simply matches the (1-based) adaptive step we are on.
240  ExodusII_IO(mesh).write_timestep(file_name_exodus.str(),
241  es,
242  1,
243  /*time=*/a_step + 1);
244  }
245 #endif
246 }
247 
249 {
250  // Only one processor needs to take care of headers.
251  if (libMesh::global_processor_id() != 0)
252  return;
253 
254  start_output(param.initial_timestep, "out_clocktime.m", "vector_clocktime");
255 
256  if (param.run_simulation)
257  {
258  start_output(param.initial_timestep, "out_activemesh.m", "table_activemesh");
259  start_output(param.initial_timestep, "out_solvesteps.m", "table_solvesteps");
260 
261  if (param.timesolver_tolerance)
262  {
263  start_output(param.initial_timestep, "out_time.m", "vector_time");
264  start_output(param.initial_timestep, "out_timesteps.m", "vector_timesteps");
265  }
266  if (param.steadystate_tolerance)
267  start_output(param.initial_timestep, "out_changerate.m", "vector_changerate");
268  }
269 }
270 
272  unsigned int a_step,
273  unsigned int newton_steps,
274  unsigned int krylov_steps,
275  unsigned int tv_sec,
276  unsigned int tv_usec)
277 {
278  MeshBase & mesh = es.get_mesh();
279 
280  // Query parallel_object_only() methods *outside* if(pid==0)
281  const std::size_t n_active_elem = mesh.n_active_elem();
282  const std::size_t n_active_dofs = es.n_active_dofs();
283 
284  if (mesh.processor_id() == 0)
285  {
286  // Write out the number of elements/dofs used
287  std::ofstream activemesh ("out_activemesh.m",
288  std::ios_base::app | std::ios_base::out);
289  activemesh.precision(17);
290  activemesh << (a_step + 1) << ' '
291  << n_active_elem << ' '
292  << n_active_dofs << std::endl;
293 
294  // Write out the number of solver steps used
295  std::ofstream solvesteps ("out_solvesteps.m",
296  std::ios_base::app | std::ios_base::out);
297  solvesteps.precision(17);
298  solvesteps << newton_steps << ' '
299  << krylov_steps << std::endl;
300 
301  // Write out the clock time
302  std::ofstream clocktime ("out_clocktime.m",
303  std::ios_base::app | std::ios_base::out);
304  clocktime.precision(17);
305  clocktime << tv_sec << '.' << tv_usec << std::endl;
306  }
307 }
308 
310 {
311  // Write footers on output .m files
312  if (libMesh::global_processor_id() == 0)
313  {
314  std::ofstream clocktime ("out_clocktime.m",
315  std::ios_base::app | std::ios_base::out);
316  clocktime << "];" << std::endl;
317 
318  if (param.run_simulation)
319  {
320  std::ofstream activemesh ("out_activemesh.m",
321  std::ios_base::app | std::ios_base::out);
322  activemesh << "];" << std::endl;
323 
324  std::ofstream solvesteps ("out_solvesteps.m",
325  std::ios_base::app | std::ios_base::out);
326  solvesteps << "];" << std::endl;
327 
328  if (param.timesolver_tolerance)
329  {
330  std::ofstream times ("out_time.m",
331  std::ios_base::app | std::ios_base::out);
332  times << "];" << std::endl;
333  std::ofstream timesteps ("out_timesteps.m",
334  std::ios_base::app | std::ios_base::out);
335  timesteps << "];" << std::endl;
336  }
337  if (param.steadystate_tolerance)
338  {
339  std::ofstream changerate ("out_changerate.m",
340  std::ios_base::app | std::ios_base::out);
341  changerate << "];" << std::endl;
342  }
343  }
344 
345  // We're done, so write out a file (for e.g. Make to check)
346  std::ofstream complete ("complete");
347  complete << "complete" << std::endl;
348  }
349 }
350 
351 #if defined(LIBMESH_HAVE_GMV) || defined(LIBMESH_HAVE_TECPLOT_API)
352 void write_error(EquationSystems & es,
353  ErrorVector & error,
354  unsigned int t_number,
355  unsigned int a_number,
356  FEMParameters & param,
357  std::string error_type)
358 #else
361  unsigned int,
362  unsigned int,
363  FEMParameters &,
364  std::string)
365 #endif
366 {
367 #ifdef LIBMESH_HAVE_GMV
368  if (param.write_gmv_error)
369  {
370  std::ostringstream error_gmv;
371  error_gmv << "error.gmv."
372  << std::setw(3)
373  << std::setfill('0')
374  << std::right
375  << a_number
376  << "."
377  << std::setw(2)
378  << std::setfill('0')
379  << std::right
380  << t_number
381  << error_type;
382 
383  error.plot_error(error_gmv.str(), es.get_mesh());
384  }
385 #endif
386 
387 #ifdef LIBMESH_HAVE_TECPLOT_API
388  if (param.write_tecplot_error)
389  {
390  std::ostringstream error_tecplot;
391  error_tecplot << "error.plt."
392  << std::setw(3)
393  << std::setfill('0')
394  << std::right
395  << a_number
396  << "."
397  << std::setw(2)
398  << std::setfill('0')
399  << std::right
400  << t_number
401  << error_type;
402 
403  error.plot_error(error_tecplot.str(), es.get_mesh());
404  }
405 #endif
406 }
407 
408 void read_output(EquationSystems & es,
409  unsigned int t_step,
410  unsigned int a_step,
411  std::string solution_type,
412  FEMParameters & param)
413 {
414  MeshBase & mesh = es.get_mesh();
415 
416  std::string file_name_mesh, file_name_soln;
417  // Look for ASCII files first
418  if (param.output_xda)
419  {
420  file_name_mesh = numbered_filename(t_step, a_step, solution_type, "mesh", "xda", param);
421  file_name_soln = numbered_filename(t_step, a_step, solution_type, "soln", "xda", param);
422  }
423  else if (param.output_xdr)
424  {
425  file_name_mesh = numbered_filename(t_step, a_step, solution_type, "mesh", "xdr", param);
426  file_name_soln = numbered_filename(t_step, a_step, solution_type, "soln", "xdr", param);
427  }
428 
429  // Read in the mesh
430  mesh.read(file_name_mesh);
431 
432  // And the stored solution
433  es.read(file_name_soln, READ,
437 
438  // Put systems in a consistent state
439  for (unsigned int i = 0; i != es.n_systems(); ++i)
440  es.get_system<FEMSystem>(i).update();
441 
442  // Figure out the current time
443  Real current_time = 0., current_timestep = 0.;
444 
445  if (param.timesolver_tolerance)
446  {
447  std::ifstream times ("out_time.m");
448  std::ifstream timesteps ("out_timesteps.m");
449  if (times.is_open() && timesteps.is_open())
450  {
451  // Read headers
452  const unsigned int headersize = 25;
453  char header[headersize];
454  timesteps.getline (header, headersize);
455  if (strcmp(header, "vector_timesteps = [") != 0)
456  libmesh_error_msg("Bad header in out_timesteps.m:\n" << header);
457 
458  times.getline (header, headersize);
459  if (strcmp(header, "vector_time = [") != 0)
460  libmesh_error_msg("Bad header in out_time.m:\n" << header);
461 
462  // Read each timestep
463  for (unsigned int i = 0; i != t_step; ++i)
464  {
465  if (!times.good())
466  libmesh_error_msg("Error: File out_time.m is in non-good state.");
467  times >> current_time;
468  timesteps >> current_timestep;
469  }
470  // Remember to increment the last timestep; out_times.m
471  // lists each *start* time
472  current_time += current_timestep;
473  }
474  else
475  libmesh_error_msg("Error opening out_time.m or out_timesteps.m");
476  }
477  else
478  current_time = t_step * param.deltat;
479 
480  for (unsigned int i = 0; i != es.n_systems(); ++i)
481  es.get_system<FEMSystem>(i).time = current_time;
482 }
483 
484 void set_system_parameters(FEMSystem & system,
485  FEMParameters & param)
486 {
487  // Verify analytic jacobians against numerical ones?
489 
490  // More desperate debugging options
492  system.print_solutions = param.print_solutions;
494  system.print_residuals = param.print_residuals;
496  system.print_jacobians = param.print_jacobians;
497 
500 
501  // Solve this as a time-dependent or steady system
502  if (param.transient)
503  {
504  UnsteadySolver *innersolver;
505  if (param.timesolver_core == "euler2")
506  {
507  Euler2Solver *euler2solver =
508  new Euler2Solver(system);
509 
510  euler2solver->theta = param.timesolver_theta;
511  innersolver = euler2solver;
512  }
513  else if (param.timesolver_core == "euler")
514  {
515  EulerSolver *eulersolver =
516  new EulerSolver(system);
517 
518  eulersolver->theta = param.timesolver_theta;
519  innersolver = eulersolver;
520  }
521  else
522  libmesh_error_msg("Don't recognize core TimeSolver type: " << param.timesolver_core);
523 
524  if (param.timesolver_tolerance)
525  {
526  TwostepTimeSolver *timesolver =
527  new TwostepTimeSolver(system);
528 
529  timesolver->max_growth = param.timesolver_maxgrowth;
530  timesolver->target_tolerance = param.timesolver_tolerance;
531  timesolver->upper_tolerance = param.timesolver_upper_tolerance;
532  timesolver->component_norm = SystemNorm(param.timesolver_norm);
533 
534  timesolver->core_time_solver.reset(innersolver);
535  system.time_solver.reset(timesolver);
536  }
537  else
538  system.time_solver.reset(innersolver);
539  }
540  else
541  system.time_solver = libmesh_make_unique<SteadySolver>(system);
542 
543  system.time_solver->reduce_deltat_on_diffsolver_failure =
544  param.deltat_reductions;
545  system.time_solver->quiet = param.time_solver_quiet;
546 
547  // Set the time stepping options
548  system.deltat = param.deltat;
549 
550  // And the integration options
552 
553  // And the nonlinear solver options
554  if (param.use_petsc_snes)
555  {
556 #ifdef LIBMESH_HAVE_PETSC
557  PetscDiffSolver *solver = new PetscDiffSolver(system);
558  system.time_solver->diff_solver().reset(solver);
559 #else
560  libmesh_error_msg("This example requires libMesh to be compiled with PETSc support.");
561 #endif
562  }
563  else
564  {
565  NewtonSolver *solver = new NewtonSolver(system);
566  system.time_solver->diff_solver().reset(solver);
567 
568  solver->quiet = param.solver_quiet;
569  solver->verbose = !param.solver_quiet;
571  solver->minsteplength = param.min_step_length;
577  if (system.time_solver->reduce_deltat_on_diffsolver_failure)
578  {
579  solver->continue_after_max_iterations = true;
580  solver->continue_after_backtrack_failure = true;
581  }
582 
583  // And the linear solver options
587  }
588 }
589 
590 #ifdef LIBMESH_ENABLE_AMR
591 
592 std::unique_ptr<MeshRefinement> build_mesh_refinement(MeshBase & mesh,
593  FEMParameters & param)
594 {
595  MeshRefinement * mesh_refinement = new MeshRefinement(mesh);
596  mesh_refinement->coarsen_by_parents() = true;
597  mesh_refinement->absolute_global_tolerance() = param.global_tolerance;
598  mesh_refinement->nelem_target() = param.nelem_target;
599  mesh_refinement->refine_fraction() = param.refine_fraction;
600  mesh_refinement->coarsen_fraction() = param.coarsen_fraction;
601  mesh_refinement->coarsen_threshold() = param.coarsen_threshold;
602 
603  return std::unique_ptr<MeshRefinement>(mesh_refinement);
604 }
605 
606 #endif // LIBMESH_ENABLE_AMR
607 
608 // This function builds the Kelly error indicator. This indicator can be used
609 // for comparisons of adjoint and non-adjoint based error indicators
610 std::unique_ptr<ErrorEstimator> build_error_estimator(FEMParameters & /* param */)
611 {
612  return libmesh_make_unique<KellyErrorEstimator>();
613 }
614 
615 // Functions to build the adjoint based error indicators
616 // The error_non_pressure and error_pressure contributions are estimated using
617 // the build_error_estimator_component_wise function below
618 std::unique_ptr<ErrorEstimator>
619 build_error_estimator_component_wise (FEMParameters & param,
620  std::vector<std::vector<Real>> & term_weights,
621  std::vector<FEMNormType> & primal_error_norm_type,
622  std::vector<FEMNormType> & dual_error_norm_type)
623 {
624  AdjointResidualErrorEstimator * adjoint_residual_estimator = new AdjointResidualErrorEstimator;
625 
626  // Both the primal and dual weights are going to be estimated using the patch recovery error estimator
628  adjoint_residual_estimator->primal_error_estimator().reset(p1);
629 
631  adjoint_residual_estimator->dual_error_estimator().reset(p2);
632 
633  // Set the boolean for specifying whether we are reusing patches while building the patch recovery estimates
634  p1->set_patch_reuse(param.patch_reuse);
635  p2->set_patch_reuse(param.patch_reuse);
636 
637  // Using the user filled error norm type vector, we pass the type of norm to be used for
638  // the error in each variable, we can have different types of norms for the primal and
639  // dual variables
640  std::size_t size = primal_error_norm_type.size();
641 
642  libmesh_assert_equal_to (size, dual_error_norm_type.size());
643  for (unsigned int i = 0; i != size; ++i)
644  {
645  adjoint_residual_estimator->primal_error_estimator()->error_norm.set_type(i, primal_error_norm_type[i]);
646  adjoint_residual_estimator->dual_error_estimator()->error_norm.set_type(i, dual_error_norm_type[i]);
647  }
648 
649  // Now we set the right weights for each term in the error estimate, using the user provided
650  // term_weights matrix
651  libmesh_assert_equal_to (size, term_weights.size());
652  for (unsigned int i = 0; i != size; ++i)
653  {
654  libmesh_assert_equal_to (size, term_weights[i].size());
655  adjoint_residual_estimator->error_norm.set_weight(i, term_weights[i][i]);
656  for (unsigned int j = 0; j != size; ++j)
657  if (i != j)
658  adjoint_residual_estimator->error_norm.set_off_diagonal_weight(i, j, term_weights[i][j]);
659  }
660 
661  return std::unique_ptr<ErrorEstimator>(adjoint_residual_estimator);
662 }
663 
664 // The error_convection_diffusion_x and error_convection_diffusion_y are the nonlinear contributions which
665 // are computed using the build_weighted_error_estimator_component_wise below
666 std::unique_ptr<ErrorEstimator>
667 build_weighted_error_estimator_component_wise (FEMParameters & param,
668  std::vector<std::vector<Real>> & term_weights,
669  std::vector<FEMNormType> & primal_error_norm_type,
670  std::vector<FEMNormType> & dual_error_norm_type,
671  std::vector<FEMFunctionBase<Number> *> coupled_system_weight_functions)
672 {
673  AdjointResidualErrorEstimator * adjoint_residual_estimator = new AdjointResidualErrorEstimator;
674 
675  // Using the user filled error norm type vector, we pass the type of norm to be used for
676  // the error in each variable, we can have different types of norms for the primal and
677  // dual variables
678 
680  adjoint_residual_estimator->primal_error_estimator().reset(p1);
681 
683  adjoint_residual_estimator->dual_error_estimator().reset(p2);
684 
685  p1->set_patch_reuse(param.patch_reuse);
686  p2->set_patch_reuse(param.patch_reuse);
687 
688  // This is the critical difference with the build_error_estimate_component_wise
689  p1->weight_functions.clear();
690 
691  // We pass the pointers to the user specified weight functions to the patch recovery
692  // error estimator objects declared above
693  std::size_t size = primal_error_norm_type.size();
694 
695  libmesh_assert(coupled_system_weight_functions.size() == size);
696  libmesh_assert(dual_error_norm_type.size() == size);
697 
698  for (unsigned int i = 0; i != size; ++i)
699  {
700  p1->weight_functions.push_back(coupled_system_weight_functions[i]);
701  adjoint_residual_estimator->primal_error_estimator()->error_norm.set_type(i, primal_error_norm_type[i]);
702  adjoint_residual_estimator->dual_error_estimator()->error_norm.set_type(i, dual_error_norm_type[i]);
703  }
704 
705  // Now we set the right weights for each term in the error estimate, using the user provided
706  // term_weights matrix
707  libmesh_assert_equal_to (size, term_weights.size());
708  for (unsigned int i = 0; i != size; ++i)
709  {
710  libmesh_assert_equal_to (size, term_weights[i].size());
711  adjoint_residual_estimator->error_norm.set_weight(i, term_weights[i][i]);
712  for (unsigned int j = 0; j != size; ++j)
713  if (i != j)
714  adjoint_residual_estimator->error_norm.set_off_diagonal_weight(i, j, term_weights[i][j]);
715  }
716 
717  return std::unique_ptr<ErrorEstimator>(adjoint_residual_estimator);
718 }
719 
720 // The main program.
721 int main (int argc, char ** argv)
722 {
723  // Initialize libMesh.
724  LibMeshInit init (argc, argv);
725 
726  // Skip adaptive examples on a non-adaptive libMesh build
727 #ifndef LIBMESH_ENABLE_AMR
728  libmesh_example_requires(false, "--enable-amr");
729 #else
730 
731  // We use Dirichlet boundary conditions here
732 #ifndef LIBMESH_ENABLE_DIRICHLET
733  libmesh_example_requires(false, "--enable-dirichlet");
734 #endif
735 
736  // This doesn't converge with Eigen BICGSTAB or with Trilinos for some reason...
737  libmesh_example_requires(libMesh::default_solver_package() == PETSC_SOLVERS, "--enable-petsc");
738 
739  libMesh::out << "Started " << argv[0] << std::endl;
740 
741  // Make sure the general input file exists, and parse it
742  {
743  std::ifstream i("general.in");
744  if (!i)
745  libmesh_error_msg('[' << init.comm().rank() << "] Can't find general.in; exiting early.");
746  }
747 
748  GetPot infile("general.in");
749 
750  // Read in parameters from the input file
751  FEMParameters param(init.comm());
752  param.read(infile);
753 
754  // Skip higher-dimensional examples on a lower-dimensional libMesh build
755  libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");
756 
757  // Create a mesh with the given dimension, distributed
758  // across the default MPI communicator.
759  Mesh mesh(init.comm(), cast_int<unsigned char>(param.dimension));
760 
761  // And an object to refine it
762  std::unique_ptr<MeshRefinement> mesh_refinement =
763  build_mesh_refinement(mesh, param);
764 
765  // And an EquationSystems to run on it
766  EquationSystems equation_systems (mesh);
767 
768  libMesh::out << "Building mesh" << std::endl;
769 
770  if (!param.initial_timestep && param.run_simulation)
771  build_domain(mesh, param);
772 
773  libMesh::out << "Building system" << std::endl;
774 
775  FEMSystem & system = build_system(equation_systems, infile, param);
776 
777  set_system_parameters(system, param);
778 
779  libMesh::out << "Initializing systems" << std::endl;
780 
781  // Create a QoI object, we will need this to compute the QoI
782  {
783  CoupledSystemQoI qoi;
784  // Our QoI is computed on the side
785  qoi.assemble_qoi_sides = true;
786  system.attach_qoi(&qoi);
787  }
788 
789  equation_systems.init ();
790 
791  // Print information about the mesh and system to the screen.
792  mesh.print_info();
793  equation_systems.print_info();
794 
795  libMesh::out << "Starting adaptive loop" << std::endl << std::endl;
796 
797  // Count the number of steps used
798  unsigned int a_step = 0;
799 
800  // Get the linear solver object to set the preconditioner reuse flag
801  LinearSolver<Number> * linear_solver = system.get_linear_solver();
802 
803  // Adaptively solve the timestep
804  for (; a_step <= param.max_adaptivesteps; ++a_step)
805  {
806  // We have to ensure that we are refining to either an error
807  // tolerance or to a target number of elements, and, not to a
808  // non-zero tolerance and a target number of elements
809  // simultaneously
810  if (param.global_tolerance > 0 && param.nelem_target > 0)
811  {
812  libMesh::out<<"We cant refine to both a non-zero tolerance and a target number of elements, EXITING adaptive loop. "<<std::endl<<std::endl;
813  break;
814  }
815 
816  // We dont want to reuse the preconditioner for the forward solve
817  linear_solver->reuse_preconditioner(false);
818 
819  libMesh::out << "Adaptive step " << a_step << std::endl;
820 
821  libMesh::out << "Solving the forward problem" << std::endl;
822 
823  libMesh::out << "We have "
824  << mesh.n_active_elem()
825  << " active elements and "
826  << equation_systems.n_active_dofs()
827  << " active dofs."
828  << std::endl
829  << std::endl;
830 
831  // Solve the forward system
832  system.solve();
833 
834  // Write the output
835  write_output(equation_systems, 0, a_step, "primal", param);
836 
837  // Compute the QoI
838  system.assemble_qoi();
839 
840  // We just call a postprocess here to set the variable computed_QoI to the value computed by assemble_qoi
841  system.postprocess();
842 
843  // Get the value of the computed_QoI variable of the CoupledSystem class
844  Number QoI_0_computed = (dynamic_cast<CoupledSystem &>(system)).get_QoI_value();
845 
846  libMesh::out << "The boundary QoI is "
847  << std::setprecision(17)
848  << QoI_0_computed
849  << std::endl
850  << std::endl;
851 
852  // Hard coded assert to ensure that the actual numbers we are getting are what they should be
853  if (a_step == param.max_adaptivesteps)
854  libmesh_assert_less(std::abs(QoI_0_computed - 0.0833), 2.5e-4);
855 
856  // You dont need to compute error estimates and refine at the last
857  // adaptive step, only before that
858  if (a_step!=param.max_adaptivesteps)
859  {
860  NumericVector<Number> & primal_solution = (*system.solution);
861 
862  // Make sure we get the contributions to the adjoint RHS from the sides
863  system.assemble_qoi_sides = true;
864 
865  // We are about to solve the adjoint system, but before we
866  // do this we see the same preconditioner flag to reuse the
867  // preconditioner from the forward solver
868  linear_solver->reuse_preconditioner(param.reuse_preconditioner);
869 
870  // Solve the adjoint system
871  libMesh::out<< "Solving the adjoint problem" <<std::endl;
872  system.adjoint_solve();
873 
874  // Now that we have solved the adjoint, set the adjoint_already_solved boolean to true, so we dont solve unnecessarily in the error estimator
875  system.set_adjoint_already_solved(true);
876 
877  // To plot the adjoint solution, we swap it with the primal solution
878  // and use the write_output function
879  NumericVector<Number> & dual_solution = system.get_adjoint_solution();
880  primal_solution.swap(dual_solution);
881 
882  write_output(equation_systems, 0, a_step, "adjoint", param);
883 
884  // Swap back
885  primal_solution.swap(dual_solution);
886 
887  // We need the values of the parameters Pe from the
888  // system for the adjoint error estimate
889  Real Pe = (dynamic_cast<CoupledSystem &>(system)).get_Pe();
890 
891  // The total error is the sum: error = error_non_pressure +
892  // error_with_pressure + ...
893  // error_estimator_convection_diffusion_x +
894  // error_estimator_convection_diffusion_y
895  ErrorVector error;
896 
897  // We first construct the non-pressure contributions
898  ErrorVector error_non_pressure;
899 
900  // First we build the norm_type_vector_non_pressure vectors and
901  // weights_matrix_non_pressure matrix for the non-pressure term
902  // error contributions
903  std::vector<FEMNormType> primal_norm_type_vector_non_pressure;
904  primal_norm_type_vector_non_pressure.push_back(H1_SEMINORM);
905  primal_norm_type_vector_non_pressure.push_back(H1_SEMINORM);
906  primal_norm_type_vector_non_pressure.push_back(L2);
907  primal_norm_type_vector_non_pressure.push_back(H1_SEMINORM);
908 
909  std::vector<FEMNormType> dual_norm_type_vector_non_pressure;
910  dual_norm_type_vector_non_pressure.push_back(H1_SEMINORM);
911  dual_norm_type_vector_non_pressure.push_back(H1_SEMINORM);
912  dual_norm_type_vector_non_pressure.push_back(L2);
913  dual_norm_type_vector_non_pressure.push_back(H1_SEMINORM);
914 
915  std::vector<std::vector<Real>>
916  weights_matrix_non_pressure(system.n_vars(),
917  std::vector<Real>(system.n_vars(), 0.0));
918  weights_matrix_non_pressure[0][0] = 1.;
919  weights_matrix_non_pressure[1][1] = 1.;
920  weights_matrix_non_pressure[3][3] = 1./Pe;
921 
922  // We build the error estimator to estimate the contributions
923  // to the QoI error from the non pressure term
924  std::unique_ptr<ErrorEstimator> error_estimator_non_pressure =
925  build_error_estimator_component_wise (param,
926  weights_matrix_non_pressure,
927  primal_norm_type_vector_non_pressure,
928  dual_norm_type_vector_non_pressure);
929 
930  // Estimate the contributions to the QoI error from the non
931  // pressure terms
932  error_estimator_non_pressure->estimate_error(system, error_non_pressure);
933 
934  // Plot the estimated error from the non_pressure terms
935  write_error(equation_systems, error_non_pressure, 0, a_step, param, "_non_pressure");
936 
937  // Now for the pressure contributions
938  ErrorVector error_with_pressure;
939 
940  // Next we build the norm_type_vector_with_pressure vectors and
941  // weights_matrix_with_pressure matrix for the pressure term
942  // error contributions
943  std::vector<FEMNormType> primal_norm_type_vector_with_pressure;
944  primal_norm_type_vector_with_pressure.push_back(H1_X_SEMINORM);
945  primal_norm_type_vector_with_pressure.push_back(H1_Y_SEMINORM);
946  primal_norm_type_vector_with_pressure.push_back(L2);
947  primal_norm_type_vector_with_pressure.push_back(L2);
948 
949  std::vector<FEMNormType> dual_norm_type_vector_with_pressure;
950  dual_norm_type_vector_with_pressure.push_back(H1_X_SEMINORM);
951  dual_norm_type_vector_with_pressure.push_back(H1_Y_SEMINORM);
952  dual_norm_type_vector_with_pressure.push_back(L2);
953  dual_norm_type_vector_with_pressure.push_back(L2);
954 
955  std::vector<std::vector<Real>>
956  weights_matrix_with_pressure (system.n_vars(),
957  std::vector<Real>(system.n_vars(), 0.0));
958  weights_matrix_with_pressure[0][2] = 1.;
959  weights_matrix_with_pressure[1][2] = 1.;
960  weights_matrix_with_pressure[2][0] = 1.;
961  weights_matrix_with_pressure[2][1] = 1.;
962 
963  // We build the error estimator to estimate the contributions
964  // to the QoI error from the pressure term
965  std::unique_ptr<ErrorEstimator> error_estimator_with_pressure =
966  build_error_estimator_component_wise (param,
967  weights_matrix_with_pressure,
968  primal_norm_type_vector_with_pressure,
969  dual_norm_type_vector_with_pressure);
970 
971  // Estimate the contributions to the QoI error from the pressure terms
972  error_estimator_with_pressure->estimate_error(system, error_with_pressure);
973 
974  // Plot the error due to the pressure terms
975  write_error(equation_systems, error_with_pressure, 0, a_step, param, "_with_pressure");
976 
977  // Now for the convection diffusion term errors (in the x and y directions)
978 
979  ErrorVector error_convection_diffusion_x;
980 
981  // The norm type vectors and weights matrix for the convection_diffusion_x errors
982  std::vector<FEMNormType> primal_norm_type_vector_convection_diffusion_x;
983  primal_norm_type_vector_convection_diffusion_x.push_back(L2);
984  primal_norm_type_vector_convection_diffusion_x.push_back(L2);
985  primal_norm_type_vector_convection_diffusion_x.push_back(L2);
986  primal_norm_type_vector_convection_diffusion_x.push_back(H1_X_SEMINORM);
987 
988  std::vector<FEMNormType> dual_norm_type_vector_convection_diffusion_x;
989  dual_norm_type_vector_convection_diffusion_x.push_back(L2);
990  dual_norm_type_vector_convection_diffusion_x.push_back(L2);
991  dual_norm_type_vector_convection_diffusion_x.push_back(L2);
992  // Note that we need the error of the dual concentration in L2
993  dual_norm_type_vector_convection_diffusion_x.push_back(L2);
994 
995  std::vector<std::vector<Real>>
996  weights_matrix_convection_diffusion_x (system.n_vars(),
997  std::vector<Real>(system.n_vars(), 0.0));
998  weights_matrix_convection_diffusion_x[0][3] = 1.;
999  weights_matrix_convection_diffusion_x[3][3] = 1.;
1000 
1001  // We will also have to build and pass the weight functions to the weighted patch recovery estimators
1002 
1003  // We pass the identity function as weights to error entries that the above matrix will scale to 0.
1004  ConstFEMFunction<Number> identity(1);
1005 
1006  // Declare object of class CoupledFEMFunctionsx, the definition of the function contains the weight
1007  // to be applied to the relevant terms
1008  // For ||e(u1 C,1_h)||_{L2} ||e(C^*)||_{L2} term, returns C,1_h
1009  CoupledFEMFunctionsx convdiffx0(system, 0);
1010  // For ||e((u_1)_h C,1)||_{L2} ||e(C^*)||_{L2} term, returns (u_1)_h
1011  CoupledFEMFunctionsx convdiffx3(system, 3);
1012 
1013  // Make a vector of pointers to these objects
1014  std::vector<FEMFunctionBase<Number> *> coupled_system_weight_functions_x;
1015  coupled_system_weight_functions_x.push_back(&convdiffx0);
1016  coupled_system_weight_functions_x.push_back(&identity);
1017  coupled_system_weight_functions_x.push_back(&identity);
1018  coupled_system_weight_functions_x.push_back(&convdiffx3);
1019 
1020  // Build the error estimator to estimate the contributions
1021  // to the QoI error from the convection diffusion x term
1022  std::unique_ptr<ErrorEstimator> error_estimator_convection_diffusion_x =
1023  build_weighted_error_estimator_component_wise (param,
1024  weights_matrix_convection_diffusion_x,
1025  primal_norm_type_vector_convection_diffusion_x,
1026  dual_norm_type_vector_convection_diffusion_x,
1027  coupled_system_weight_functions_x);
1028 
1029  // Estimate the contributions to the QoI error from the
1030  // convection diffusion x term
1031  error_estimator_convection_diffusion_x->estimate_error(system, error_convection_diffusion_x);
1032 
1033  // Plot this error
1034  write_error (equation_systems,
1035  error_convection_diffusion_x,
1036  0,
1037  a_step,
1038  param,
1039  "_convection_diffusion_x");
1040 
1041  // Now for the y direction terms
1042  ErrorVector error_convection_diffusion_y;
1043 
1044  // The norm type vectors and weights matrix for the convection_diffusion_x errors
1045  std::vector<FEMNormType> primal_norm_type_vector_convection_diffusion_y;
1046  primal_norm_type_vector_convection_diffusion_y.push_back(L2);
1047  primal_norm_type_vector_convection_diffusion_y.push_back(L2);
1048  primal_norm_type_vector_convection_diffusion_y.push_back(L2);
1049  primal_norm_type_vector_convection_diffusion_y.push_back(H1_Y_SEMINORM);
1050 
1051  std::vector<FEMNormType> dual_norm_type_vector_convection_diffusion_y;
1052  dual_norm_type_vector_convection_diffusion_y.push_back(L2);
1053  dual_norm_type_vector_convection_diffusion_y.push_back(L2);
1054  dual_norm_type_vector_convection_diffusion_y.push_back(L2);
1055  // Note that we need the error of the dual concentration in L2
1056  dual_norm_type_vector_convection_diffusion_y.push_back(L2);
1057 
1058  std::vector<std::vector<Real>>
1059  weights_matrix_convection_diffusion_y (system.n_vars(),
1060  std::vector<Real>(system.n_vars(), 0.0));
1061  weights_matrix_convection_diffusion_y[1][3] = 1.;
1062  weights_matrix_convection_diffusion_y[3][3] = 1.;
1063 
1064  // For ||e(u2 C,2_h)||_{L2} ||e(C^*)||_{L2} term, returns C,2_h
1065  CoupledFEMFunctionsy convdiffy1(system, 1);
1066  // For ||e((u_2)_h C,2)||_{L2} ||e(C^*)||_{L2} term, returns (u_2)_h
1067  CoupledFEMFunctionsy convdiffy3(system, 3);
1068 
1069  // Make a vector of pointers to these objects
1070  std::vector<FEMFunctionBase<Number> *> coupled_system_weight_functions_y;
1071  coupled_system_weight_functions_y.push_back(&identity);
1072  coupled_system_weight_functions_y.push_back(&convdiffy1);
1073  coupled_system_weight_functions_y.push_back(&identity);
1074  coupled_system_weight_functions_y.push_back(&convdiffy3);
1075 
1076  // Build the error estimator to estimate the contributions
1077  // to the QoI error from the convection diffusion y term
1078  std::unique_ptr<ErrorEstimator> error_estimator_convection_diffusion_y =
1079  build_weighted_error_estimator_component_wise (param,
1080  weights_matrix_convection_diffusion_y,
1081  primal_norm_type_vector_convection_diffusion_y,
1082  dual_norm_type_vector_convection_diffusion_y,
1083  coupled_system_weight_functions_y);
1084 
1085  // Estimate the contributions to the QoI error from the
1086  // convection diffusion y terms
1087  error_estimator_convection_diffusion_y->estimate_error(system, error_convection_diffusion_y);
1088 
1089  // Plot this error
1090  write_error(equation_systems, error_convection_diffusion_y, 0, a_step, param, "_convection_diffusion_y");
1091 
1092  if (param.indicator_type == "adjoint_residual")
1093  {
1094  error.resize(error_non_pressure.size());
1095 
1096  // Now combine the contribs from the pressure and non
1097  // pressure terms to get the complete estimate
1098  for (std::size_t i = 0; i < error.size(); i++)
1099  error[i] = error_non_pressure[i] + error_with_pressure[i] + error_convection_diffusion_x[i] + error_convection_diffusion_y[i];
1100  }
1101  else
1102  {
1103  libMesh::out << "Using Kelly Estimator" << std::endl;
1104 
1105  // Build the Kelly error estimator
1106  std::unique_ptr<ErrorEstimator> error_estimator = build_error_estimator(param);
1107 
1108  // Estimate the error
1109  error_estimator->estimate_error(system, error);
1110  }
1111 
1112  write_error(equation_systems, error, 0, a_step, param, "_total");
1113 
1114  // We have to refine either based on reaching an error
1115  // tolerance or a number of elements target, which should be
1116  // verified above
1117 
1118  // Otherwise we flag elements by error tolerance or nelem
1119  // target
1120 
1121  if (param.refine_uniformly)
1122  {
1123  mesh_refinement->uniformly_refine(1);
1124  }
1125  else if (param.global_tolerance >= 0. && param.nelem_target == 0.) // Refine based on reaching an error tolerance
1126  {
1127  mesh_refinement->flag_elements_by_error_tolerance (error);
1128 
1129  // Carry out the adaptive mesh refinement/coarsening
1130  mesh_refinement->refine_and_coarsen_elements();
1131  }
1132  else // Refine based on reaching a target number of elements
1133  {
1134  //If we have reached the desired number of elements, we
1135  //dont do any more adaptive steps
1136  if (mesh.n_active_elem() >= param.nelem_target)
1137  {
1138  libMesh::out << "We reached the target number of elements." << std::endl <<std::endl;
1139  break;
1140  }
1141 
1142  mesh_refinement->flag_elements_by_nelem_target (error);
1143 
1144  // Carry out the adaptive mesh refinement/coarsening
1145  mesh_refinement->refine_and_coarsen_elements();
1146  }
1147 
1148  equation_systems.reinit();
1149  }
1150  }
1151 
1152  write_output_footers(param);
1153 
1154 #endif // #ifndef LIBMESH_ENABLE_AMR
1155 
1156  // All done.
1157  return 0;
1158 
1159 }
libMesh::LinearSolver::reuse_preconditioner
virtual void reuse_preconditioner(bool)
Set the same_preconditioner flag, which indicates if we reuse the same preconditioner for subsequent ...
Definition: linear_solver.C:129
libMesh::EulerSolver
This class defines a theta-method Euler (defaulting to Backward Euler with theta = 1....
Definition: euler_solver.h:43
FEMParameters::reuse_preconditioner
bool reuse_preconditioner
Definition: femparameters.h:128
libMesh::ErrorVector::plot_error
void plot_error(const std::string &filename, const MeshBase &mesh) const
Plots a data file, of a type determined by looking at the file extension in filename,...
Definition: error_vector.C:210
set_system_parameters
void set_system_parameters(LaplaceSystem &system, FEMParameters &param)
Definition: adjoints_ex1.C:162
FEMParameters::use_petsc_snes
bool use_petsc_snes
Definition: femparameters.h:127
libMesh::DifferentiableSystem::deltat
Real deltat
For time-dependent problems, this is the amount delta t to advance the solution in time.
Definition: diff_system.h:260
mysystems.h
numbered_filename
std::string numbered_filename(unsigned int t_step, unsigned int a_step, std::string solution_type, std::string type, std::string extension, FEMParameters &param)
Definition: adjoints_ex3.C:117
FEMParameters::print_jacobians
bool print_jacobians
Definition: femparameters.h:118
FEMParameters::timesolver_norm
std::vector< libMesh::FEMNormType > timesolver_norm
Definition: femparameters.h:41
libMesh::Number
Real Number
Definition: libmesh_common.h:195
libMesh::System::n_vars
unsigned int n_vars() const
Definition: system.h:2155
write_output_solvedata
void write_output_solvedata(EquationSystems &es, unsigned int a_step, unsigned int newton_steps, unsigned int krylov_steps, unsigned int tv_sec, unsigned int tv_usec)
Definition: adjoints_ex3.C:271
libMesh::FEMSystem::solve
virtual void solve() override
Invokes the solver associated with the system.
Definition: fem_system.C:1046
libMesh::Mesh
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
libMesh::DifferentiableSystem::print_jacobian_norms
bool print_jacobian_norms
Set print_jacobian_norms to true to print |J| whenever it is assembled.
Definition: diff_system.h:341
libMesh::MeshRefinement::coarsen_threshold
Real & coarsen_threshold()
The coarsen_threshold provides hysteresis in AMR/C strategies.
Definition: mesh_refinement.h:897
libMesh::EquationSystems::get_mesh
const MeshBase & get_mesh() const
Definition: equation_systems.h:637
libMesh::MeshBase::read
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false)=0
Interfaces for reading/writing a mesh to/from a file.
CoupledSystemQoI
Definition: H-qoi.h:15
FEMParameters::coarsen_fraction
libMesh::Real coarsen_fraction
Definition: femparameters.h:61
FEMParameters::steadystate_tolerance
libMesh::Real steadystate_tolerance
Definition: femparameters.h:38
libMesh::EquationSystems::WRITE_DATA
Definition: equation_systems.h:93
libMesh::ErrorEstimator::error_norm
SystemNorm error_norm
When estimating the error in a single system, the error_norm is used to control the scaling and norm ...
Definition: error_estimator.h:164
libMesh::EquationSystems::READ_ADDITIONAL_DATA
Definition: equation_systems.h:85
libMesh::SystemNorm::set_off_diagonal_weight
void set_off_diagonal_weight(unsigned int i, unsigned int j, Real w)
Sets the weight corresponding to the norm from the variable pair v1(var1) coming from v2(var2).
Definition: system_norm.C:155
libMesh::DifferentiableSystem::print_residual_norms
bool print_residual_norms
Set print_residual_norms to true to print |F| whenever it is assembled.
Definition: diff_system.h:331
libMesh::PETSC_SOLVERS
Definition: enum_solver_package.h:36
libMesh::PatchRecoveryErrorEstimator
This class implements the Patch Recovery error indicator.
Definition: patch_recovery_error_estimator.h:55
FEMParameters::max_nonlinear_iterations
unsigned int max_nonlinear_iterations
Definition: femparameters.h:131
FEMParameters::output_xda
bool output_xda
Definition: femparameters.h:68
libMesh::NewtonSolver::require_residual_reduction
bool require_residual_reduction
If this is set to true, the solver is forced to test the residual after each Newton step,...
Definition: newton_solver.h:98
libMesh::H1_Y_SEMINORM
Definition: enum_norm_type.h:58
libMesh::NumericVector::swap
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
Definition: numeric_vector.h:989
FEMParameters::print_residuals
bool print_residuals
Definition: femparameters.h:118
libMesh::FEMFunctionBase< Number >
libMesh::DifferentiableSystem::print_element_solutions
bool print_element_solutions
Set print_element_solutions to true to print each U_elem input.
Definition: diff_system.h:351
FEMParameters::print_solution_norms
bool print_solution_norms
Definition: femparameters.h:118
FEMParameters::print_residual_norms
bool print_residual_norms
Definition: femparameters.h:118
FEMParameters::timesolver_maxgrowth
libMesh::Real timesolver_maxgrowth
Definition: femparameters.h:38
libMesh::MeshBase::write
virtual void write(const std::string &name)=0
FEMParameters::dimension
unsigned int dimension
Definition: femparameters.h:45
libMesh::DifferentiableSystem::print_residuals
bool print_residuals
Set print_residuals to true to print F whenever it is assembled.
Definition: diff_system.h:336
libMesh::System::get_adjoint_solution
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
Definition: system.C:957
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::DiffSolver::continue_after_backtrack_failure
bool continue_after_backtrack_failure
Defaults to false, telling the DiffSolver to throw an error when the backtracking scheme fails to fin...
Definition: diff_solver.h:180
FEMParameters::timesolver_tolerance
libMesh::Real timesolver_tolerance
Definition: femparameters.h:38
libMesh::H1_SEMINORM
Definition: enum_norm_type.h:43
libMesh::EquationSystems::get_system
const T_sys & get_system(const std::string &name) const
Definition: equation_systems.h:757
libMesh::System::extra_quadrature_order
int extra_quadrature_order
A member int that can be employed to indicate increased or reduced quadrature order.
Definition: system.h:1524
FEMParameters::output_gmv
bool output_gmv
Definition: femparameters.h:68
libMesh::DifferentiableSystem::attach_qoi
void attach_qoi(DifferentiableQoI *qoi_in)
Attach external QoI object.
Definition: diff_system.h:224
libMesh::EulerSolver::theta
Real theta
The value for the theta method to employ: 1.0 corresponds to backwards Euler, 0.0 corresponds to forw...
Definition: euler_solver.h:100
FEMParameters::refine_fraction
libMesh::Real refine_fraction
Definition: femparameters.h:61
FEMParameters::output_exodus
bool output_exodus
Definition: femparameters.h:68
libMesh::DifferentiableSystem::print_solution_norms
bool print_solution_norms
Set print_residual_norms to true to print |U| whenever it is used in an assembly() call.
Definition: diff_system.h:320
libMesh::default_solver_package
SolverPackage default_solver_package()
Definition: libmesh.C:993
FEMParameters::initial_linear_tolerance
double initial_linear_tolerance
Definition: femparameters.h:134
libMesh::AdaptiveTimeSolver::upper_tolerance
Real upper_tolerance
This tolerance is the maximum relative error between an exact time integration and a single time step...
Definition: adaptive_time_solver.h:161
libMesh::WRITE
Definition: enum_xdr_mode.h:40
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::ExodusII_IO::write_timestep
void write_timestep(const std::string &fname, const EquationSystems &es, const int timestep, const Real time, const std::set< std::string > *system_names=nullptr)
Writes out the solution at a specific timestep.
Definition: exodusII_io.C:1286
libMesh::GMVIO
This class implements writing meshes in the GMV format.
Definition: gmv_io.h:54
libMesh::NewtonSolver::linear_tolerance_multiplier
double linear_tolerance_multiplier
The tolerance for linear solves is kept below this multiplier (which defaults to 1e-3) times the norm...
Definition: newton_solver.h:143
libMesh::ExodusII_IO
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition: exodusII_io.h:51
libMesh::WeightedPatchRecoveryErrorEstimator::weight_functions
std::vector< FEMFunctionBase< Number > * > weight_functions
Vector of fem function base pointers, the user will fill this in with pointers to the appropriate wei...
Definition: weighted_patch_recovery_error_estimator.h:83
FEMParameters::timesolver_core
std::string timesolver_core
Definition: femparameters.h:37
FEMParameters::solver_quiet
bool solver_quiet
Definition: femparameters.h:128
FEMParameters::write_gmv_error
bool write_gmv_error
Definition: femparameters.h:68
FEMParameters::require_residual_reduction
bool require_residual_reduction
Definition: femparameters.h:128
FEMParameters::coarsen_threshold
libMesh::Real coarsen_threshold
Definition: femparameters.h:61
libMesh::ConstFEMFunction
FEMFunction that returns a single value, regardless of the time and location inputs.
Definition: const_fem_function.h:45
libMesh::WeightedPatchRecoveryErrorEstimator
This class implements the Patch Recovery error indicator.
Definition: weighted_patch_recovery_error_estimator.h:47
FEMParameters::run_simulation
bool run_simulation
Definition: femparameters.h:104
FEMParameters::max_linear_iterations
unsigned int max_linear_iterations
Definition: femparameters.h:131
libMesh::FEMSystem
This class provides a specific system class.
Definition: fem_system.h:53
libMesh::DifferentiableSystem::time_solver
std::unique_ptr< TimeSolver > time_solver
A pointer to the solver object we're going to use.
Definition: diff_system.h:233
libMesh::NumericVector< Number >
libMesh::Euler2Solver
This class defines a theta-method (defaulting to Backward Euler with theta = 1.0) solver to handle ti...
Definition: euler2_solver.h:48
FEMParameters::indicator_type
std::string indicator_type
Definition: femparameters.h:145
FEMParameters::refine_uniformly
bool refine_uniformly
Definition: femparameters.h:144
libMesh::TriangleWrapper::init
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
start_output
void start_output(unsigned int timesteps, std::string filename, std::string varname)
Definition: output.C:11
libMesh::MeshRefinement
Implements (adaptive) mesh refinement algorithms for a MeshBase.
Definition: mesh_refinement.h:61
libMesh::libmesh_assert
libmesh_assert(ctx)
FEMParameters::print_solutions
bool print_solutions
Definition: femparameters.h:118
libMesh::TwostepTimeSolver
This class wraps another UnsteadySolver derived class, and compares the results of timestepping with ...
Definition: twostep_time_solver.h:50
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::EquationSystems::n_active_dofs
std::size_t n_active_dofs() const
Definition: equation_systems.C:1362
libMesh::DiffSolver::minimum_linear_tolerance
double minimum_linear_tolerance
The tolerance for linear solves is kept above this minimum.
Definition: diff_solver.h:215
FEMParameters::transient
bool transient
Definition: femparameters.h:35
FEMParameters::max_adaptivesteps
unsigned int max_adaptivesteps
Definition: femparameters.h:62
FEMParameters::output_bz2
bool output_bz2
Definition: femparameters.h:68
libMesh::UnsteadySolver
This is a generic class that defines a solver to handle time integration of DifferentiableSystems.
Definition: unsteady_solver.h:48
libMesh::DiffSolver::relative_step_tolerance
Real relative_step_tolerance
Definition: diff_solver.h:204
libMesh::DiffSolver::verbose
bool verbose
The DiffSolver may print a lot more to libMesh::out if verbose is set to true; default is false.
Definition: diff_solver.h:168
libMesh::AdaptiveTimeSolver::core_time_solver
std::unique_ptr< UnsteadySolver > core_time_solver
This object is used to take timesteps.
Definition: adaptive_time_solver.h:114
libMesh::FEMSystem::postprocess
virtual void postprocess() override
Runs a postprocessing loop over all elements, and if postprocess_sides is true over all sides.
Definition: fem_system.C:1097
libMesh::AdaptiveTimeSolver::component_norm
SystemNorm component_norm
Error calculations are done in this norm, DISCRETE_L2 by default.
Definition: adaptive_time_solver.h:119
libMesh::ParallelObject::processor_id
processor_id_type processor_id() const
Definition: parallel_object.h:106
FEMParameters::output_xdr
bool output_xdr
Definition: femparameters.h:68
libMesh::EquationSystems::READ_DATA
Definition: equation_systems.h:84
libMesh::DifferentiableSystem::print_jacobians
bool print_jacobians
Set print_jacobians to true to print J whenever it is assembled.
Definition: diff_system.h:346
build_error_estimator
std::unique_ptr< ErrorEstimator > build_error_estimator(FEMParameters &param, QoISet &qois)
Definition: adjoints_ex1.C:239
libMesh::DiffSolver::continue_after_max_iterations
bool continue_after_max_iterations
Defaults to true, telling the DiffSolver to continue rather than exit when a solve has reached its ma...
Definition: diff_solver.h:174
coupled_system.h
write_output_footers
void write_output_footers(FEMParameters &param)
Definition: adjoints_ex3.C:309
libMesh::DifferentiableSystem::get_linear_solver
virtual LinearSolver< Number > * get_linear_solver() const override
Definition: diff_system.C:175
FEMParameters::absolute_residual_tolerance
libMesh::Real absolute_residual_tolerance
Definition: femparameters.h:132
libMesh::AdaptiveTimeSolver::max_growth
Real max_growth
Do not allow the adaptive time solver to select a new deltat greater than max_growth times the old de...
Definition: adaptive_time_solver.h:181
FEMParameters::relative_residual_tolerance
libMesh::Real relative_residual_tolerance
Definition: femparameters.h:132
libMesh::ErrorVector
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
Definition: error_vector.h:50
libMesh::H1_X_SEMINORM
Definition: enum_norm_type.h:57
FEMParameters::relative_step_tolerance
libMesh::Real relative_step_tolerance
Definition: femparameters.h:132
libMesh::DifferentiableSystem::adjoint_solve
virtual std::pair< unsigned int, Real > adjoint_solve(const QoISet &qoi_indices=QoISet()) override
This function sets the _is_adjoint boolean member of TimeSolver to true and then calls the adjoint_so...
Definition: diff_system.C:164
FEMParameters::minimum_linear_tolerance
double minimum_linear_tolerance
Definition: femparameters.h:134
libMesh::LibMeshInit
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:83
write_output_headers
void write_output_headers(FEMParameters &param)
Definition: adjoints_ex3.C:248
libMesh::NewtonSolver
This class defines a solver which uses the default libMesh linear solver in a quasiNewton method to h...
Definition: newton_solver.h:46
main
int main(int argc, char **argv)
Definition: adaptivity_ex1.C:60
libMesh::EquationSystems::n_systems
unsigned int n_systems() const
Definition: equation_systems.h:652
libMesh::MeshRefinement::nelem_target
dof_id_type & nelem_target()
If nelem_target is set to a nonzero value, methods like flag_elements_by_nelem_target() will attempt ...
Definition: mesh_refinement.h:903
libMesh::READ
Definition: enum_xdr_mode.h:41
FEMParameters::print_element_solutions
bool print_element_solutions
Definition: femparameters.h:118
libMesh::EquationSystems::read
void read(const std::string &name, const XdrMODE, const unsigned int read_flags=(READ_HEADER|READ_DATA), bool partition_agnostic=true)
Read & initialize the systems from disk using the XDR data format.
Definition: equation_systems_io.C:90
libMesh::EquationSystems
This is the EquationSystems class.
Definition: equation_systems.h:74
libMesh::System::time
Real time
For time-dependent problems, this is the time t at the beginning of the current timestep.
Definition: system.h:1561
libMesh::MeshOutput::write_equation_systems
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
This method implements writing a mesh with data to a specified file where the data is taken from the ...
Definition: mesh_output.C:31
libMesh::MeshBase::renumber_nodes_and_elements
virtual void renumber_nodes_and_elements()=0
After partitioning a mesh it is useful to renumber the nodes and elements so that they lie in contigu...
libMesh::DiffSolver::quiet
bool quiet
The DiffSolver should not print anything to libMesh::out unless quiet is set to false; default is tru...
Definition: diff_solver.h:162
libMesh::DifferentiableQoI::assemble_qoi_sides
bool assemble_qoi_sides
If assemble_qoi_sides is true (it is false by default), the assembly loop for a quantity of interest ...
Definition: diff_qoi.h:85
libMesh::AdjointResidualErrorEstimator::dual_error_estimator
std::unique_ptr< ErrorEstimator > & dual_error_estimator()
Access to the "subestimator" (default: PatchRecovery) to use on the dual/adjoint solution.
Definition: adjoint_residual_error_estimator.h:83
write_output
void write_output(EquationSystems &es, unsigned int t_step, unsigned int a_step, std::string solution_type, FEMParameters &param)
Definition: adjoints_ex3.C:149
write_error
void write_error(EquationSystems &es, ErrorVector &error, unsigned int t_number, unsigned int a_number, FEMParameters &param, std::string error_type) void write_error(EquationSystems &
FEMParameters::timesolver_theta
libMesh::Real timesolver_theta
Definition: femparameters.h:38
libMesh::MeshRefinement::coarsen_fraction
Real & coarsen_fraction()
The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for...
Definition: mesh_refinement.h:885
libMesh::DiffSolver::relative_residual_tolerance
Real relative_residual_tolerance
Definition: diff_solver.h:192
FEMParameters::global_tolerance
libMesh::Real global_tolerance
Definition: femparameters.h:60
libMesh::System::solution
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1539
libMesh::PatchRecoveryErrorEstimator::set_patch_reuse
void set_patch_reuse(bool)
Definition: patch_recovery_error_estimator.C:58
libMesh::MeshRefinement::refine_fraction
Real & refine_fraction()
The refine_fraction sets either a desired target or a desired maximum number of elements to flag for ...
Definition: mesh_refinement.h:879
FEMParameters::min_step_length
libMesh::Real min_step_length
Definition: femparameters.h:130
FEMParameters::read
void read(GetPot &input, const std::vector< std::string > *other_variable_names=nullptr)
Definition: femparameters.C:154
FEMParameters::extra_quadrature_order
int extra_quadrature_order
Definition: femparameters.h:110
FEMParameters::patch_reuse
bool patch_reuse
Definition: femparameters.h:146
libMesh::DiffSolver::absolute_residual_tolerance
Real absolute_residual_tolerance
The DiffSolver should exit after the residual is reduced to either less than absolute_residual_tolera...
Definition: diff_solver.h:191
domain.h
libMesh::FEMSystem::verify_analytic_jacobians
Real verify_analytic_jacobians
If verify_analytic_jacobian is equal to zero (as it is by default), no numeric jacobians will be calc...
Definition: fem_system.h:209
FEMParameters::deltat
libMesh::Real deltat
Definition: femparameters.h:38
libMesh::MeshBase::print_info
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the mesh.
Definition: mesh_base.C:585
libMesh::TecplotIO
This class implements writing meshes in the Tecplot format.
Definition: tecplot_io.h:43
libMesh::LinearSolver< Number >
CoupledFEMFunctionsy
Definition: coupled_system.h:138
libMesh::DiffSolver::max_linear_iterations
unsigned int max_linear_iterations
Each linear solver step should exit after max_linear_iterations is exceeded.
Definition: diff_solver.h:148
libMesh::MeshRefinement::absolute_global_tolerance
Real & absolute_global_tolerance()
If absolute_global_tolerance is set to a nonzero value, methods like flag_elements_by_global_toleranc...
Definition: mesh_refinement.h:909
libMesh::Euler2Solver::theta
Real theta
The value for the theta method to employ: 1.0 corresponds to backwards Euler, 0.0 corresponds to forw...
Definition: euler2_solver.h:105
libMesh::L2
Definition: enum_norm_type.h:36
libMesh::EquationSystems::write
void write(const std::string &name, const XdrMODE, const unsigned int write_flags=(WRITE_DATA), bool partition_agnostic=true) const
Write the systems to disk using the XDR data format.
Definition: equation_systems_io.C:378
libMesh::FEMSystem::assemble_qoi
virtual void assemble_qoi(const QoISet &indices=QoISet()) override
Runs a qoi assembly loop over all elements, and if assemble_qoi_sides is true over all sides.
Definition: fem_system.C:1117
libMesh::MeshRefinement::coarsen_by_parents
bool & coarsen_by_parents()
If coarsen_by_parents is true, complete groups of sibling elements (elements with the same parent) wi...
Definition: mesh_refinement.h:873
libMesh::DifferentiableSystem::print_solutions
bool print_solutions
Set print_solutions to true to print U whenever it is used in an assembly() call.
Definition: diff_system.h:326
FEMParameters::verify_analytic_jacobians
libMesh::Real verify_analytic_jacobians
Definition: femparameters.h:115
libMesh::SystemNorm
This class defines a norm/seminorm to be applied to a NumericVector which contains coefficients in a ...
Definition: system_norm.h:51
FEMParameters::print_jacobian_norms
bool print_jacobian_norms
Definition: femparameters.h:118
libMesh::EquationSystems::WRITE_ADDITIONAL_DATA
Definition: equation_systems.h:94
libMesh::PetscDiffSolver
This class defines a solver which uses a PETSc SNES context to handle a DifferentiableSystem.
Definition: petsc_diff_solver.h:55
FEMParameters::write_tecplot_error
bool write_tecplot_error
Definition: femparameters.h:68
FEMParameters
Definition: femparameters.h:22
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::DiffSolver::max_nonlinear_iterations
unsigned int max_nonlinear_iterations
The DiffSolver should exit in failure if max_nonlinear_iterations is exceeded and continue_after_max_...
Definition: diff_solver.h:156
FEMParameters::deltat_reductions
unsigned int deltat_reductions
Definition: femparameters.h:36
FEMParameters::nelem_target
unsigned int nelem_target
Definition: femparameters.h:59
FEMParameters::linear_tolerance_multiplier
double linear_tolerance_multiplier
Definition: femparameters.h:134
FEMParameters::output_tecplot
bool output_tecplot
Definition: femparameters.h:68
libMesh::NewtonSolver::minsteplength
Real minsteplength
If the quasi-Newton step length must be reduced to below this factor to give a residual reduction,...
Definition: newton_solver.h:137
libMesh::out
OStreamProxy out
libMesh::DifferentiableSystem::print_element_residuals
bool print_element_residuals
Set print_element_residuals to true to print each R_elem contribution.
Definition: diff_system.h:356
libMesh::global_processor_id
processor_id_type global_processor_id()
Definition: libmesh_base.h:85
FEMParameters::output_gz
bool output_gz
Definition: femparameters.h:68
H-qoi.h
FEMParameters::timesolver_upper_tolerance
libMesh::Real timesolver_upper_tolerance
Definition: femparameters.h:38
build_mesh_refinement
std::unique_ptr< MeshRefinement > build_mesh_refinement(MeshBase &mesh, FEMParameters &param)
Definition: adjoints_ex1.C:216
libMesh::System::update
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:408
FEMParameters::print_element_residuals
bool print_element_residuals
Definition: femparameters.h:118
libMesh::SystemNorm::set_weight
void set_weight(unsigned int var, Real w)
Sets the weight corresponding to the norm in variable var.
Definition: system_norm.C:141
libMesh::AdjointResidualErrorEstimator
This class implements a goal oriented error indicator, by weighting residual-based estimates from the...
Definition: adjoint_residual_error_estimator.h:49
libMesh::AdaptiveTimeSolver::target_tolerance
Real target_tolerance
This tolerance is the target relative error between an exact time integration and a single time step ...
Definition: adaptive_time_solver.h:144
libMesh::AdjointResidualErrorEstimator::primal_error_estimator
std::unique_ptr< ErrorEstimator > & primal_error_estimator()
Access to the "subestimator" (default: PatchRecovery) to use on the primal/forward solution.
Definition: adjoint_residual_error_estimator.h:77
build_domain
void build_domain(MeshBase &mesh, FEMParameters &param)
Definition: domain.C:10
FEMParameters::time_solver_quiet
bool time_solver_quiet
Definition: femparameters.h:128
libMesh::MeshBase::n_active_elem
virtual dof_id_type n_active_elem() const =0
libMesh::EquationSystems::READ_HEADER
Definition: equation_systems.h:83
output.h
FEMParameters::initial_timestep
unsigned int initial_timestep
Definition: femparameters.h:34
CoupledFEMFunctionsx
Definition: coupled_system.h:107
build_system
FEMSystem & build_system(EquationSystems &es, GetPot &, FEMParameters &)
Definition: mysystems.h:7
libMesh::DiffSolver::initial_linear_tolerance
double initial_linear_tolerance
Any required linear solves will at first be done with this tolerance; the DiffSolver may tighten the ...
Definition: diff_solver.h:210
libMesh::System::set_adjoint_already_solved
void set_adjoint_already_solved(bool setting)
Setter for the adjoint_already_solved boolean.
Definition: system.h:402