Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : #include "libmesh/time_solver.h" 19 : 20 : #include "libmesh/diff_solver.h" 21 : #include "libmesh/diff_system.h" 22 : #include "libmesh/linear_solver.h" 23 : #include "libmesh/no_solution_history.h" 24 : 25 : #include "libmesh/adjoint_refinement_estimator.h" 26 : #include "libmesh/error_vector.h" 27 : 28 : 29 : // C++ includes 30 : #include <memory> 31 : 32 : 33 : namespace libMesh 34 : { 35 : 36 5884 : TimeSolver::TimeSolver (sys_type & s) 37 5536 : : quiet (true), 38 5536 : reduce_deltat_on_diffsolver_failure (0), 39 5536 : _diff_solver (), 40 5536 : _linear_solver (), 41 5536 : _system (s), 42 6058 : solution_history(std::make_unique<NoSolutionHistory>()), 43 5884 : last_deltat (s.deltat), 44 6058 : _is_adjoint (false) 45 : { 46 5884 : } 47 : 48 : 49 : 50 5536 : TimeSolver::~TimeSolver () = default; 51 : 52 : 53 : 54 5236 : void TimeSolver::reinit () 55 : { 56 176 : libmesh_assert(this->diff_solver().get()); 57 176 : libmesh_assert_equal_to (&(this->diff_solver()->system()), &(this->system())); 58 5236 : this->diff_solver()->reinit(); 59 : 60 176 : libmesh_assert(this->linear_solver().get()); 61 5236 : this->linear_solver()->clear(); 62 10296 : if (libMesh::on_command_line("--solver-system-names")) 63 0 : this->linear_solver()->init((_system.name()+"_").c_str()); 64 : else 65 5236 : this->linear_solver()->init(); 66 : 67 5236 : this->_linear_solver->init_names(_system); 68 5236 : } 69 : 70 : 71 : 72 5044 : void TimeSolver::init () 73 : { 74 : // If the user hasn't given us a solver to use, 75 : // just build a default solver 76 5044 : if (this->diff_solver().get() == nullptr) 77 7262 : this->diff_solver() = DiffSolver::build(_system); 78 : 79 5044 : if (this->linear_solver().get() == nullptr) 80 9938 : this->linear_solver() = LinearSolver<Number>::build(_system.comm()); 81 5044 : } 82 : 83 840 : void TimeSolver::init_adjoints () 84 : { 85 24 : libmesh_assert_msg(_system.n_qois() != 0, "System qois have to be initialized before initializing adjoints."); 86 : 87 : // Add adjoint vectors 88 2240 : for(auto i : make_range(_system.n_qois())) 89 : { 90 1440 : std::string adjoint_solution_name = "adjoint_solution"; 91 1360 : adjoint_solution_name+= std::to_string(i); 92 1440 : _system.add_vector(adjoint_solution_name, false, GHOSTED); 93 : } 94 : 95 840 : } 96 : 97 5044 : void TimeSolver::init_data () 98 : { 99 5044 : this->diff_solver()->init(); 100 : 101 9938 : if (libMesh::on_command_line("--solver-system-names")) 102 0 : this->linear_solver()->init((_system.name()+"_").c_str()); 103 : else 104 5044 : this->linear_solver()->init(); 105 : 106 5044 : this->linear_solver()->init_names(_system); 107 5044 : } 108 : 109 : 110 : 111 5132 : void TimeSolver::solve () 112 : { 113 182 : libmesh_assert(this->diff_solver().get()); 114 182 : libmesh_assert_equal_to (&(this->diff_solver()->system()), &(this->system())); 115 5132 : this->diff_solver()->solve(); 116 5132 : } 117 : 118 : 119 1680 : void TimeSolver::set_solution_history (const SolutionHistory & _solution_history) 120 : { 121 3264 : solution_history = _solution_history.clone(); 122 1680 : } 123 : 124 13020 : SolutionHistory & TimeSolver::get_solution_history () 125 : { 126 13020 : return *solution_history; 127 : } 128 : 129 677 : void TimeSolver::advance_timestep () 130 : { 131 677 : } 132 : 133 2823 : std::pair<unsigned int, Real> TimeSolver::adjoint_solve (const QoISet & qoi_indices) 134 : { 135 126 : libmesh_assert(this->diff_solver().get()); 136 126 : libmesh_assert_equal_to (&(this->diff_solver()->system()), &(this->system())); 137 : 138 2823 : return this->_system.ImplicitSystem::adjoint_solve(qoi_indices); 139 : } 140 : 141 0 : void TimeSolver::integrate_qoi_timestep() 142 : { 143 0 : libmesh_not_implemented(); 144 : } 145 : 146 0 : void TimeSolver::integrate_adjoint_sensitivity(const QoISet & /* qois */, const ParameterVector & /* parameter_vector */, SensitivityData & /* sensitivities */) 147 : { 148 0 : libmesh_not_implemented(); 149 : } 150 : 151 : #ifdef LIBMESH_ENABLE_AMR 152 0 : void TimeSolver::integrate_adjoint_refinement_error_estimate 153 : (AdjointRefinementEstimator & /* adjoint_refinement_error_estimator */, 154 : ErrorVector & /* QoI_elementwise_error */) 155 : { 156 0 : libmesh_not_implemented(); 157 : } 158 : #endif // LIBMESH_ENABLE_AMR 159 : 160 34580 : Real TimeSolver::last_completed_timestep_size() 161 : { 162 34580 : return last_deltat; 163 : } 164 : 165 0 : void TimeSolver::adjoint_advance_timestep () 166 : { 167 0 : } 168 : 169 0 : void TimeSolver::retrieve_timestep () 170 : { 171 0 : } 172 : 173 : } // namespace libMesh