PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
IP_SSATaucForwardProblem.hh
Go to the documentation of this file.
1 // Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2020, 2021, 2022, 2023 David Maxwell and Constantine Khroulev
2 //
3 // This file is part of PISM.
4 //
5 // PISM is free software; you can redistribute it and/or modify it under the
6 // terms of the GNU General Public License as published by the Free Software
7 // Foundation; either version 3 of the License, or (at your option) any later
8 // version.
9 //
10 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with PISM; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #ifndef IP_SSATAUCFORWARDPROBLEM_HH_4AEVR4Z
20 #define IP_SSATAUCFORWARDPROBLEM_HH_4AEVR4Z
21 
22 #include "pism/stressbalance/ssa/SSAFEM.hh"
23 #include "pism/inverse/IPDesignVariableParameterization.hh"
24 #include "pism/util/petscwrappers/KSP.hh"
25 #include "pism/util/petscwrappers/Mat.hh"
26 
27 namespace pism {
28 namespace inverse {
29 
30 //! Implements the forward problem of the map taking \f$\tau_c\f$ to the corresponding solution of the %SSA.
31 /*! The class SSAFEM solves the %SSA, and the solution depends on a large number of parameters. Considering
32  all of these to be fixed except for \f$\tau_c\f$, we obtain a map \f$F_{\rm SSA}\f$ taking
33  \f$\tau_c\f$ to the corresponding solution \f$u_{\rm SSA}\f$ of the %SSA. This is a forward problem which
34  we would like to invert; given \f$u_{\rm SSA}\f$ determine \f$\tau_c\f$ such that
35  \f$F_{\rm SSA}(\tau_c) = u_{\rm SSA}\f$. The forward problem actually implemented by
36  IP_SSATaucForwardProblem is a mild variation \f$F_{\rm SSA}\f$.
37 
38  First, given the constraint \f$\tau_c\ge 0\f$ it can be helpful to parameterize \f$\tau_c\f$ by some other
39  parameter \f$\zeta\f$,
40  \f[
41  \tau_c = g(\zeta),
42  \f]
43  where the function \f$g\f$ is non-negative. The function \f$g\f$ is specified by an instance
44  of IPDesignVariableParameterization.
45 
46  Second, there may be locations where the value of \f$\tau_c\f$ (and hence \f$\zeta\f$)
47  is known a-priori, and should not be adjusted. Let \f$\pi\f$ be the map that replaces
48  the values of \f$\zeta\f$ with known values at these locations.
49 
50  IP_SSATaucForwardProblem implements the forward problem
51  \f[
52  F(\zeta) = F_{\rm SSA}(g(\pi(\zeta))).
53  \f]
54 
55  Algorithms to solve the inverse problem make use of variations on the linearization
56  of \f$F\f$, which are explained below.
57 
58  The solution of the %SSA in SSAFEM is implemented using SNES to solve
59  a nonlinear residual function of the form
60  \f[
61  \mathcal{R}_{SSA}(u;\tau_c, \text{other parameters})= \vec 0,
62  \f]
63  usually using Newton's method. Let
64  \f[
65  \mathcal{R}(u, \zeta) = \mathcal{R}_{SSA}(u; g(\pi(\zeta)), \text{other parameters}).
66  \f]
67 
68  The derivative of \f$\mathcal{R}\f$ with respect to \f$ u\f$ is called the state Jacobian,
69  \f$J_{\rm State}\f$. Specifically, if \f$u=[U_j]\f$ then
70  \f[
71  (J_{\rm State})_{ij} = \frac{d \mathcal{R}_i}{dU_j}.
72  \f]
73  This is exactly the same Jacobian that is computed by SSAFEM for solving the %SSA via SNES. The
74  matrix for the design Jacobian can be obtained with \ref assemble_jacobian_state.
75 
76  The derivative of \f$\mathcal{R}\f$ with respect to \f$ \zeta\f$ is called the design Jacobian,
77  \f$J_{\rm Design}\f$. Specifically, if \f$\zeta=[Z_k]\f$ then
78  \f[
79  (J_{\rm Design})_{ik} = \frac{d \mathcal{R}_i}{dZ_k}.
80  \f]
81  The map \f$J_{\rm Design}\f$ can be applied to a vector \f$d\zeta\f$ with
82  apply_jacobian_design. For inverse methods using adjoints, one also
83  needs to be able to apply the transpose of \f$J_{\rm Design}\f$,
84  which is done using \ref apply_jacobian_design_transpose.
85 
86  The forward problem map \f$F\f$ solves the implicit equation
87  \f[
88  \mathcal{R}(F(\zeta), \zeta) = 0.
89  \f]
90  Its linearisation \f$DF\f$ then satisfies
91  \f[
92  J_{\rm State}\; DF\; d\zeta + J_{\rm Design}\; d\zeta = 0
93  \f]
94  for any perturbation \f$d\zeta\f$. Hence
95  \f[
96  DF = -J_{\rm State}^{-1}\circ J_{\rm Design}.
97  \f]
98  This derivative is sometimes called the reduced gradient in the literature. To
99  apply \f$DF\f$ to a perturbation \f$d\zeta\f$, use \ref apply_linearization. Adjoint
100  methods require the transpose of this map; to apply \f$DF^t\f$ to \f$du\f$ use
101  \ref apply_linearization_transpose.
102 */
104 {
105 public:
106 
107  /// The function space for the design variable, i.e. \f$\tau_c\f$.
110 
111  /// The function space for the state variable, \f$u_{\rm SSA}\f$.
114 
115  //! Constructs from the same objects as SSAFEM, plus a specification of how \f$\tau_c\f$
116  //! is parameterized.
117  IP_SSATaucForwardProblem(std::shared_ptr<const Grid> g,
119 
120  virtual ~IP_SSATaucForwardProblem() = default;
121 
122  void init();
123 
124  //! Selects nodes where \f$\tau_c\f$ (more specifically \f$\zeta\f$) should not be adjusted.
125  /*! The paramter \a locations should be set to 1 at each node where \f$\tau_c\f$
126  is fixed. The forward map then effectively treats the design space as the subspace
127  of nodes where \a locations is 0. Tangent vectors to this subspace, as would be
128  generated by, e.g., \f$J_{\rm Design}^t\f$ are represented as vectors in the full
129  space with entries set to zero in the fixed locations. These can safely be added
130  to preexisting values of \f$\zeta\f$ without changing the entries of \f$\zeta\f$ at the
131  fixed locations. Inversion can be done by setting an initial value of \f$\zeta\f$
132  having the desired values in the fixed locations, and using set_tauc_fixed_locations()
133  to indicate the nodes that should not be changed.
134  */
135  virtual void set_tauc_fixed_locations(array::Scalar &locations)
136  {
137  m_fixed_tauc_locations = &locations;
138  }
139 
140  //! Returns the last solution of the %SSA as computed by \ref linearize_at.
141  virtual std::shared_ptr<array::Vector> solution() {
142  m_velocity_shared->copy_from(m_velocity);
143  return m_velocity_shared;
144  }
145 
146  //! Exposes the \f$\tau_c\f$ parameterization being used.
148  return m_tauc_param;
149  }
150 
151  virtual void set_design(array::Scalar &zeta);
152 
153  virtual std::shared_ptr<TerminationReason> linearize_at(array::Scalar &zeta);
154 
155  virtual void assemble_residual(array::Vector &u, array::Vector &R);
156  virtual void assemble_residual(array::Vector &u, Vec R);
157 
158  virtual void assemble_jacobian_state(array::Vector &u, Mat J);
159 
160  virtual void apply_jacobian_design(array::Vector &u, array::Scalar &dzeta, array::Vector &du);
161  virtual void apply_jacobian_design(array::Vector &u, array::Scalar &dzeta, Vec du);
162  virtual void apply_jacobian_design(array::Vector &u, array::Scalar &dzeta, Vector2d **du_a);
163 
165  virtual void apply_jacobian_design_transpose(array::Vector &u, array::Vector &du, Vec dzeta);
166  virtual void apply_jacobian_design_transpose(array::Vector &u, array::Vector &du, double **dzeta);
167 
168  virtual void apply_linearization(array::Scalar &dzeta, array::Vector &du);
170 
171  //! Exposes the DMDA of the underlying grid for the benefit of TAO.
172  petsc::DM& get_da() const {
173  return *m_da;
174  }
175 
176 protected:
177 
178  /// Current value of zeta, provided from caller.
180  /// Storage for d_zeta with ghosts, if needed when an argument d_zeta is ghost-less.
182  /// Storage for tauc (avoids modifying fields obtained via pism::Vars)
184 
185  /// Locations where \f$\tau_c\f$ should not be adjusted.
187 
188  /// The function taking \f$\zeta\f$ to \f$\tau_c\f$.
190 
191  /// Copy of the velocity field managed using a shared pointer.
192  std::shared_ptr<array::Vector> m_velocity_shared;
193 
194  /// Temporary storage when state vectors need to be used without ghosts.
196  /// Temporary storage when state vectors need to be used with ghosts.
198 
201 
202  /// KSP used in \ref apply_linearization and \ref apply_linearization_transpose
204  /// Mat used in \ref apply_linearization and \ref apply_linearization_transpose
206 
207  SNESConvergedReason m_reason;
208 
209  /// Flag indicating that the state jacobian matrix needs rebuilding.
211 };
212 
213 } // end of namespace inverse
214 } // end of namespace pism
215 
216 #endif /* end of include guard: IP_SSATAUCFORWARDPROBLEM_HH_4AEVR4Z */
This class represents a 2D vector field (such as ice velocity) at a certain grid point.
Definition: Vector2d.hh:29
Manages iterating over element indices.
Q1 element with sides parallel to X and Y axes.
Definition: Element.hh:257
virtual void apply_jacobian_design(array::Vector &u, array::Scalar &dzeta, array::Vector &du)
Applies the design Jacobian matrix to a perturbation of the design variable.
virtual void apply_jacobian_design_transpose(array::Vector &u, array::Vector &du, array::Scalar &dzeta)
Applies the transpose of the design Jacobian matrix to a perturbation of the state variable.
array::Scalar * m_fixed_tauc_locations
Locations where should not be adjusted.
IPDesignVariableParameterization & m_tauc_param
The function taking to .
virtual std::shared_ptr< array::Vector > solution()
Returns the last solution of the SSA as computed by linearize_at.
bool m_rebuild_J_state
Flag indicating that the state jacobian matrix needs rebuilding.
virtual void set_tauc_fixed_locations(array::Scalar &locations)
Selects nodes where (more specifically ) should not be adjusted.
array::Scalar * m_zeta
Current value of zeta, provided from caller.
petsc::KSP m_ksp
KSP used in apply_linearization and apply_linearization_transpose.
virtual void apply_linearization(array::Scalar &dzeta, array::Vector &du)
Applies the linearization of the forward map (i.e. the reduced gradient described in the class-level...
petsc::DM & get_da() const
Exposes the DMDA of the underlying grid for the benefit of TAO.
virtual IPDesignVariableParameterization & tauc_param()
Exposes the parameterization being used.
petsc::Mat m_J_state
Mat used in apply_linearization and apply_linearization_transpose.
virtual void assemble_residual(array::Vector &u, array::Vector &R)
Computes the residual function as defined in the class-level documentation.
virtual std::shared_ptr< TerminationReason > linearize_at(array::Scalar &zeta)
Sets the current value of the design variable and solves the SSA to find the associated .
std::shared_ptr< array::Vector > m_velocity_shared
Copy of the velocity field managed using a shared pointer.
array::Scalar DesignVec
The function space for the design variable, i.e. .
virtual void apply_linearization_transpose(array::Vector &du, array::Scalar &dzeta)
Applies the transpose of the linearization of the forward map (i.e. the transpose of the reduced grad...
array::Vector1 m_du_local
Temporary storage when state vectors need to be used with ghosts.
array::Vector m_du_global
Temporary storage when state vectors need to be used without ghosts.
IP_SSATaucForwardProblem(std::shared_ptr< const Grid > g, IPDesignVariableParameterization &tp)
array::Vector StateVec
The function space for the state variable, .
virtual void set_design(array::Scalar &zeta)
Sets the current value of of the design paramter .
array::Scalar1 m_dzeta_local
Storage for d_zeta with ghosts, if needed when an argument d_zeta is ghost-less.
virtual void assemble_jacobian_state(array::Vector &u, Mat J)
Assembles the state Jacobian matrix.
array::Scalar2 m_tauc_copy
Storage for tauc (avoids modifying fields obtained via pism::Vars)
Implements the forward problem of the map taking to the corresponding solution of the SSA.
PISM's SSA solver: the finite element method implementation written by Jed and David.
Definition: SSAFEM.hh:40
std::shared_ptr< petsc::DM > m_da
Definition: SSA.hh:149
static const double g
Definition: exactTestP.cc:36
const int J[]
Definition: ssafd_code.cc:34