81#include "adjoint_initial.h"
82#include "femparameters.h"
83#include "heatsystem.h"
86#include "libmesh/equation_systems.h"
87#include "libmesh/dirichlet_boundaries.h"
88#include "libmesh/system_norm.h"
89#include "libmesh/numeric_vector.h"
90#include "libmesh/enum_solver_package.h"
92#include "libmesh/mesh.h"
93#include "libmesh/mesh_generation.h"
94#include "libmesh/mesh_refinement.h"
96#include "libmesh/petsc_diff_solver.h"
97#include "libmesh/steady_solver.h"
98#include "libmesh/euler_solver.h"
99#include "libmesh/euler2_solver.h"
100#include "libmesh/newton_solver.h"
101#include "libmesh/petsc_diff_solver.h"
102#include "libmesh/twostep_time_solver.h"
104#include "libmesh/getpot.h"
105#include "libmesh/tecplot_io.h"
106#include "libmesh/gmv_io.h"
107#include "libmesh/exodusII_io.h"
109#include "libmesh/sensitivity_data.h"
112#include "libmesh/solution_history.h"
113#include "libmesh/memory_solution_history.h"
114#include "libmesh/file_solution_history.h"
124 std::string solution_type,
128 libmesh_ignore(es, t_step, solution_type, param);
130#ifdef LIBMESH_HAVE_GMV
133 MeshBase &
mesh = es.get_mesh();
135 std::ostringstream file_name_gmv;
136 file_name_gmv << solution_type
143 GMVIO(
mesh).write_equation_systems(file_name_gmv.str(), es);
147#ifdef LIBMESH_HAVE_EXODUS_API
150 MeshBase &
mesh = es.get_mesh();
160 std::ostringstream file_name_exodus;
162 file_name_exodus << solution_type <<
".e";
164 file_name_exodus <<
"-s"
171 ExodusII_IO(
mesh).write_timestep(file_name_exodus.str(),
205 std::unique_ptr<UnsteadySolver> innersolver;
208 auto euler2solver = std::make_unique<Euler2Solver>(system);
210 innersolver = std::move(euler2solver);
214 auto eulersolver = std::make_unique<EulerSolver>(system);
216 innersolver = std::move(eulersolver);
219 libmesh_error_msg(
"This example (and unsteady adjoints in libMesh) only support Backward Euler and explicit methods.");
223 system.
time_solver = std::make_unique<TwostepTimeSolver>(system);
224 auto timesolver = cast_ptr<TwostepTimeSolver *>(system.
time_solver.get());
230 timesolver->core_time_solver = std::move(innersolver);
235 MemorySolutionHistory heatsystem_solution_history(system);
236 system.
time_solver->set_solution_history(heatsystem_solution_history);
240 FileSolutionHistory heatsystem_solution_history(system);
241 system.
time_solver->set_solution_history(heatsystem_solution_history);
253 MemorySolutionHistory heatsystem_solution_history(system);
254 system.
time_solver->set_solution_history(heatsystem_solution_history);
258 FileSolutionHistory heatsystem_solution_history(system);
259 system.
time_solver->set_solution_history(heatsystem_solution_history);
266 system.
time_solver = std::make_unique<SteadySolver>(system);
271 #ifdef LIBMESH_ENABLE_DIRICHLET
274 std::map<boundary_id_type, FunctionBase<Number> *>::
280 boundary_id_type
b = i->first;
281 FunctionBase<Number> *f = i->second;
287 libMesh::out <<
"Added Dirichlet boundary " <<
b <<
" for variables ";
303#ifdef LIBMESH_HAVE_PETSC
304 system.
time_solver->diff_solver() = std::make_unique<PetscDiffSolver>(system);
306 libmesh_error_msg(
"This example requires libMesh to be compiled with PETSc support.");
311 system.
time_solver->diff_solver() = std::make_unique<NewtonSolver>(system);
312 auto solver = cast_ptr<NewtonSolver *>(system.
time_solver->diff_solver().get());
322 if (system.
time_solver->reduce_deltat_on_diffsolver_failure)
324 solver->continue_after_max_iterations =
true;
325 solver->continue_after_backtrack_failure =
true;
337int main (
int argc,
char ** argv)
340#ifndef LIBMESH_ENABLE_AMR
341 libmesh_ignore(argc, argv);
342 libmesh_example_requires(
false,
"--enable-amr");
345 libmesh_example_requires(2 <= LIBMESH_DIM,
"2D support");
348#ifndef LIBMESH_ENABLE_DIRICHLET
349 libmesh_example_requires(
false,
"--enable-dirichlet");
353 LibMeshInit init (argc, argv);
362 std::ifstream i(
"general.in");
363 libmesh_error_msg_if(!i,
'[' << init.comm().rank() <<
"] Can't find general.in; exiting early.");
365 GetPot infile(
"general.in");
368 infile.parse_command_line(argc, argv);
376 Mesh
mesh(init.comm(), cast_int<unsigned char>(param.
dimension));
379 auto mesh_refinement = std::make_unique<MeshRefinement>(
mesh);
382 EquationSystems equation_systems (
mesh);
409 equation_systems.init ();
414 mesh_refinement->uniformly_refine(1);
415 equation_systems.reinit();
418 libMesh::out <<
"Setting primal initial conditions" << std::endl;
423 equation_systems.parameters);
447 equation_systems.print_info();
452#if defined(NDEBUG) && defined(LIBMESH_ENABLE_EXCEPTIONS)
480 libMesh::out <<
"Advancing timestep" << std::endl << std::endl;
484 write_output(equation_systems, t_step+1,
"primal", param);
491 libMesh::out << std::endl <<
"Solving the adjoint problem" << std::endl;
496 const std::string & adjoint_solution_name0 =
"adjoint_solution0";
497 const std::string & old_adjoint_solution_name0 =
"_old_adjoint_solution0";
513 equation_systems.parameters,
537 libmesh_assert(Z_norm == Z_old_norm);
594 libMesh::out <<
"Saving adjoint and retrieving primal solutions at time t=" << system.
time - system.
deltat << std::endl;
606 libmesh_assert(Z_norm == Z_old_norm);
616 NumericVector<Number> & primal_solution = *system.
solution;
622 primal_solution.
swap(dual_solution_0);
627 primal_solution.swap(dual_solution_0);
642 qois.add_indices({0});
643 qois.set_weight(0, 1.0);
649 Number total_sensitivity = 0.0;
659 libmesh_error_msg_if(std::abs(Z_old_norm - (2.23366)) >= 2.e-4,
660 "Mismatch in expected Z0_old norm for the 1st half timestep!");
664 libmesh_error_msg_if(std::abs(Z_old_norm - (2.23627)) >= 2.e-4,
665 "Mismatch in expected Z0_old norm for the 1st timestep!");
742 total_sensitivity += sensitivities[0][0];
746 libMesh::out <<
"Sensitivity of QoI 0 w.r.t parameter 0 is: "
756 libmesh_error_msg_if(std::abs(system.
time - (1.0089)) >= 2.e-4,
757 "Mismatch in end time reached by adaptive timestepper!");
759 libmesh_error_msg_if(std::abs(total_sensitivity - 4.87767) >= 3.e-3,
760 "Mismatch in sensitivity gold value!");
764 libmesh_error_msg_if(std::abs(total_sensitivity - 4.83551) >= 2.e-4,
765 "Mismatch in sensitivity gold value!");
768#if defined(NDEBUG) && defined(LIBMESH_ENABLE_EXCEPTIONS)
772 <<
"] Caught exception; exiting early." << std::endl;
777 <<
"] Completing output."
Number initial_value(const Point &, const Parameters &, const std::string &, const std::string &)
void read_initial_parameters()
Gradient initial_grad(const Point &, const Parameters &, const std::string &, const std::string &)
void finish_initialization()
Gradient adjoint_initial_grad(const Point &p, const Parameters &, const std::string &, const std::string &)
Number adjoint_initial_value(const Point &p, const Parameters &, const std::string &, const std::string &)
void write_output(EquationSystems &es, unsigned int t_step, std::string solution_type, FEMParameters ¶m)
void set_system_parameters(HeatSystem &system, FEMParameters ¶m)
std::map< libMesh::boundary_id_type, libMesh::FunctionBase< libMesh::Number > * > dirichlet_conditions
double minimum_linear_tolerance
double initial_linear_tolerance
libMesh::Real timesolver_theta
double linear_tolerance_multiplier
libMesh::Real timesolver_tolerance
libMesh::Real domain_xmin
bool print_element_jacobians
std::map< libMesh::boundary_id_type, std::vector< unsigned int > > dirichlet_condition_variables
libMesh::Real verify_analytic_jacobians
unsigned int max_nonlinear_iterations
libMesh::Real timesolver_maxgrowth
libMesh::Real domain_ymin
bool print_element_residuals
int extra_quadrature_order
libMesh::Real min_step_length
libMesh::Real timesolver_upper_tolerance
std::string timesolver_core
libMesh::Real numerical_jacobian_h
std::vector< std::string > fe_family
unsigned int initial_timestep
libMesh::Real relative_residual_tolerance
bool print_residual_norms
bool print_jacobian_norms
std::string solution_history_type
std::vector< libMesh::FEMNormType > timesolver_norm
void read(GetPot &input, const std::vector< std::string > *other_variable_names=nullptr)
libMesh::Real domain_edge_length
libMesh::Real relative_step_tolerance
unsigned int max_linear_iterations
bool require_residual_reduction
std::vector< unsigned int > fe_order
unsigned int extrarefinements
bool print_solution_norms
unsigned int deltat_reductions
libMesh::Real domain_edge_width
unsigned int & fe_order()
bool & analytic_jacobians()
ParameterVector & get_parameter_vector()
std::string & fe_family()
bool print_jacobians
Set print_jacobians to true to print J whenever it is assembled.
bool print_residuals
Set print_residuals to true to print F whenever it is assembled.
Real deltat
For time-dependent problems, this is the amount delta t to advance the solution in time.
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_element_jacobians
Set print_element_jacobians to true to print each J_elem contribution.
bool print_solution_norms
Set print_residual_norms to true to print |U| whenever it is used in an assembly() call.
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_element_residuals
Set print_element_residuals to true to print each R_elem contribution.
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.
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
virtual void solve() override
Invokes the solver associated with the system.
Real numerical_jacobian_h
If calculating numeric jacobians is required, the FEMSystem will perturb each solution vector entry b...
Real verify_analytic_jacobians
If verify_analytic_jacobian is equal to zero (as it is by default), no numeric jacobians will be calc...
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
int extra_quadrature_order
A member int that can be employed to indicate increased or reduced quadrature order.
void project_vector(NumericVector< Number > &new_vector, FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr, int is_adjoint=-1, std::optional< ConstElemRange > active_local_range=std::nullopt, std::optional< std::vector< unsigned int > > variable_numbers=std::nullopt) const
Projects arbitrary functions onto a vector of degree of freedom values for the current system.
void project_solution(FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr, std::optional< ConstElemRange > active_local_range=std::nullopt, std::optional< std::vector< unsigned int > > variable_numbers=std::nullopt) const
Projects arbitrary functions onto the current solution.
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...
void init_qois(unsigned int n_qois)
Accessors for qoi and qoi_error_estimates vectors.
void set_adjoint_already_solved(bool setting)
Setter for the adjoint_already_solved boolean.
Real time
For time-dependent problems, this is the time t at the beginning of the current timestep.
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
const DofMap & get_dof_map() const
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
const NumericVector< Number > & get_vector(std::string_view vec_name) const
SolverPackage default_solver_package()