Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
IP_SSAHardavForwardProblem.hh
Go to the documentation of this file.
1// Copyright (C) 2013, 2014, 2015, 2016, 2017, 2020, 2021, 2022, 2023, 2024 David Maxwell
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 2 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_SSAHARDAVFORWARDPROBLEM_HH_HAD68BK7
20#define IP_SSAHARDAVFORWARDPROBLEM_HH_HAD68BK7
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
27namespace pism {
28namespace 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_SSAHardavForwardProblem 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_SSAHardavForwardProblem 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{
105public:
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$ is parameterized.
116 IP_SSAHardavForwardProblem(std::shared_ptr<const Grid> g,
118
119 virtual ~IP_SSAHardavForwardProblem() = default;
120
121 //! Selects nodes where \f$\tau_c\f$ (more specifically \f$\zeta\f$) should not be adjusted.
122 /*! The paramter \a locations should be set to 1 at each node where \f$\tau_c\f$
123 is fixed. The forward map then effectively treats the design space as the subspace
124 of nodes where \a locations is 0. Tangent vectors to this subspace, as would be
125 generated by, e.g., \f$J_{\rm Design}^t\f$ are represented as vectors in the full
126 space with entries set to zero in the fixed locations. These can safely be added
127 to preexisting values of \f$\zeta\f$ without changing the entries of \f$\zeta\f$ at the
128 fixed locations. Inversion can be done by setting an initial value of \f$\zeta\f$
129 having the desired values in the fixed locations, and using set_tauc_fixed_locations()
130 to indicated the nodes that should not be changed.
131 */
133 {
134 m_fixed_design_locations = &locations;
135 }
136
137 //! Returns the last solution of the %SSA as computed by \ref linearize_at.
138 virtual std::shared_ptr<array::Vector> solution() {
139 m_velocity_shared->copy_from(m_velocity);
140 return m_velocity_shared;
141 }
142
143 //! Exposes the design variable parameterization being used.
147
148 void init();
149
150 virtual void set_design(array::Scalar &zeta);
151
152 virtual std::shared_ptr<TerminationReason> linearize_at(array::Scalar &zeta);
153
154 virtual void assemble_residual(array::Vector &u, array::Vector &R);
155 virtual void assemble_residual(array::Vector &u, Vec R);
156
157 virtual void assemble_jacobian_state(array::Vector &u, Mat J);
158
160 virtual void apply_jacobian_design(array::Vector &u, array::Scalar &dzeta, Vec du);
161 virtual void apply_jacobian_design(array::Vector &u, array::Scalar &dzeta, Vector2d **du_a);
162
164 virtual void apply_jacobian_design_transpose(array::Vector &u, array::Vector &du, Vec dzeta);
165 virtual void apply_jacobian_design_transpose(array::Vector &u, array::Vector &du, double **dzeta);
166
167 virtual void apply_linearization(array::Scalar &dzeta, array::Vector &du);
169
170 //! Exposes the DMDA of the underlying grid for the benefit of TAO.
171 petsc::DM& get_da() const {
172 return *m_velocity_global.dm();
173 }
174
175protected:
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
183 /// Locations where \f$\tau_c\f$ should not be adjusted.
185
186 /// The function taking \f$\zeta\f$ to \f$\tau_c\f$.
188
189 std::shared_ptr<array::Vector> m_velocity_shared;
190
191 /// Temporary storage when state vectors need to be used without ghosts.
193 /// Temporary storage when state vectors need to be used with ghosts.
195 /// Vertically-averaged ice hardness.
197
200
201 /// KSP used in \ref apply_linearization and \ref apply_linearization_transpose
203 /// Mat used in \ref apply_linearization and \ref apply_linearization_transpose
205
206 SNESConvergedReason m_reason;
207
208 /// Flag indicating that the state jacobian matrix needs rebuilding.
210};
211
212} // end of namespace inverse
213} // end of namespace pism
214
215#endif /* end of include guard: IP_SSAHARDAVFORWARDPROBLEM_HH_HAD68BK7 */
This class represents a 2D vector field (such as ice velocity) at a certain grid point.
Definition Vector2d.hh:29
std::shared_ptr< petsc::DM > dm() const
Definition Array.cc:324
Manages iterating over element indices.
Q1 element with sides parallel to X and Y axes.
Definition Element.hh:264
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 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::Vector m_du_global
Temporary storage when state vectors need to be used without ghosts.
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...
virtual void assemble_jacobian_state(array::Vector &u, Mat J)
Assembles the state Jacobian matrix.
IPDesignVariableParameterization & m_design_param
The function taking to .
array::Scalar DesignVec
The function space for the design variable, i.e. .
array::Scalar1 m_hardav
Vertically-averaged ice hardness.
array::Scalar * m_fixed_design_locations
Locations where should not be adjusted.
array::Scalar1 m_dzeta_local
Storage for d_zeta with ghosts, if needed when an argument d_zeta is ghost-less.
virtual IPDesignVariableParameterization & design_param()
Exposes the design variable parameterization being used.
virtual void set_design_fixed_locations(array::Scalar &locations)
Selects nodes where (more specifically ) should not be adjusted.
virtual std::shared_ptr< array::Vector > solution()
Returns the last solution of the SSA as computed by linearize_at.
array::Vector StateVec
The function space for the state variable, .
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 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 .
array::Scalar * m_zeta
Current value of zeta, provided from caller.
bool m_rebuild_J_state
Flag indicating that the state jacobian matrix needs rebuilding.
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...
virtual void set_design(array::Scalar &zeta)
Sets the current value of of the design paramter .
petsc::DM & get_da() const
Exposes the DMDA of the underlying grid for the benefit of TAO.
array::Vector1 m_du_local
Temporary storage when state vectors need to be used with ghosts.
petsc::KSP m_ksp
KSP used in apply_linearization and apply_linearization_transpose.
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:38
array::Vector m_velocity_global
Definition SSA.hh:133
static const double g
Definition exactTestP.cc:36