https://mooseframework.inl.gov
Loading...
Searching...
No Matches
AdjointTransientSolve.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11
12#include "FEProblemBase.h"
13#include "NonlinearSystemBase.h"
14#include "MooseUtils.h"
15
16#include "libmesh/sparse_matrix.h"
17#include "libmesh/numeric_vector.h"
18
19using namespace libMesh;
20
27
29 : AdjointSolve(ex),
30 Restartable(this, "Executioners"),
31 _old_time_residual(_nl_adjoint.getResidualTimeVector()),
32 _forward_solutions(declareRecoverableData<std::vector<std::string>>("forward_solutions"))
33{
34}
35
36bool
38{
39 bool converged = AdjointSolve::solve();
40
41 // Gather the contribution of this timestep to add to the next solve's source
42 if (converged)
44
45 return converged;
46}
47
48void
50{
51 // Time step should not be negative
52 if (tstep < 0)
53 mooseError("Negative time step occurred.");
54 auto t_step = cast_int<std::size_t>(tstep); // Avoid compiler warnings
55 // Should not be inserting a time greater the last one inserted
56 if (t_step > _forward_solutions.size())
57 mooseError("Trying to insert a solution at a time-step greater than one past the previously "
58 "inserted time step. Previous time step = ",
59 (int)_forward_solutions.size() - 1,
60 ", inserted time step = ",
61 t_step,
62 ".");
63
64 // Add vector name to member variable if this time has not occurred
65 if (t_step == _forward_solutions.size())
67
68 // Get/add vector from/to adjoint system
69 auto & solution = _nl_adjoint.addVector(_forward_solutions[t_step], false, PARALLEL);
70
71 // Set the vector to the inserted solution
72 solution = _nl_forward.solution();
73}
74
75void
77{
78 // Make sure the time step was saved
79 if (tstep < 0 || tstep >= cast_int<int>(_forward_solutions.size()))
80 mooseError("Could not find forward solution at time step ", tstep, ".");
81 auto t_step = cast_int<std::size_t>(tstep); // Avoid compiler warnings
82
83 // Copy the solutions to states that exist in the system
84 unsigned int state = 0;
85 while (_nl_forward.hasSolutionState(state))
86 {
87 const auto & name = t_step > state ? _forward_solutions[t_step - state] : _forward_solutions[0];
89 state++;
90 }
91
93}
94
95void
97 const NumericVector<Number> & solution,
99{
100 // Assemble the steady-state version of the adjoint problem
101 AdjointSolve::assembleAdjointSystem(matrix, solution, rhs);
102 // Add the contribution from old solutions
103 rhs += _old_time_residual;
104}
105
106void
108 NumericVector<Number> & residual)
109{
110 // This tag should exist, but the matrix might not necessarily be added
111 auto time_matrix_tag = _problem.getMatrixTagID("TIME");
112 // Use the adjoint system matrix to hold the time Jacobian
113 auto & time_matrix = static_cast<ImplicitSystem &>(_nl_adjoint.system()).get_system_matrix();
114
115 // Make sure we tell the problem which system we are evaluating
117 // Accumulate the time part of the Jacobian into the adjoint matrix
118 _problem.computeJacobianTag(*_nl_forward.currentSolution(), time_matrix, time_matrix_tag);
119
120 // Perform multiplication of the adjoint solution on the transpose of the time Jacobian
121 residual.zero();
122 residual.add_vector_transpose(solution, time_matrix);
123}
The solve object is responsible for solving the adjoint version of a forward model.
virtual bool solve() override
Solve the adjoint system with the following procedure:
const unsigned int _forward_sys_num
The number of the nonlinear system representing the forward model.
NonlinearSystemBase & _nl_forward
The nonlinear system representing the forward model.
virtual void assembleAdjointSystem(SparseMatrix< Number > &matrix, const NumericVector< Number > &solution, NumericVector< Number > &rhs)
Assembles adjoint system.
NonlinearSystemBase & _nl_adjoint
The nonlinear system representing the adjoint model.
static InputParameters validParams()
void evaluateTimeResidual(const NumericVector< Number > &solution, NumericVector< Number > &residual)
This evaluates the time part of the adjoint residual.
AdjointTransientSolve(Executioner &ex)
void setForwardSolution(int tstep)
Takes the previously saved forward solutions residing in the adjoint system and copies them to the av...
virtual bool solve() override
Overriding parent class so the time-derivative residual is stored for the next time step.
static InputParameters validParams()
std::vector< std::string > & _forward_solutions
Name of the forward solution at each time step residing in the adjoint system.
NumericVector< Number > & _old_time_residual
The residual contribution from previous adjoint solutions.
static std::string getForwardSolutionName(int tstep)
Prescribed name of the forward solution at a specified time step.
virtual void assembleAdjointSystem(SparseMatrix< Number > &matrix, const NumericVector< Number > &solution, NumericVector< Number > &rhs) override
Overriding parent class so the previous time-derivative residual is added to the right-hand-side of t...
void insertForwardSolution(int tstep)
This function should be called after every converged forward time step.
void setCurrentNonlinearSystem(const unsigned int nl_sys_num)
virtual void computeJacobianTag(const NumericVector< libMesh::Number > &soln, libMesh::SparseMatrix< libMesh::Number > &jacobian, TagID tag)
const std::string & name() const
void mooseError(Args &&... args) const
virtual libMesh::System & system() override
FEProblemBase & _problem
virtual const NumericVector< Number > *const & currentSolution() const override final
virtual TagID getMatrixTagID(const TagName &tag_name) const
virtual NumericVector< Number > & getVector(const std::string &name)
virtual NumericVector< Number > & solutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time)
virtual bool hasSolutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time) const
NumericVector< Number > & solution()
NumericVector< Number > & addVector(const std::string &vector_name, const bool project, const libMesh::ParallelType type)
virtual void add_vector_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A)=0
virtual void zero()=0
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...