44 #include "adjoint_initial.h" 45 #include "femparameters.h" 46 #include "heatsystem.h" 50 #include "libmesh/equation_systems.h" 51 #include "libmesh/dirichlet_boundaries.h" 52 #include "libmesh/system_norm.h" 53 #include "libmesh/numeric_vector.h" 54 #include "libmesh/enum_solver_package.h" 56 #include "libmesh/mesh.h" 57 #include "libmesh/mesh_generation.h" 58 #include "libmesh/mesh_refinement.h" 60 #include "libmesh/petsc_diff_solver.h" 61 #include "libmesh/steady_solver.h" 62 #include "libmesh/euler_solver.h" 63 #include "libmesh/euler2_solver.h" 64 #include "libmesh/newton_solver.h" 65 #include "libmesh/petsc_diff_solver.h" 66 #include "libmesh/twostep_time_solver.h" 68 #include "libmesh/getpot.h" 69 #include "libmesh/tecplot_io.h" 70 #include "libmesh/gmv_io.h" 71 #include "libmesh/exodusII_io.h" 73 #include "libmesh/adjoint_refinement_estimator.h" 74 #include "libmesh/error_vector.h" 77 #include "libmesh/solution_history.h" 78 #include "libmesh/memory_solution_history.h" 79 #include "libmesh/file_solution_history.h" 89 std::string solution_type,
95 #ifdef LIBMESH_HAVE_GMV 98 MeshBase &
mesh = es.get_mesh();
100 std::ostringstream file_name_gmv;
101 file_name_gmv << solution_type
108 GMVIO(
mesh).write_equation_systems(file_name_gmv.str(), es);
112 #ifdef LIBMESH_HAVE_EXODUS_API 115 MeshBase &
mesh = es.get_mesh();
125 std::ostringstream file_name_exodus;
127 file_name_exodus << solution_type <<
".e";
129 file_name_exodus <<
"-s" 136 ExodusII_IO(
mesh).write_timestep(file_name_exodus.str(),
166 std::unique_ptr<UnsteadySolver> innersolver;
169 auto euler2solver = std::make_unique<Euler2Solver>(system);
171 innersolver = std::move(euler2solver);
175 auto eulersolver = std::make_unique<EulerSolver>(system);
177 innersolver = std::move(eulersolver);
180 libmesh_error_msg(
"This example (and unsteady adjoints in libMesh) only support Backward Euler and explicit methods.");
184 system.
time_solver = std::make_unique<TwostepTimeSolver>(system);
185 auto timesolver = cast_ptr<TwostepTimeSolver *>(system.
time_solver.get());
191 timesolver->core_time_solver = std::move(innersolver);
196 MemorySolutionHistory heatsystem_solution_history(system);
197 system.
time_solver->set_solution_history(heatsystem_solution_history);
201 FileSolutionHistory heatsystem_solution_history(system);
202 system.
time_solver->set_solution_history(heatsystem_solution_history);
214 MemorySolutionHistory heatsystem_solution_history(system);
215 system.
time_solver->set_solution_history(heatsystem_solution_history);
219 FileSolutionHistory heatsystem_solution_history(system);
220 system.
time_solver->set_solution_history(heatsystem_solution_history);
227 system.
time_solver = std::make_unique<SteadySolver>(system);
232 #ifdef LIBMESH_ENABLE_DIRICHLET 235 std::map<boundary_id_type, FunctionBase<Number> *>::
242 FunctionBase<Number> *f = i->second;
248 libMesh::out <<
"Added Dirichlet boundary " << b <<
" for variables ";
253 #endif // LIBMESH_ENABLE_DIRICHLET 264 #ifdef LIBMESH_HAVE_PETSC 265 system.
time_solver->diff_solver() = std::make_unique<PetscDiffSolver>(system);
267 libmesh_error_msg(
"This example requires libMesh to be compiled with PETSc support.");
272 system.
time_solver->diff_solver() = std::make_unique<NewtonSolver>(system);
273 auto solver = cast_ptr<NewtonSolver*>(system.
time_solver->diff_solver().get());
283 if (system.
time_solver->reduce_deltat_on_diffsolver_failure)
285 solver->continue_after_max_iterations =
true;
286 solver->continue_after_backtrack_failure =
true;
297 #ifdef LIBMESH_ENABLE_AMR 298 std::unique_ptr<AdjointRefinementEstimator>
301 std::cout<<
"Computing the error estimate using the Adjoint Refinement Error Estimator"<<std::endl<<std::endl;
303 auto adjoint_refinement_estimator = std::make_unique<AdjointRefinementEstimator>();
305 adjoint_refinement_estimator->qoi_set() = qois;
309 adjoint_refinement_estimator->set_residual_evaluation_physics(supplied_physics);
312 adjoint_refinement_estimator->set_adjoint_evaluation_physics(supplied_physics);
316 adjoint_refinement_estimator->number_h_refinements = 0;
318 return adjoint_refinement_estimator;
320 #endif // LIBMESH_ENABLE_AMR 323 int main (
int argc,
char ** argv)
326 #ifndef LIBMESH_ENABLE_AMR 328 libmesh_example_requires(
false,
"--enable-amr");
331 libmesh_example_requires(2 <= LIBMESH_DIM,
"2D support");
334 #ifndef LIBMESH_ENABLE_DIRICHLET 335 libmesh_example_requires(
false,
"--enable-dirichlet");
339 LibMeshInit
init (argc, argv);
348 std::ifstream i(
"general.in");
349 libmesh_error_msg_if(!i,
'[' <<
init.comm().rank() <<
"] Can't find general.in; exiting early.");
351 GetPot infile(
"general.in");
354 infile.parse_command_line(argc, argv);
362 Mesh
mesh(
init.comm(), cast_int<unsigned char>(param.dimension));
365 auto mesh_refinement = std::make_unique<MeshRefinement>(
mesh);
368 EquationSystems equation_systems (
mesh);
375 if (param.elementtype ==
"tri" ||
376 param.elementtype ==
"unstructured")
382 param.domain_xmin, param.domain_xmin + param.domain_edge_width,
383 param.domain_ymin, param.domain_ymin + param.domain_edge_length,
393 auto sigma_physics = std::make_unique<SigmaPhysics>();
394 sigma_physics->init_data(system);
399 equation_systems.init ();
402 for (
unsigned int i=0; i != param.extrarefinements; ++i)
404 mesh_refinement->uniformly_refine(1);
405 equation_systems.reinit();
408 libMesh::out <<
"Setting primal initial conditions" << std::endl;
411 equation_systems.parameters);
432 equation_systems.print_info();
435 Number QoI_1_accumulated = 0.0;
440 #if defined(NDEBUG) && defined(LIBMESH_ENABLE_EXCEPTIONS) 446 for (
unsigned int t_step=param.initial_timestep;
447 t_step != param.initial_timestep + param.n_timesteps; ++t_step)
467 libMesh::out <<
"Advancing timestep" << std::endl << std::endl;
471 write_output(equation_systems, t_step+1,
"primal", param);
476 (
dynamic_cast<HeatSystem &
>(system).QoI_time_instant)[0] = system.
time;
485 QoI_1_accumulated = 0.0;
487 for (
unsigned int t_step=param.initial_timestep;
488 t_step != param.initial_timestep + param.n_timesteps; ++t_step)
495 std::cout<<
"The computed QoI 0 is " << std::setprecision(17) << system.
get_qoi_value(0) << std::endl;
496 std::cout<<
"The computed QoI 1 is " << std::setprecision(17) << QoI_1_accumulated << std::endl;
501 libMesh::out << std::endl <<
"Solving the adjoint problems." << std::endl;
508 const std::string & adjoint_solution_name0 =
"adjoint_solution0";
509 const std::string & adjoint_solution_name1 =
"adjoint_solution1";
510 const std::string & old_adjoint_solution_name0 =
"_old_adjoint_solution0";
511 const std::string & old_adjoint_solution_name1 =
"_old_adjoint_solution1";
528 equation_systems.parameters,
567 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
574 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
589 primal_solution.
swap(dual_solution_0);
591 write_output(equation_systems, param.n_timesteps,
"dual0", param);
594 primal_solution.swap(dual_solution_0);
600 primal_solution.
swap(dual_solution_1);
602 write_output(equation_systems, param.n_timesteps,
"dual1", param);
605 primal_solution.swap(dual_solution_1);
611 for (
unsigned int t_step=param.initial_timestep;
612 t_step != param.initial_timestep + param.n_timesteps; ++t_step)
630 << system.
time - (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
667 libMesh::out <<
"Saving adjoint and retrieving primal solutions at time t=" << system.
time - system.
deltat << std::endl;
684 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
691 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
704 primal_solution.
swap(dual_solution_0);
706 write_output(equation_systems, param.n_timesteps - (t_step + 1),
"dual0", param);
709 primal_solution.swap(dual_solution_0);
715 primal_solution.
swap(dual_solution_1);
717 write_output(equation_systems, param.n_timesteps - (t_step + 1),
"dual1", param);
720 primal_solution.swap(dual_solution_1);
736 qois.add_indices({0,1});
737 qois.set_weight(0, 0.5);
738 qois.set_weight(1, 0.5);
741 auto adjoint_refinement_error_estimator =
745 ErrorVector QoI_elementwise_error;
746 std::vector<Number> QoI_spatially_integrated_error(system.
n_qois());
749 ErrorVector accumulated_QoI_elementwise_error;
750 std::vector<Number> accumulated_QoI_spatially_integrated_error(system.
n_qois());
791 if(param.timesolver_tolerance)
793 libmesh_error_msg_if(std::abs(Z0_old_norm - (4.3523242593920151e-06)) >= 2.e-10,
794 "Mismatch in expected Z0_old norm for the 1st half timestep!");
795 libmesh_error_msg_if(std::abs(Z1_old_norm - (0.3118758855352407)) >= 2.e-5,
796 "Mismatch in expected Z1_old norm for the 1st half timestep!");
800 libmesh_error_msg_if(std::abs(Z0_old_norm - (0.0030758523361801263)) >= 2.e-7,
801 "Mismatch in expected Z0_old norm for the 1st timestep!");
802 libmesh_error_msg_if(std::abs(Z1_old_norm - (0.31162043809579365)) >= 2.e-5,
803 "Mismatch in expected Z1_old norm for the 1st timestep!");
807 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
814 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
822 for (
unsigned int t_step=param.initial_timestep;
823 t_step != param.initial_timestep + param.n_timesteps; ++t_step)
825 system.
time_solver->integrate_adjoint_refinement_error_estimate(*adjoint_refinement_error_estimator, QoI_elementwise_error);
860 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
867 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
874 for(
unsigned int i = 0; i < QoI_elementwise_error.size(); i++)
875 accumulated_QoI_elementwise_error[i] += QoI_elementwise_error[i];
881 if ((adjoint_refinement_error_estimator->qoi_set()).has_index(j))
888 std::cout<<
"Time integrated error estimate for QoI 0: "<<std::setprecision(17)<<accumulated_QoI_spatially_integrated_error[0]<<std::endl;
889 std::cout<<
"Time integrated error estimate for QoI 1: "<<std::setprecision(17)<<accumulated_QoI_spatially_integrated_error[1]<<std::endl;
895 if(param.timesolver_tolerance)
897 libmesh_error_msg_if(std::abs(system.
time - (1.7548735069535084)) >= 2.e-4,
898 "Mismatch in end time reached by adaptive timestepper!");
900 libmesh_error_msg_if(std::abs(accumulated_QoI_spatially_integrated_error[0] - (-0.75139371165754232)) >= 2.e-4,
901 "Error Estimator identity not satisfied!");
903 libmesh_error_msg_if(std::abs(accumulated_QoI_spatially_integrated_error[1] - (-0.70905030091469889)) >= 2.e-4,
904 "Error Estimator identity not satisfied!");
908 libmesh_error_msg_if(std::abs(accumulated_QoI_spatially_integrated_error[0] - (-0.44809323880671958)) >= 2.e-4,
909 "Error Estimator identity not satisfied!");
911 libmesh_error_msg_if(std::abs(accumulated_QoI_spatially_integrated_error[1] - (-0.23895256319278346)) >= 2.e-4,
912 "Error Estimator identity not satisfied!");
915 #if defined(NDEBUG) && defined(LIBMESH_ENABLE_EXCEPTIONS) 919 <<
"] Caught exception; exiting early." << std::endl;
924 <<
"] Completing output." 930 #endif // LIBMESH_ENABLE_AMR
libMesh::Real timesolver_upper_tolerance
Real time
For time-dependent problems, this is the time t at the beginning of the current timestep.
bool print_solution_norms
ElemType
Defines an enum for geometric element types.
bool print_element_residuals
std::string solution_history_type
Real verify_analytic_jacobians
If verify_analytic_jacobian is equal to zero (as it is by default), no numeric jacobians will be calc...
Number adjoint_initial_value0(const Point &, const Parameters &, const std::string &, const std::string &)
libMesh::Real timesolver_tolerance
void set_adjoint_already_solved(bool setting)
Setter for the adjoint_already_solved boolean.
void write_output(EquationSystems &es, unsigned int t_step, std::string solution_type, FEMParameters ¶m)
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...
Number get_qoi_value(unsigned int qoi_index) const
bool print_jacobian_norms
Set print_jacobian_norms to true to print |J| whenever it is assembled.
int main(int argc, char **argv)
unsigned int n_qois() const
Number of currently active quantities of interest.
int extra_quadrature_order
A member int that can be employed to indicate increased or reduced quadrature order.
Real numerical_jacobian_h
If calculating numeric jacobians is required, the FEMSystem will perturb each solution vector entry b...
std::string timesolver_core
bool require_residual_reduction
std::unique_ptr< TimeSolver > time_solver
A pointer to the solver object we're going to use.
bool print_residual_norms
void init_qois(unsigned int n_qois)
Accessors for qoi and qoi_error_estimates vectors.
libMesh::Real timesolver_maxgrowth
Gradient adjoint_initial_grad0(const Point &, const Parameters &, const std::string &, const std::string &)
libMesh::Real relative_step_tolerance
bool print_jacobians
Set print_jacobians to true to print J whenever it is assembled.
void pop_physics()
Pop a physics object off of our stack.
bool print_element_residuals
Set print_element_residuals to true to print each R_elem contribution.
SolverPackage default_solver_package()
void project_solution(FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr) const
Projects arbitrary functions onto the current solution.
bool print_solution_norms
Set print_residual_norms to true to print |U| whenever it is used in an assembly() call...
void libmesh_ignore(const Args &...)
unsigned int max_linear_iterations
bool print_residual_norms
Set print_residual_norms to true to print |F| whenever it is assembled.
double minimum_linear_tolerance
Real deltat
For time-dependent problems, this is the amount delta t to advance the solution in time...
libMesh::Real verify_analytic_jacobians
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Real calculate_norm(const NumericVector< Number > &v, unsigned int var, FEMNormType norm_type, std::set< unsigned int > *skip_dimensions=nullptr) const
bool print_residuals
Set print_residuals to true to print F whenever it is assembled.
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
double initial_linear_tolerance
void set_system_parameters(HeatSystem &system, FEMParameters ¶m)
int extra_quadrature_order
void read(GetPot &input, const std::vector< std::string > *other_variable_names=nullptr)
bool print_solutions
Set print_solutions to true to print U whenever it is used in an assembly() call. ...
libMesh::Real relative_residual_tolerance
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void set_vector_preservation(const std::string &vec_name, bool preserve)
Allows one to set the boolean controlling whether the vector identified by vec_name should be "preser...
bool print_jacobian_norms
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
libMesh::Real min_step_length
libMesh::Real timesolver_theta
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Gradient initial_grad(const Point &, const Parameters &, const std::string &, const std::string &)
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
bool print_element_jacobians
Set print_element_jacobians to true to print each J_elem contribution.
bool print_element_jacobians
unsigned int max_nonlinear_iterations
double linear_tolerance_multiplier
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
std::map< libMesh::boundary_id_type, std::vector< unsigned int > > dirichlet_condition_variables
std::unique_ptr< AdjointRefinementEstimator > build_adjoint_refinement_error_estimator(QoISet &qois, FEMPhysics *supplied_physics, FEMParameters &)
void project_vector(NumericVector< Number > &new_vector, FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr, int is_adjoint=-1) const
Projects arbitrary functions onto a vector of degree of freedom values for the current system...
virtual void solve() override
Invokes the solver associated with the system.
void push_physics(DifferentiablePhysics &new_physics)
Push a clone of a new physics object onto our stack, overriding the current physics until the new phy...
Number get_qoi_error_estimate_value(unsigned int qoi_index) const
bool & analytic_jacobians()
libMesh::Real numerical_jacobian_h
std::map< libMesh::boundary_id_type, libMesh::FunctionBase< libMesh::Number > * > dirichlet_conditions
const DofMap & get_dof_map() const
std::vector< libMesh::FEMNormType > timesolver_norm
template class LIBMESH_EXPORT NumericVector< Number >
Number initial_value(const Point &, const Parameters &, const std::string &, const std::string &)
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...
const NumericVector< Number > & get_vector(std::string_view vec_name) const
unsigned int deltat_reductions