61#include "libmesh/equation_systems.h"
62#include "libmesh/linear_solver.h"
63#include "libmesh/error_vector.h"
64#include "libmesh/mesh.h"
65#include "libmesh/mesh_refinement.h"
66#include "libmesh/newton_solver.h"
67#include "libmesh/numeric_vector.h"
68#include "libmesh/petsc_diff_solver.h"
69#include "libmesh/steady_solver.h"
70#include "libmesh/system_norm.h"
71#include "libmesh/enum_solver_package.h"
74#include "libmesh/qoi_set.h"
75#include "libmesh/adjoint_refinement_estimator.h"
78#include "libmesh/getpot.h"
79#include "libmesh/gmv_io.h"
80#include "libmesh/exodusII_io.h"
83#include "femparameters.h"
97 std::string solution_type,
103#ifdef LIBMESH_HAVE_GMV
108 std::ostringstream file_name_gmv;
109 file_name_gmv << solution_type
117 (file_name_gmv.str(), es);
121#ifdef LIBMESH_HAVE_EXODUS_API
134 std::ostringstream file_name_exodus;
136 file_name_exodus << solution_type <<
".e";
138 file_name_exodus <<
"-s"
178 system.
time_solver = std::make_unique<SteadySolver>(system);
183#ifdef LIBMESH_HAVE_PETSC
184 system.
time_solver->diff_solver() = std::make_unique<PetscDiffSolver>(system);
186 libmesh_error_msg(
"This example requires libMesh to be compiled with PETSc support.");
191 system.
time_solver->diff_solver() = std::make_unique<NewtonSolver>(system);
192 auto solver = cast_ptr<NewtonSolver*>(system.
time_solver->diff_solver().get());
201 if (system.
time_solver->reduce_deltat_on_diffsolver_failure)
203 solver->continue_after_max_iterations =
true;
204 solver->continue_after_backtrack_failure =
true;
217#ifdef LIBMESH_ENABLE_AMR
222 auto mesh_refinement = std::make_unique<MeshRefinement>(
mesh);
223 mesh_refinement->coarsen_by_parents() =
true;
230 return mesh_refinement;
238 libMesh::out <<
"Computing the error estimate using the Adjoint Refinement Error Estimator" << std::endl << std::endl;
240 auto adjoint_refinement_estimator = std::make_unique<AdjointRefinementEstimator>();
242 adjoint_refinement_estimator->qoi_set() = qois;
245 adjoint_refinement_estimator->number_h_refinements = 2;
247 return adjoint_refinement_estimator;
254int main (
int argc,
char** argv)
261 "--enable-petsc, --enable-trilinos, or --enable-eigen");
264#ifndef LIBMESH_ENABLE_AMR
265 libmesh_example_requires(
false,
"--enable-amr");
272 std::ifstream i(
"general.in");
273 libmesh_error_msg_if(!i,
'[' << init.comm().rank() <<
"] Can't find general.in; exiting early.");
277 GetPot infile(
"general.in");
280 infile.parse_command_line(argc, argv);
286 libmesh_example_requires(2 <= LIBMESH_DIM,
"2D support");
293 std::unique_ptr<MeshRefinement> mesh_refinement =
299 libMesh::out <<
"Reading in and building the mesh" << std::endl;
322 equation_systems.
init ();
331 unsigned int a_step = 0;
349 write_output(equation_systems, a_step,
"primal", param);
383 primal_solution.
swap(dual_solution_0);
384 write_output(equation_systems, a_step,
"adjoint_0", param);
387 primal_solution.
swap(dual_solution_0);
393 primal_solution.
swap(dual_solution_1);
394 write_output(equation_systems, a_step,
"adjoint_1", param);
397 primal_solution.
swap(dual_solution_1);
403 <<
" active elements and "
418 << std::setprecision(17)
419 << std::abs(QoI_0_computed - QoI_0_exact) / std::abs(QoI_0_exact)
423 << std::setprecision(17)
424 << std::abs(QoI_1_computed - QoI_1_exact) / std::abs(QoI_1_exact)
432 std::unique_ptr<AdjointRefinementEstimator> adjoint_refinement_error_estimator =
436 adjoint_refinement_error_estimator->estimate_error(system, QoI_elementwise_error);
440 libMesh::out <<
"The computed relative error in QoI 0 is "
441 << std::setprecision(17)
442 << std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(0)) / std::abs(QoI_0_exact)
445 libMesh::out <<
"The computed relative error in QoI 1 is "
446 << std::setprecision(17)
447 << std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(1)) / std::abs(QoI_1_exact)
452 libMesh::out <<
"The effectivity index for the computed error in QoI 0 is "
453 << std::setprecision(17)
454 << std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(0)) / std::abs(QoI_0_computed - QoI_0_exact)
457 libMesh::out <<
"The effectivity index for the computed error in QoI 1 is "
458 << std::setprecision(17)
459 << std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(1)) / std::abs(QoI_1_computed - QoI_1_exact)
466 for (std::size_t i=0; i<QoI_elementwise_error.size(); i++)
467 if (QoI_elementwise_error[i] != 0.)
468 QoI_elementwise_error[i] = std::abs(QoI_elementwise_error[i]);
477 mesh_refinement->uniformly_refine(1);
482 mesh_refinement->flag_elements_by_error_tolerance (QoI_elementwise_error);
484 mesh_refinement->refine_and_coarsen_elements();
491 libMesh::out <<
"We reached the target number of elements." << std::endl << std::endl;
495 mesh_refinement->flag_elements_by_nelem_target (QoI_elementwise_error);
497 mesh_refinement->refine_and_coarsen_elements();
501 equation_systems.
reinit();
505 <<
" active elements and "
517 write_output(equation_systems, a_step,
"primal", param);
536 primal_solution.
swap(dual_solution_0);
537 write_output(equation_systems, a_step,
"adjoint_0", param);
539 primal_solution.
swap(dual_solution_0);
543 primal_solution.
swap(dual_solution_1);
544 write_output(equation_systems, a_step,
"adjoint_1", param);
546 primal_solution.
swap(dual_solution_1);
552 <<
" active elements and "
567 << std::setprecision(17)
568 << std::abs(QoI_0_computed - QoI_0_exact) / std::abs(QoI_0_exact)
572 << std::setprecision(17)
573 << std::abs(QoI_1_computed - QoI_1_exact) / std::abs(QoI_1_exact)
583 std::unique_ptr<AdjointRefinementEstimator> adjoint_refinement_error_estimator =
587 adjoint_refinement_error_estimator->estimate_error(system, QoI_elementwise_error);
591 libMesh::out <<
"The computed relative error in QoI 0 is "
592 << std::setprecision(17)
593 << std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(0)) / std::abs(QoI_0_exact)
596 libMesh::out <<
"The computed relative error in QoI 1 is "
597 << std::setprecision(17)
598 << std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(1)) / std::abs(QoI_1_exact)
603 libMesh::out <<
"The effectivity index for the computed error in QoI 0 is "
604 << std::setprecision(17)
605 << std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(0)) / std::abs(QoI_0_computed - QoI_0_exact)
608 libMesh::out <<
"The effectivity index for the computed error in QoI 1 is "
609 << std::setprecision(17)
610 << std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(1)) / std::abs(QoI_1_computed - QoI_1_exact)
621 libmesh_assert_less(std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(0)) / std::abs(QoI_0_computed - QoI_0_exact), 2.5);
622 libmesh_assert_greater(std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(0)) / std::abs(QoI_0_computed - QoI_0_exact), .4);
623 libmesh_assert_less(std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(1)) / std::abs(QoI_1_computed - QoI_1_exact), 2.5);
624 libmesh_assert_greater(std::abs(adjoint_refinement_error_estimator->get_global_QoI_error_estimate(1)) / std::abs(QoI_1_computed - QoI_1_exact), .4);
627 libmesh_assert_less(std::abs(QoI_0_computed - QoI_0_exact), 2e-4);
628 libmesh_assert_less(std::abs(QoI_1_computed - QoI_1_exact), 2e-4);
633 <<
"] Completing output."
void write_output(EquationSystems &es, unsigned int a_step, std::string solution_type, FEMParameters ¶m)
void set_system_parameters(LaplaceSystem &system, FEMParameters ¶m)
std::unique_ptr< AdjointRefinementEstimator > build_adjoint_refinement_error_estimator(QoISet &qois)
std::unique_ptr< MeshRefinement > build_mesh_refinement(MeshBase &mesh, FEMParameters ¶m)
double minimum_linear_tolerance
double initial_linear_tolerance
unsigned int max_adaptivesteps
double linear_tolerance_multiplier
libMesh::Real refine_fraction
unsigned int coarserefinements
libMesh::Real verify_analytic_jacobians
unsigned int max_nonlinear_iterations
libMesh::Real global_tolerance
libMesh::Real min_step_length
std::vector< std::string > fe_family
libMesh::Real relative_residual_tolerance
bool print_residual_norms
bool print_jacobian_norms
void read(GetPot &input, const std::vector< std::string > *other_variable_names=nullptr)
libMesh::Real relative_step_tolerance
unsigned int max_linear_iterations
bool require_residual_reduction
libMesh::Real coarsen_fraction
unsigned int nelem_target
std::vector< unsigned int > fe_order
libMesh::Real coarsen_threshold
bool print_solution_norms
bool reuse_preconditioner
virtual void postprocess()
Runs a postprocessing loop over all elements, and if postprocess_sides is true over all sides.
std::string & fe_family()
Number & get_QoI_value(std::string type, unsigned int QoI_index)
unsigned int & fe_order()
bool & analytic_jacobians()
bool assemble_qoi_sides
If assemble_qoi_sides is true (it is false by default), the assembly loop for a quantity of interest ...
bool print_jacobians
Set print_jacobians to true to print J whenever it is assembled.
bool postprocess_sides
If postprocess_sides is true (it is false by default), the postprocessing loop will loop over all sid...
bool print_residuals
Set print_residuals to true to print F whenever it is assembled.
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...
bool print_solution_norms
Set print_residual_norms to true to print |U| whenever it is used in an assembly() call.
virtual LinearSolver< Number > * get_linear_solver() const override
bool print_solutions
Set print_solutions to true to print U whenever it is used in an assembly() call.
bool print_residual_norms
Set print_residual_norms to true to print |F| whenever it is assembled.
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...
bool print_jacobian_norms
Set print_jacobian_norms to true to print |J| whenever it is assembled.
std::unique_ptr< TimeSolver > time_solver
A pointer to the solver object we're going to use.
This is the EquationSystems class.
virtual void reinit()
Handle any mesh changes and reinitialize all the systems on the updated mesh.
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
std::size_t n_active_dofs() const
const MeshBase & get_mesh() const
virtual void init()
Initialize all the systems.
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
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.
virtual void solve() override
Invokes the solver associated with the system.
Real verify_analytic_jacobians
If verify_analytic_jacobian is equal to zero (as it is by default), no numeric jacobians will be calc...
This class implements writing meshes in the GMV format.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
This base class can be inherited from to provide interfaces to linear solvers from different packages...
virtual void reuse_preconditioner(bool)
Set the same_preconditioner flag, which indicates if we reuse the same preconditioner for subsequent ...
This is the MeshBase class.
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.
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false, bool skip_detect_interior_parents=false)=0
Interfaces for reading/writing a mesh to/from a file.
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
virtual dof_id_type n_active_elem() const =0
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 ...
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
processor_id_type processor_id() const
Data structure for specifying which Quantities of Interest should be calculated in an adjoint or a pa...
void add_indices(const std::vector< unsigned int > &indices)
Add this indices to the set to be calculated.
void set_weight(std::size_t, Real)
Set the weight for this index.
void set_adjoint_already_solved(bool setting)
Setter for the adjoint_already_solved boolean.
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
The libMesh namespace provides an interface to certain functionality in the library.
void libmesh_ignore(const Args &...)
SolverPackage default_solver_package()