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> *>::
241 boundary_id_type
b = i->first;
242 FunctionBase<Number> *f = i->second;
248 libMesh::out <<
"Added Dirichlet boundary " <<
b <<
" for variables ";
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;
323int main (
int argc,
char ** argv)
326#ifndef LIBMESH_ENABLE_AMR
327 libmesh_ignore(argc, argv);
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);
393 auto sigma_physics = std::make_unique<SigmaPhysics>();
394 sigma_physics->init_data(system);
399 equation_systems.init ();
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)
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;
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,
563 libmesh_assert(Z0_norm == Z0_old_norm);
564 libmesh_assert(Z1_norm == Z1_old_norm);
583 NumericVector<Number> & primal_solution = *system.
solution;
589 primal_solution.
swap(dual_solution_0);
594 primal_solution.swap(dual_solution_0);
600 primal_solution.
swap(dual_solution_1);
605 primal_solution.swap(dual_solution_1);
667 libMesh::out <<
"Saving adjoint and retrieving primal solutions at time t=" << system.
time - system.
deltat << std::endl;
680 libmesh_assert(Z0_norm == Z0_old_norm);
681 libmesh_assert(Z1_norm == Z1_old_norm);
704 primal_solution.
swap(dual_solution_0);
709 primal_solution.swap(dual_solution_0);
715 primal_solution.
swap(dual_solution_1);
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());
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!");
825 system.
time_solver->integrate_adjoint_refinement_error_estimate(*adjoint_refinement_error_estimator, QoI_elementwise_error);
874 for(
unsigned int i = 0; i < QoI_elementwise_error.size(); i++)
875 accumulated_QoI_elementwise_error[i] += QoI_elementwise_error[i];
878 for (
auto j : make_range(system.
n_qois()))
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;
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."