libMesh
Functions
adjoints_ex1.C File Reference

Go to the source code of this file.

Functions

void write_output (EquationSystems &es, unsigned int a_step, std::string solution_type, FEMParameters &param)
 
void set_system_parameters (LaplaceSystem &system, FEMParameters &param)
 
std::unique_ptr< MeshRefinementbuild_mesh_refinement (MeshBase &mesh, const FEMParameters &param)
 
std::unique_ptr< ErrorEstimatorbuild_error_estimator (const FEMParameters &param, const QoISet &qois)
 
int main (int argc, char **argv)
 

Function Documentation

◆ build_error_estimator()

std::unique_ptr<ErrorEstimator> build_error_estimator ( const FEMParameters param,
const QoISet qois 
)

Definition at line 250 of file adjoints_ex1.C.

References libMesh::H1_SEMINORM, FEMParameters::indicator_type, libMesh::out, and FEMParameters::patch_reuse.

Referenced by main().

252 {
253  if (param.indicator_type == "kelly")
254  {
255  libMesh::out << "Using Kelly Error Estimator" << std::endl;
256 
257  return std::make_unique<KellyErrorEstimator>();
258  }
259  else if (param.indicator_type == "adjoint_residual")
260  {
261  libMesh::out << "Using Adjoint Residual Error Estimator with Patch Recovery Weights" << std::endl;
262 
263  auto adjoint_residual_estimator = std::make_unique<AdjointResidualErrorEstimator>();
264 
265  adjoint_residual_estimator->qoi_set() = qois;
266  adjoint_residual_estimator->error_plot_suffix = "error.gmv";
267 
268  adjoint_residual_estimator->primal_error_estimator() = std::make_unique<PatchRecoveryErrorEstimator>();
269  auto p1 = cast_ptr<PatchRecoveryErrorEstimator *>(adjoint_residual_estimator->primal_error_estimator().get());
270  p1->error_norm.set_type(0, H1_SEMINORM);
271  p1->set_patch_reuse(param.patch_reuse);
272 
273  adjoint_residual_estimator->dual_error_estimator() = std::make_unique<PatchRecoveryErrorEstimator>();
274  auto p2 = cast_ptr<PatchRecoveryErrorEstimator *>(adjoint_residual_estimator->dual_error_estimator().get());
275  p2->error_norm.set_type(0, H1_SEMINORM);
276  p2->set_patch_reuse(param.patch_reuse);
277 
278  return adjoint_residual_estimator;
279  }
280  else
281  libmesh_error_msg("Unknown indicator_type = " << param.indicator_type);
282 }
std::string indicator_type
OStreamProxy out

◆ build_mesh_refinement()

std::unique_ptr<MeshRefinement> build_mesh_refinement ( MeshBase mesh,
const FEMParameters param 
)

Definition at line 227 of file adjoints_ex1.C.

References FEMParameters::coarsen_fraction, FEMParameters::coarsen_threshold, FEMParameters::global_tolerance, mesh, FEMParameters::nelem_target, and FEMParameters::refine_fraction.

Referenced by main().

229 {
230  auto mesh_refinement = std::make_unique<MeshRefinement>(mesh);
231  mesh_refinement->coarsen_by_parents() = true;
232  mesh_refinement->absolute_global_tolerance() = param.global_tolerance;
233  mesh_refinement->nelem_target() = param.nelem_target;
234  mesh_refinement->refine_fraction() = param.refine_fraction;
235  mesh_refinement->coarsen_fraction() = param.coarsen_fraction;
236  mesh_refinement->coarsen_threshold() = param.coarsen_threshold;
237 
238  return mesh_refinement;
239 }
unsigned int nelem_target
Definition: femparameters.h:60
MeshBase & mesh
libMesh::Real refine_fraction
Definition: femparameters.h:62
libMesh::Real coarsen_threshold
Definition: femparameters.h:62
libMesh::Real global_tolerance
Definition: femparameters.h:61
libMesh::Real coarsen_fraction
Definition: femparameters.h:62

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 285 of file adjoints_ex1.C.

References libMesh::QoISet::add_indices(), libMesh::EquationSystems::add_system(), libMesh::DifferentiableSystem::adjoint_solve(), libMesh::MeshBase::all_second_order(), libMesh::DifferentiableQoI::assemble_qoi_sides, libMesh::Factory< Base >::build(), build_error_estimator(), build_mesh_refinement(), libMesh::default_solver_package(), libMesh::err, libMesh::System::get_adjoint_solution(), libMesh::DifferentiableSystem::get_linear_solver(), LaplaceSystem::get_QoI_value(), libMesh::TriangleWrapper::init(), libMesh::EquationSystems::init(), libMesh::INVALID_SOLVER_PACKAGE, libMesh::MeshBase::is_replicated(), mesh, libMesh::EquationSystems::n_active_dofs(), libMesh::MeshBase::n_active_elem(), libMesh::out, libMesh::MeshBase::partitioner(), LaplaceSystem::postprocess(), libMesh::DifferentiableSystem::postprocess_sides, libMesh::EquationSystems::print_info(), libMesh::MeshBase::print_info(), libMesh::ParallelObject::processor_id(), libMesh::BasicOStreamProxy< charT, traits >::rdbuf(), FEMParameters::read(), libMesh::MeshBase::read(), libMesh::EquationSystems::reinit(), libMesh::LinearSolver< T >::reuse_preconditioner(), libMesh::System::set_adjoint_already_solved(), set_system_parameters(), libMesh::QoISet::set_weight(), libMesh::System::solution, libMesh::FEMSystem::solve(), libMesh::NumericVector< T >::swap(), libMesh::MeshRefinement::uniformly_refine(), and write_output().

286 {
287  // Initialize libMesh.
288  LibMeshInit init (argc, argv);
289 
290  // This example requires a linear solver package.
291  libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
292  "--enable-petsc, --enable-trilinos, or --enable-eigen");
293 
294  // This example relies on exceptions to control which Partitioner gets built.
295 #ifndef LIBMESH_ENABLE_EXCEPTIONS
296  libmesh_example_requires(false, "--enable-exceptions");
297 #endif
298 
299  // Skip adaptive examples on a non-adaptive libMesh build
300 #ifndef LIBMESH_ENABLE_AMR
301  libmesh_example_requires(false, "--enable-amr");
302 #else
303 
304  libMesh::out << "Started " << argv[0] << std::endl;
305 
306  // Make sure the general input file exists, and parse it
307  {
308  std::ifstream i("general.in");
309  libmesh_error_msg_if(!i, '[' << init.comm().rank() << "] Can't find general.in; exiting early.");
310  }
311 
312  // Read in parameters from the input file
313  GetPot infile("general.in");
314 
315  // But allow the command line to override it.
316  infile.parse_command_line(argc, argv);
317 
318  FEMParameters param(init.comm());
319  param.read(infile);
320 
321  // Skip this default-2D example if libMesh was compiled as 1D-only.
322  libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");
323 
324  // Create a mesh, with dimension to be overridden later, distributed
325  // across the default MPI communicator.
326  Mesh mesh(init.comm());
327 
328  // Give the mesh a non-default partitioner if we can try to do so
329  // safely
330  if (param.mesh_partitioner_type != "Default")
331  {
332 #if !defined(LIBMESH_HAVE_RTTI) || !defined(LIBMESH_ENABLE_EXCEPTIONS)
333  libmesh_example_requires(false, "RTTI + exceptions support");
334 #else
335  // Factory failures are *verbose* in parallel; let's silence
336  // cerr temporarily.
337  auto oldbuf = libMesh::err.rdbuf();
338  libMesh::err.rdbuf(nullptr);
339  try
340  {
341  // Many partitioners won't work on a distributed Mesh, and
342  // even a currently serialized DistributedMesh won't stay
343  // that way through AMR/C
344  if (!mesh.is_replicated() &&
345  (param.mesh_partitioner_type == "Centroid" ||
346  param.mesh_partitioner_type == "Hilbert" ||
347  param.mesh_partitioner_type == "Morton" ||
348  param.mesh_partitioner_type == "SFCurves" ||
349  param.mesh_partitioner_type == "Metis"))
350  libmesh_example_requires(false, "--disable-parmesh");
351 
352  mesh.partitioner() =
353  Factory<Partitioner>::build(param.mesh_partitioner_type);
354  }
355  catch (...)
356  {
357  libmesh_example_requires(false, param.mesh_partitioner_type + " partitioner support");
358  }
359  libMesh::err.rdbuf(oldbuf);
360 #endif // LIBMESH_HAVE_RTTI, LIBMESH_ENABLE_EXCEPTIONS
361  }
362 
363  // And an object to refine it
364  std::unique_ptr<MeshRefinement> mesh_refinement =
365  build_mesh_refinement(mesh, param);
366 
367  // And an EquationSystems to run on it
368  EquationSystems equation_systems (mesh);
369 
370  libMesh::out << "Reading in and building the mesh" << std::endl;
371 
372  // Read in the mesh
373  mesh.read(param.domainfile.c_str());
374  // Make all the elements of the mesh second order so we can compute
375  // with a higher order basis
377 
378  // Create a mesh refinement object to do the initial uniform refinements
379  // on the coarse grid read in from lshaped.xda
380  MeshRefinement initial_uniform_refinements(mesh);
381  initial_uniform_refinements.uniformly_refine(param.coarserefinements);
382 
383  libMesh::out << "Building system" << std::endl;
384 
385  // Build the FEMSystem
386  LaplaceSystem & system = equation_systems.add_system<LaplaceSystem> ("LaplaceSystem");
387 
388  // Set its parameters
389  set_system_parameters(system, param);
390 
391  libMesh::out << "Initializing systems" << std::endl;
392 
393  equation_systems.init ();
394 
395  // Print information about the mesh and system to the screen.
396  mesh.print_info();
397  equation_systems.print_info();
398  LinearSolver<Number> * linear_solver = system.get_linear_solver();
399 
400  {
401  // Adaptively solve the timestep
402  unsigned int a_step = 0;
403  for (; a_step != param.max_adaptivesteps; ++a_step)
404  {
405  // We can't adapt to both a tolerance and a
406  // target mesh size
407  if (param.global_tolerance != 0.)
408  libmesh_assert_equal_to (param.nelem_target, 0);
409  // If we aren't adapting to a tolerance we need a
410  // target mesh size
411  else
412  libmesh_assert_greater (param.nelem_target, 0);
413 
414  linear_solver->reuse_preconditioner(false);
415 
416  // Solve the forward problem
417  system.solve();
418 
419  // Write out the computed primal solution
420  write_output(equation_systems, a_step, "primal", param);
421 
422  // Get a pointer to the primal solution vector
423  NumericVector<Number> & primal_solution = *system.solution;
424 
425  // Declare a QoISet object, we need this object to set weights for our QoI error contributions
426  QoISet qois;
427 
428  // Each index will correspond to a QoI
429  qois.add_indices({0,1});
430 
431  // Set weights for each index, these will weight the contribution of each QoI in the final error
432  // estimate to be used for flagging elements for refinement
433  qois.set_weight(0, 0.5);
434  qois.set_weight(1, 0.5);
435 
436  // Make sure we get the contributions to the adjoint RHS from the sides
437  system.assemble_qoi_sides = true;
438 
439  // We are about to solve the adjoint system, but before we do this we see the same preconditioner
440  // flag to reuse the preconditioner from the forward solver
441  linear_solver->reuse_preconditioner(param.reuse_preconditioner);
442 
443  // Solve the adjoint system. This takes the transpose of the stiffness matrix and then
444  // solves the resulting system
445  system.adjoint_solve();
446 
447  // Now that we have solved the adjoint, set the adjoint_already_solved boolean to true, so we dont solve unnecessarily in the error estimator
448  system.set_adjoint_already_solved(true);
449 
450  // Get a pointer to the solution vector of the adjoint problem for QoI 0
451  NumericVector<Number> & dual_solution_0 = system.get_adjoint_solution(0);
452 
453  // Swap the primal and dual solutions so we can write out the adjoint solution
454  primal_solution.swap(dual_solution_0);
455  write_output(equation_systems, a_step, "adjoint_0", param);
456 
457  // Swap back
458  primal_solution.swap(dual_solution_0);
459 
460  // Get a pointer to the solution vector of the adjoint problem for QoI 0
461  NumericVector<Number> & dual_solution_1 = system.get_adjoint_solution(1);
462 
463  // Swap again
464  primal_solution.swap(dual_solution_1);
465  write_output(equation_systems, a_step, "adjoint_1", param);
466 
467  // Swap back again
468  primal_solution.swap(dual_solution_1);
469 
470  libMesh::out << "Adaptive step "
471  << a_step
472  << ", we have "
473  << mesh.n_active_elem()
474  << " active elements and "
475  << equation_systems.n_active_dofs()
476  << " active dofs."
477  << std::endl;
478 
479  // Postprocess, compute the approximate QoIs and write them out to the console
480  libMesh::out << "Postprocessing: " << std::endl;
481  system.postprocess_sides = true;
482  system.postprocess();
483  Number QoI_0_computed = system.get_QoI_value("computed", 0);
484  Number QoI_0_exact = system.get_QoI_value("exact", 0);
485  Number QoI_1_computed = system.get_QoI_value("computed", 1);
486  Number QoI_1_exact = system.get_QoI_value("exact", 1);
487 
488  libMesh::out << "The relative error in QoI 0 is "
489  << std::setprecision(17)
490  << std::abs(QoI_0_computed - QoI_0_exact) / std::abs(QoI_0_exact)
491  << std::endl;
492 
493  libMesh::out << "The relative error in QoI 1 is "
494  << std::setprecision(17)
495  << std::abs(QoI_1_computed - QoI_1_exact) / std::abs(QoI_1_exact)
496  << std::endl
497  << std::endl;
498 
499  // Now we construct the data structures for the mesh refinement process
500  ErrorVector error;
501 
502  // Build an error estimator object
503  std::unique_ptr<ErrorEstimator> error_estimator =
504  build_error_estimator(param, qois);
505 
506  // Estimate the error in each element using the Adjoint Residual or Kelly error estimator
507  error_estimator->estimate_error(system, error);
508 
509  // We have to refine either based on reaching an error tolerance or
510  // a number of elements target, which should be verified above
511  // Otherwise we flag elements by error tolerance or nelem target
512 
513  // Uniform refinement
514  if (param.refine_uniformly)
515  {
516  mesh_refinement->uniformly_refine(1);
517  }
518  // Adaptively refine based on reaching an error tolerance
519  else if (param.global_tolerance >= 0. && param.nelem_target == 0.)
520  {
521  mesh_refinement->flag_elements_by_error_tolerance (error);
522 
523  mesh_refinement->refine_and_coarsen_elements();
524  }
525  // Adaptively refine based on reaching a target number of elements
526  else
527  {
528  if (mesh.n_active_elem() >= param.nelem_target)
529  {
530  libMesh::out << "We reached the target number of elements." << std::endl << std::endl;
531  break;
532  }
533 
534  mesh_refinement->flag_elements_by_nelem_target (error);
535 
536  mesh_refinement->refine_and_coarsen_elements();
537  }
538 
539  // Dont forget to reinit the system after each adaptive refinement !
540  equation_systems.reinit();
541 
542  libMesh::out << "Refined mesh to "
543  << mesh.n_active_elem()
544  << " active elements and "
545  << equation_systems.n_active_dofs()
546  << " active dofs."
547  << std::endl;
548  }
549 
550  // Do one last solve if necessary
551  if (a_step == param.max_adaptivesteps)
552  {
553  linear_solver->reuse_preconditioner(false);
554  system.solve();
555 
556  write_output(equation_systems, a_step, "primal", param);
557 
558  NumericVector<Number> & primal_solution = *system.solution;
559 
560  QoISet qois;
561  std::vector<unsigned int> qoi_indices;
562 
563  qoi_indices.push_back(0);
564  qoi_indices.push_back(1);
565  qois.add_indices(qoi_indices);
566 
567  qois.set_weight(0, 0.5);
568  qois.set_weight(1, 0.5);
569 
570  system.assemble_qoi_sides = true;
571  linear_solver->reuse_preconditioner(param.reuse_preconditioner);
572  system.adjoint_solve();
573 
574  // Now that we have solved the adjoint, set the adjoint_already_solved boolean to true, so we dont solve unnecessarily in the error estimator
575  system.set_adjoint_already_solved(true);
576 
577  NumericVector<Number> & dual_solution_0 = system.get_adjoint_solution(0);
578 
579  primal_solution.swap(dual_solution_0);
580  write_output(equation_systems, a_step, "adjoint_0", param);
581 
582  primal_solution.swap(dual_solution_0);
583 
584  NumericVector<Number> & dual_solution_1 = system.get_adjoint_solution(1);
585 
586  primal_solution.swap(dual_solution_1);
587  write_output(equation_systems, a_step, "adjoint_1", param);
588 
589  primal_solution.swap(dual_solution_1);
590 
591  libMesh::out << "Adaptive step "
592  << a_step
593  << ", we have "
594  << mesh.n_active_elem()
595  << " active elements and "
596  << equation_systems.n_active_dofs()
597  << " active dofs."
598  << std::endl;
599 
600  libMesh::out << "Postprocessing: " << std::endl;
601  system.postprocess_sides = true;
602  system.postprocess();
603 
604  Number QoI_0_computed = system.get_QoI_value("computed", 0);
605  Number QoI_0_exact = system.get_QoI_value("exact", 0);
606  Number QoI_1_computed = system.get_QoI_value("computed", 1);
607  Number QoI_1_exact = system.get_QoI_value("exact", 1);
608 
609  libMesh::out << "The relative error in QoI 0 is "
610  << std::setprecision(17)
611  << std::abs(QoI_0_computed - QoI_0_exact) / std::abs(QoI_0_exact)
612  << std::endl;
613 
614  libMesh::out << "The relative error in QoI 1 is "
615  << std::setprecision(17)
616  << std::abs(QoI_1_computed - QoI_1_exact) / std::abs(QoI_1_exact)
617  << std::endl
618  << std::endl;
619 
620  // Hard coded asserts to ensure that the actual numbers we are getting are what they should be
621  if (param.max_adaptivesteps > 5 && param.coarserefinements > 2)
622  {
623  libmesh_assert_less(std::abs(QoI_0_computed - QoI_0_exact)/std::abs(QoI_0_exact), 4.e-5);
624  libmesh_assert_less(std::abs(QoI_1_computed - QoI_1_exact)/std::abs(QoI_1_exact), 1.e-4);
625  }
626  else
627  {
628  // This seems to be loose enough for the case of 2 coarse
629  // refinements, 4 adaptive steps
630  libmesh_assert_less(std::abs(QoI_0_computed - QoI_0_exact)/std::abs(QoI_0_exact), 4.e-4);
631  libmesh_assert_less(std::abs(QoI_1_computed - QoI_1_exact)/std::abs(QoI_1_exact), 2.e-3);
632  }
633  }
634  }
635 
636  libMesh::err << '[' << mesh.processor_id()
637  << "] Completing output."
638  << std::endl;
639 
640 #endif // #ifndef LIBMESH_ENABLE_AMR
641 
642  // All done.
643  return 0;
644 }
OStreamProxy err
This is the EquationSystems class.
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.
void set_weight(std::size_t, Real)
Set the weight for this index.
Definition: qoi_set.h:232
virtual dof_id_type n_active_elem() const =0
void write_output(EquationSystems &es, unsigned int a_step, std::string solution_type, FEMParameters &param)
Definition: adjoints_ex1.C:102
void set_adjoint_already_solved(bool setting)
Setter for the adjoint_already_solved boolean.
Definition: system.h:415
Data structure for specifying which Quantities of Interest should be calculated in an adjoint or a pa...
Definition: qoi_set.h:45
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
Definition: error_vector.h:50
Number & get_QoI_value(std::string type, unsigned int QoI_index)
Definition: L-shaped.h:32
MeshBase & mesh
virtual std::unique_ptr< Partitioner > & partitioner()
A partitioner to use at each prepare_for_use()
Definition: mesh_base.h:160
bool postprocess_sides
If postprocess_sides is true (it is false by default), the postprocessing loop will loop over all sid...
Definition: diff_system.h:334
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:90
void set_system_parameters(LaplaceSystem &system, FEMParameters &param)
Definition: adjoints_ex1.C:163
SolverPackage default_solver_package()
Definition: libmesh.C:1117
Factory class definition.
Definition: factory.h:46
Implements (adaptive) mesh refinement algorithms for a MeshBase.
std::unique_ptr< ErrorEstimator > build_error_estimator(const FEMParameters &param, const QoISet &qois)
Definition: adjoints_ex1.C:250
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
Definition: mesh_base.C:1562
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1593
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
void read(GetPot &input, const std::vector< std::string > *other_variable_names=nullptr)
std::unique_ptr< MeshRefinement > build_mesh_refinement(MeshBase &mesh, const FEMParameters &param)
Definition: adjoints_ex1.C:227
streambufT * rdbuf() const
Get the associated stream buffer.
virtual LinearSolver< Number > * get_linear_solver() const override
Definition: diff_system.C:163
virtual void reuse_preconditioner(bool)
Set the same_preconditioner flag, which indicates if we reuse the same preconditioner for subsequent ...
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
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:99
OStreamProxy out
virtual bool is_replicated() const
Definition: mesh_base.h:233
void add_indices(const std::vector< unsigned int > &indices)
Add this indices to the set to be calculated.
Definition: qoi_set.C:46
void all_second_order(const bool full_ordered=true)
Calls the range-based version of this function with a range consisting of all elements in the mesh...
Definition: mesh_base.C:1608
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
Definition: system.C:1245
virtual void solve() override
Invokes the solver associated with the system.
Definition: fem_system.C:1076
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
processor_id_type processor_id() const
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:150
virtual void postprocess()
Runs a postprocessing loop over all elements, and if postprocess_sides is true over all sides...
Definition: L-shaped.C:168

◆ set_system_parameters()

void set_system_parameters ( LaplaceSystem system,
FEMParameters param 
)

Definition at line 163 of file adjoints_ex1.C.

References LaplaceSystem::analytic_jacobians(), FEMParameters::analytic_jacobians, FEMParameters::constrain_in_solver, LaplaceSystem::fe_family(), FEMParameters::fe_family, LaplaceSystem::fe_order(), FEMParameters::fe_order, FEMParameters::initial_linear_tolerance, FEMParameters::linear_tolerance_multiplier, FEMParameters::max_linear_iterations, FEMParameters::max_nonlinear_iterations, FEMParameters::min_step_length, FEMParameters::minimum_linear_tolerance, FEMParameters::print_jacobian_norms, libMesh::DifferentiableSystem::print_jacobian_norms, FEMParameters::print_jacobians, libMesh::DifferentiableSystem::print_jacobians, FEMParameters::print_residual_norms, libMesh::DifferentiableSystem::print_residual_norms, FEMParameters::print_residuals, libMesh::DifferentiableSystem::print_residuals, FEMParameters::print_solution_norms, libMesh::DifferentiableSystem::print_solution_norms, FEMParameters::print_solutions, libMesh::DifferentiableSystem::print_solutions, FEMParameters::relative_residual_tolerance, FEMParameters::relative_step_tolerance, FEMParameters::require_residual_reduction, libMesh::DifferentiableSystem::set_constrain_in_solver(), FEMParameters::solver_quiet, FEMParameters::solver_verbose, libMesh::DifferentiableSystem::time_solver, FEMParameters::use_petsc_snes, FEMParameters::verify_analytic_jacobians, and libMesh::FEMSystem::verify_analytic_jacobians.

Referenced by main().

165 {
166  // Use analytical jacobians?
167  system.analytic_jacobians() = param.analytic_jacobians;
168 
169  // Verify analytic jacobians against numerical ones?
171 
172  // Use the prescribed FE type
173  system.fe_family() = param.fe_family[0];
174  system.fe_order() = param.fe_order[0];
175 
176  // More desperate debugging options
178  system.print_solutions = param.print_solutions;
180  system.print_residuals = param.print_residuals;
182  system.print_jacobians = param.print_jacobians;
183 
184  // No transient time solver
185  system.time_solver = std::make_unique<SteadySolver>(system);
186 
187  // Nonlinear solver options
188  if (param.use_petsc_snes)
189  {
190 #ifdef LIBMESH_HAVE_PETSC
191  system.time_solver->diff_solver() = std::make_unique<PetscDiffSolver>(system);
192 #else
193  libmesh_error_msg("This example requires libMesh to be compiled with PETSc support.");
194 #endif
195  }
196  else
197  {
198  system.time_solver->diff_solver() = std::make_unique<NewtonSolver>(system);
199  auto solver = cast_ptr<NewtonSolver*>(system.time_solver->diff_solver().get());
200 
201  solver->quiet = param.solver_quiet;
202  solver->verbose = param.solver_verbose;
203  solver->max_nonlinear_iterations = param.max_nonlinear_iterations;
204  solver->minsteplength = param.min_step_length;
205  solver->relative_step_tolerance = param.relative_step_tolerance;
206  solver->relative_residual_tolerance = param.relative_residual_tolerance;
207  solver->require_residual_reduction = param.require_residual_reduction;
208  solver->linear_tolerance_multiplier = param.linear_tolerance_multiplier;
209  if (system.time_solver->reduce_deltat_on_diffsolver_failure)
210  {
211  solver->continue_after_max_iterations = true;
212  solver->continue_after_backtrack_failure = true;
213  }
215 
216  // And the linear solver options
217  solver->max_linear_iterations = param.max_linear_iterations;
218  solver->initial_linear_tolerance = param.initial_linear_tolerance;
219  solver->minimum_linear_tolerance = param.minimum_linear_tolerance;
220  }
221 }
bool print_solution_norms
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:215
bool analytic_jacobians
virtual void set_constrain_in_solver(bool enable)
set_constrain_in_solver to false to apply constraints only via residual terms in the systems to be so...
Definition: diff_system.C:424
bool print_jacobian_norms
Set print_jacobian_norms to true to print |J| whenever it is assembled.
Definition: diff_system.h:361
std::string & fe_family()
Definition: L-shaped.h:24
bool require_residual_reduction
std::unique_ptr< TimeSolver > time_solver
A pointer to the solver object we&#39;re going to use.
Definition: diff_system.h:253
bool print_residual_norms
libMesh::Real relative_step_tolerance
bool & analytic_jacobians()
Definition: L-shaped.h:26
bool print_jacobians
Set print_jacobians to true to print J whenever it is assembled.
Definition: diff_system.h:366
std::vector< unsigned int > fe_order
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:340
unsigned int max_linear_iterations
bool constrain_in_solver
bool print_residual_norms
Set print_residual_norms to true to print |F| whenever it is assembled.
Definition: diff_system.h:351
double minimum_linear_tolerance
std::vector< std::string > fe_family
libMesh::Real verify_analytic_jacobians
bool print_residuals
Set print_residuals to true to print F whenever it is assembled.
Definition: diff_system.h:356
double initial_linear_tolerance
bool print_solutions
Set print_solutions to true to print U whenever it is used in an assembly() call. ...
Definition: diff_system.h:346
libMesh::Real relative_residual_tolerance
unsigned int & fe_order()
Definition: L-shaped.h:25
bool print_jacobian_norms
libMesh::Real min_step_length
unsigned int max_nonlinear_iterations
double linear_tolerance_multiplier

◆ write_output()

void write_output ( EquationSystems es,
unsigned int  a_step,
std::string  solution_type,
FEMParameters param 
)

Definition at line 102 of file adjoints_ex1.C.

References libMesh::EquationSystems::get_mesh(), libMesh::libmesh_ignore(), mesh, FEMParameters::output_exodus, FEMParameters::output_gmv, libMesh::MeshOutput< MT >::write_equation_systems(), and libMesh::ExodusII_IO::write_timestep().

Referenced by main().

106 {
107  // Ignore parameters when there are no output formats available.
108  libmesh_ignore(es, a_step, solution_type, param);
109 
110 #ifdef LIBMESH_HAVE_GMV
111  if (param.output_gmv)
112  {
113  MeshBase & mesh = es.get_mesh();
114 
115  std::ostringstream file_name_gmv;
116  file_name_gmv << solution_type
117  << ".out.gmv."
118  << std::setw(2)
119  << std::setfill('0')
120  << std::right
121  << a_step;
122 
124  (file_name_gmv.str(), es);
125  }
126 #endif
127 
128 #ifdef LIBMESH_HAVE_EXODUS_API
129  if (param.output_exodus)
130  {
131  MeshBase & mesh = es.get_mesh();
132 
133  // We write out one file per adaptive step. The files are named in
134  // the following way:
135  // foo.e
136  // foo.e-s002
137  // foo.e-s003
138  // ...
139  // so that, if you open the first one with Paraview, it actually
140  // opens the entire sequence of adapted files.
141  std::ostringstream file_name_exodus;
142 
143  file_name_exodus << solution_type << ".e";
144  if (a_step > 0)
145  file_name_exodus << "-s"
146  << std::setw(3)
147  << std::setfill('0')
148  << std::right
149  << a_step + 1;
150 
151  // We write each adaptive step as a pseudo "time" step, where the
152  // time simply matches the (1-based) adaptive step we are on.
153  ExodusII_IO(mesh).write_timestep(file_name_exodus.str(),
154  es,
155  1,
156  /*time=*/a_step + 1);
157  }
158 #endif
159 }
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
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition: exodusII_io.h:52
MeshBase & mesh
This class implements writing meshes in the GMV format.
Definition: gmv_io.h:46
This is the MeshBase class.
Definition: mesh_base.h:75
void libmesh_ignore(const Args &...)
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:2017
const MeshBase & get_mesh() const