https://mooseframework.inl.gov
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 
10 #include "AdjointTransientSolve.h"
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 
19 using namespace libMesh;
20 
23 {
25  return params;
26 }
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 
36 bool
38 {
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 
48 void
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 
75 void
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 
95 void
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 
106 void
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 }
virtual void computeJacobianTag(const NumericVector< libMesh::Number > &soln, libMesh::SparseMatrix< libMesh::Number > &jacobian, TagID tag)
const unsigned int _forward_sys_num
The number of the nonlinear system representing the forward model.
Definition: AdjointSolve.h:86
FEProblemBase & _problem
static InputParameters validParams()
Definition: AdjointSolve.C:27
NumericVector< Number > & solution()
PARALLEL
std::vector< std::string > & _forward_solutions
Name of the forward solution at each time step residing in the adjoint system.
virtual void add_vector_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A)=0
virtual NumericVector< Number > & solutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time)
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
AdjointTransientSolve(Executioner &ex)
static InputParameters validParams()
virtual const std::string & name() const
virtual void zero()=0
NumericVector< Number > & addVector(const std::string &vector_name, const bool project, const libMesh::ParallelType type)
bool converged(const std::vector< std::pair< unsigned int, Real >> &residuals, const std::vector< Real > &abs_tolerances)
Based on the residuals, determine if the iterative process converged or not.
static std::string getForwardSolutionName(int tstep)
Prescribed name of the forward solution at a specified time step.
void setCurrentNonlinearSystem(const unsigned int nl_sys_num)
virtual const NumericVector< Number > *const & currentSolution() const override final
virtual TagID getMatrixTagID(const TagName &tag_name) const
The solve object is responsible for solving the adjoint version of a forward model.
Definition: AdjointSolve.h:31
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...
virtual bool hasSolutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time) const
virtual bool solve() override
Solve the adjoint system with the following procedure:
Definition: AdjointSolve.C:79
void evaluateTimeResidual(const NumericVector< Number > &solution, NumericVector< Number > &residual)
This evaluates the time part of the adjoint residual.
void insertForwardSolution(int tstep)
This function should be called after every converged forward time step.
NumericVector< Number > & _old_time_residual
The residual contribution from previous adjoint solutions.
void setForwardSolution(int tstep)
Takes the previously saved forward solutions residing in the adjoint system and copies them to the av...
void mooseError(Args &&... args) const
virtual void assembleAdjointSystem(SparseMatrix< Number > &matrix, const NumericVector< Number > &solution, NumericVector< Number > &rhs)
Assembles adjoint system.
Definition: AdjointSolve.C:145
NonlinearSystemBase & _nl_adjoint
The nonlinear system representing the adjoint model.
Definition: AdjointSolve.h:92
virtual NumericVector< Number > & getVector(const std::string &name)
virtual bool solve() override
Overriding parent class so the time-derivative residual is stored for the next time step...
NonlinearSystemBase & _nl_forward
The nonlinear system representing the forward model.
Definition: AdjointSolve.h:90
virtual libMesh::System & system() override