338{
339
340#ifndef LIBMESH_ENABLE_AMR
342 libmesh_example_requires(false, "--enable-amr");
343#else
344
345 libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");
346
347
348#ifndef LIBMESH_ENABLE_DIRICHLET
349 libmesh_example_requires(false, "--enable-dirichlet");
350#endif
351
352
353 LibMeshInit
init (argc, argv);
354
355
357
359
360
361 {
362 std::ifstream i("general.in");
363 libmesh_error_msg_if(!i,
'[' <<
init.comm().rank() <<
"] Can't find general.in; exiting early.");
364 }
365 GetPot infile("general.in");
366
367
368 infile.parse_command_line(argc, argv);
369
370
372 param.read(infile);
373
374
375
376 Mesh
mesh(
init.comm(), cast_int<unsigned char>(param.dimension));
377
378
379 auto mesh_refinement = std::make_unique<MeshRefinement>(
mesh);
380
381
382 EquationSystems equation_systems (
mesh);
383
385
386
388
389 if (param.elementtype == "tri" ||
390 param.elementtype == "unstructured")
392 else
394
395 MeshTools::Generation::build_square (
mesh, param.coarsegridx, param.coarsegridy,
396 param.domain_xmin, param.domain_xmin + param.domain_edge_width,
397 param.domain_ymin, param.domain_ymin + param.domain_edge_length,
398 elemtype);
399
401
403
405
407
408
409 equation_systems.init ();
410
411
412 for (unsigned int i=0; i != param.extrarefinements; ++i)
413 {
414 mesh_refinement->uniformly_refine(1);
415 equation_systems.reinit();
416 }
417
418 libMesh::out <<
"Setting primal initial conditions" << std::endl;
419
421
423 equation_systems.parameters);
424
425
428 << ")|= "
430 << std::endl
431 << std::endl;
432
433
435
436
438
439
441
442
444
445
447 equation_systems.print_info();
448
449
450
451
452#if defined(NDEBUG) && defined(LIBMESH_ENABLE_EXCEPTIONS)
453 try
454#endif
455 {
456
457
458 for (unsigned int t_step=param.initial_timestep;
459 t_step != param.initial_timestep + param.n_timesteps; ++t_step)
460 {
461
463 << t_step
464 << ", time = "
466 << std::endl;
467
468
470
471
472
475 << ")|= "
477 << std::endl;
478
479
480 libMesh::out <<
"Advancing timestep" << std::endl << std::endl;
482
483
484 write_output(equation_systems, t_step+1,
"primal", param);
485 }
486
487
489
490
491 libMesh::out << std::endl <<
"Solving the adjoint problem" << std::endl;
492
493
494
495
496 const std::string & adjoint_solution_name0 = "adjoint_solution0";
497 const std::string & old_adjoint_solution_name0 = "_old_adjoint_solution0";
498
499
502
505 << ")"
506 <<std::endl;
507
508
509
510
513 equation_systems.parameters,
515
516
517
518
520
522
525 << ")|= "
526 << Z_norm
527 << std::endl
528 << std::endl;
529
530
531
533
535
536
538
540 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
541 << ")|= "
542 << Z_old_norm
543 << std::endl
544 << std::endl;
545
546 write_output(equation_systems, param.n_timesteps,
"dual", param);
547
548
549
550
551
552 for (unsigned int t_step=param.initial_timestep;
553 t_step != param.initial_timestep + param.n_timesteps; ++t_step)
554 {
555
557 << t_step
558 << ", time = "
560 << std::endl;
561
562
563
566 << ")|= "
568 << std::endl;
569
571 << system.
time - (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
572 << ")|= "
574 << std::endl;
575
577
579
581
584 << ")|= "
585 << Z_norm
586 << std::endl
587 << std::endl;
588
589
590
591
593
594 libMesh::out <<
"Saving adjoint and retrieving primal solutions at time t=" << system.
time - system.
deltat << std::endl;
595
596
597
598
599
600
602
604
605
607
609 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
610 << ")|= "
611 << Z_old_norm
612 << std::endl
613 << std::endl;
614
615
616 NumericVector<Number> & primal_solution = *system.
solution;
617
618
620
621
622 primal_solution.
swap(dual_solution_0);
623
624 write_output(equation_systems, param.n_timesteps - (t_step + 1),
"dual", param);
625
626
627 primal_solution.swap(dual_solution_0);
628 }
629
630
631
632
633
634
635
636
638
639
640 QoISet qois;
641
642 qois.add_indices({0});
643 qois.set_weight(0, 1.0);
644
645
647
648
649 Number total_sensitivity = 0.0;
650
651
653
655
656
657 if(param.timesolver_tolerance)
658 {
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!");
661 }
662 else
663 {
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!");
666 }
667
668
670 << "time = "
672 << std::endl;
673
676 << ")|= "
678 << std::endl;
679
682 << ")|= "
684 << std::endl;
685
688 << ")|= "
690 << std::endl
691 << std::endl;
692
694 << system.
time + (system.
time_solver->last_completed_timestep_size())/((param.timesolver_tolerance) ? 2.0 : 1.0)
695 << ")|= "
697 << std::endl
698 << std::endl;
699
700
701
702 for (unsigned int t_step=param.initial_timestep;
703 t_step != param.initial_timestep + param.n_timesteps; ++t_step)
704 {
705
706
708
709
711 << "time = "
713 << std::endl;
714
717 << ")|= "
719 << std::endl;
720
723 << ")|= "
725 << std::endl;
726
729 << ")|= "
731 << std::endl
732 << std::endl;
733
736 << ")|= "
738 << std::endl
739 << std::endl;
740
741
742 total_sensitivity += sensitivities[0][0];
743 }
744
745
746 libMesh::out <<
"Sensitivity of QoI 0 w.r.t parameter 0 is: "
747 << total_sensitivity
748 << std::endl;
749
750
751
752
753
754 if(param.timesolver_tolerance)
755 {
756 libmesh_error_msg_if(std::abs(system.
time - (1.0089)) >= 2.e-4,
757 "Mismatch in end time reached by adaptive timestepper!");
758
759 libmesh_error_msg_if(std::abs(total_sensitivity - 4.87767) >= 3.e-3,
760 "Mismatch in sensitivity gold value!");
761 }
762 else
763 {
764 libmesh_error_msg_if(std::abs(total_sensitivity - 4.83551) >= 2.e-4,
765 "Mismatch in sensitivity gold value!");
766 }
767 }
768#if defined(NDEBUG) && defined(LIBMESH_ENABLE_EXCEPTIONS)
769 catch (...)
770 {
772 << "] Caught exception; exiting early." << std::endl;
773 }
774#endif
775
777 << "] Completing output."
778 << std::endl;
779
780
781 return 0;
782
783#endif
784}
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)
ParameterVector & get_parameter_vector()
Real deltat
For time-dependent problems, this is the amount delta t to advance the solution in time.
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...
std::unique_ptr< TimeSolver > time_solver
A pointer to the solver object we're going to use.
virtual void solve() override
Invokes the solver associated with the system.
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
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
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
const NumericVector< Number > & get_vector(std::string_view vec_name) const
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
ElemType
Defines an enum for geometric element types.
void libmesh_ignore(const Args &...)
SolverPackage default_solver_package()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real