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
IPFunctional.hh
Go to the documentation of this file.
1// Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2020, 2022, 2025 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 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 PISM_IPFUNCTIONAL_H
20#define PISM_IPFUNCTIONAL_H
21
22#include "pism/util/fem/Element.hh"
23#include "pism/util/fem/Quadrature.hh"
24#include "pism/util/fem/ElementIterator.hh"
25#include "pism/util/array/Vector.hh"
26
27namespace pism {
28
29class Grid;
30
31//! Inverse modeling code.
32namespace inverse {
33//! Abstract base class for functions from ice model vectors to \f$\mathbb{R}\f$.
34/*! Inverse problems frequently involve minimizing a functional,
35 such such as the misfit
36 \f[
37 J(u) = \int_\Omega |u-u_{\rm obs}|^2
38 \f]
39 between observed (\f$u_{\rm obs}\f$) and modeled (\f$u\f$)
40 surface velocities. Subclasses of IPFunctional define such maps,
41 and permit computation of their gradients.
42*/
43template<class IMVecType>
45
46public:
47 IPFunctional(std::shared_ptr<const Grid> grid)
48 : m_grid(grid),
50 m_element(*m_grid, fem::Q1Quadrature4())
51 {
52 // empty
53 }
54
55 virtual ~IPFunctional() {};
56
57 //! Computes the value of the functional at the vector x.
58 virtual void valueAt(IMVecType &x, double *OUTPUT) = 0;
59
60 //! Computes the gradient of the functional at the vector x.
61 /*! On an \f$m\times n\f$ Grid, an array::Array \f$x\f$ with \f$d\f$
62 degrees of freedom will be \f$d m n\f$-dimensional with components \f$x_i\f$.
63 The gradient computed here is the vector of directional derivatives \f$\nabla J\f$ of the functional
64 \f$J\f$ with respect to \f$x\f$. Concretely, the \f$i^{\rm th}\f$ component of \f$\nabla J\f$
65 is
66 \f[
67 \nabla J_i = \frac{\partial}{\partial x_i} J(x).
68 \f]
69 This vector is returned as `gradient`.
70 */
71 virtual void gradientAt(IMVecType &x, IMVecType &gradient) = 0;
72
73protected:
74 std::shared_ptr<const Grid> m_grid;
75
78
79private:
80 // Hide copy/assignment operations
83
84};
85
86//! Abstract base class for IPFunctionals arising from an inner product.
87/*!
88 Frequently functionals have the structure
89 \f[
90 J(u) = Q(u, u)
91 \f]
92 where \f$Q\f$ is a symmetric, non-negative definite, bilinear form. Certain
93 minimization algorithms only apply to such functionals, which should subclass
94 from IPInnerProductFunctional.
95*/
96template<class IMVecType>
97class IPInnerProductFunctional : public IPFunctional<IMVecType> {
98
99public:
100 IPInnerProductFunctional(std::shared_ptr<const Grid> grid) : IPFunctional<IMVecType>(grid) {};
101
102 //! Computes the inner product \f$Q(a, b)\f$.
103 virtual void dot(IMVecType &a, IMVecType &b, double *OUTPUT) = 0;
104
105 //! Computes the interior product of a vector with the IPInnerProductFunctional's underlying bilinear form.
106 /*! If \f$Q(x, y)\f$ is a bilinear form, and \f$a\f$ is a vector, then the
107 interior product of \f$a\f$ with \f$Q\f$ is the functional
108 \f[
109 I(z) = Q(a, z).
110 \f]
111 Such a functional is always linear and hence can be represented by taking
112 the standard dot product with some vector \f$y\f$:
113 \f[
114 I(z) = y^T z.
115 \f]
116 This method returns the vector \f$y\f$.
117 */
118 virtual void interior_product(IMVecType &x, IMVecType &y) {
119 this->gradientAt(x, y);
120 y.scale(0.5);
121 }
122
123 // Assembles the matrix \f$Q_{ij}\f$ corresponding to the bilinear form.
124 /* If \f$\{x_i\}\f$ is a basis for the vector space IMVecType,
125 \f$Q_{ij}= Q(x_i, x_j)\f$. */
126 // virtual void assemble_form(Mat Q) = 0;
127
128};
129
130//! Computes finite difference approximations of a IPFunctional<array::Scalar> gradient.
131/*! Useful for debugging a hand coded gradient. */
132void gradientFD(IPFunctional<array::Scalar> &f, array::Scalar &x, array::Scalar &gradient);
133
134//! Computes finite difference approximations of a IPFunctional<array::Vector> gradient.
135/*! Useful for debugging a hand coded gradient. */
136void gradientFD(IPFunctional<array::Vector> &f, array::Vector &x, array::Vector &gradient);
137
138} // end of namespace inverse
139} // end of namespace pism
140
141#endif // PISM_IPFUNCTIONAL_H
Manages iterating over element indices.
Q1 element with sides parallel to X and Y axes.
Definition Element.hh:264
IPFunctional & operator=(IPFunctional const &)
virtual void valueAt(IMVecType &x, double *OUTPUT)=0
Computes the value of the functional at the vector x.
IPFunctional(std::shared_ptr< const Grid > grid)
IPFunctional(IPFunctional const &)
virtual void gradientAt(IMVecType &x, IMVecType &gradient)=0
Computes the gradient of the functional at the vector x.
fem::ElementIterator m_element_index
std::shared_ptr< const Grid > m_grid
Abstract base class for functions from ice model vectors to .
virtual void dot(IMVecType &a, IMVecType &b, double *OUTPUT)=0
Computes the inner product .
virtual void interior_product(IMVecType &x, IMVecType &y)
Computes the interior product of a vector with the IPInnerProductFunctional's underlying bilinear for...
IPInnerProductFunctional(std::shared_ptr< const Grid > grid)
Abstract base class for IPFunctionals arising from an inner product.
void gradientFD(IPFunctional< array::Scalar > &f, array::Scalar &x, array::Scalar &gradient)
Computes finite difference approximations of a IPFunctional<array::Scalar> gradient.