Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.1-cd005eec8 committed by Constantine Khrulev on 2025-03-07
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
IPLogRatioFunctional.cc
Go to the documentation of this file.
1// Copyright (C) 2013, 2014, 2015, 2016, 2017, 2020, 2022, 2023 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#include "pism/inverse/functional/IPLogRatioFunctional.hh"
20#include "pism/util/Grid.hh"
21#include "pism/util/array/Vector.hh"
22#include "pism/util/array/Scalar.hh"
23#include "pism/util/pism_utilities.hh"
24
25namespace pism {
26namespace inverse {
27
28//! Determine the normalization constant for the functional.
29/*! Sets the normalization constant \f$c_N\f$ so that
30\f[
31J(x)=1
32\f]
33if \f$|x| = \mathtt{scale}|u_{\rm obs}| \f$ everywhere.
34*/
36
37 double value = 0;
38
39 double w = 1.0;
40
42
43 if (m_weights) {
44 list.add(*m_weights);
45 }
46
47 for (auto p = m_grid->points(); p; p.next()) {
48 const int i = p.i(), j = p.j();
49
50 if (m_weights) {
51 w = (*m_weights)(i, j);
52 }
53
54 Vector2d &u_obs_ij = m_u_observed(i, j);
55 double obsMagSq = u_obs_ij.u*u_obs_ij.u + u_obs_ij.v*u_obs_ij.v + m_eps*m_eps;
56
57 double modelMagSq = scale*scale*(u_obs_ij.u*u_obs_ij.u + u_obs_ij.v*u_obs_ij.v) + m_eps*m_eps;
58
59 double v = log(modelMagSq/obsMagSq);
60 value += w*v*v;
61 }
62
63 m_normalization = GlobalSum(m_grid->com, value);
64}
65
67
68 // The value of the objective
69 double value = 0;
70
71 double w = 1.;
72
74
75 if (m_weights) {
76 list.add(*m_weights);
77 }
78
79 for (auto p = m_grid->points(); p; p.next()) {
80 const int i = p.i(), j = p.j();
81
82 if (m_weights) {
83 w = (*m_weights)(i, j);
84 }
85 Vector2d &x_ij = x(i, j);
86 Vector2d &u_obs_ij = m_u_observed(i, j);
87 Vector2d u_model_ij = x_ij+u_obs_ij;
88 double obsMagSq = u_obs_ij.u*u_obs_ij.u + u_obs_ij.v*u_obs_ij.v + m_eps*m_eps;
89
90 double modelMagSq = (u_model_ij.u*u_model_ij.u + u_model_ij.v*u_model_ij.v)+m_eps*m_eps;
91 double v = log(modelMagSq/obsMagSq);
92 value += w*v*v;
93 }
94
95 value /= m_normalization;
96
97 GlobalSum(m_grid->com, &value, OUTPUT, 1);
98}
99
101 gradient.set(0);
102
103 double w = 1.;
104
105 array::AccessScope list{&x, &gradient, &m_u_observed};
106
107 if (m_weights) {
108 list.add(*m_weights);
109 }
110
111 for (auto p = m_grid->points(); p; p.next()) {
112 const int i = p.i(), j = p.j();
113
114 if (m_weights) {
115 w = (*m_weights)(i, j);
116 }
117 Vector2d &x_ij = x(i, j);
118 Vector2d &u_obs_ij = m_u_observed(i, j);
119 Vector2d u_model_ij = x_ij+u_obs_ij;
120
121 double obsMagSq = u_obs_ij.u*u_obs_ij.u + u_obs_ij.v*u_obs_ij.v + m_eps*m_eps;
122 double modelMagSq = (u_model_ij.u*u_model_ij.u + u_model_ij.v*u_model_ij.v)+m_eps*m_eps;
123 double v = log(modelMagSq/obsMagSq);
124 double dJdw = 2*w*v/modelMagSq;
125
126 gradient(i, j).u = dJdw*2*u_model_ij.u/m_normalization;
127 gradient(i, j).v = dJdw*2*u_model_ij.v/m_normalization;
128 }
129}
130
131} // end of namespace inverse
132} // end of namespace pism
This class represents a 2D vector field (such as ice velocity) at a certain grid point.
Definition Vector2d.hh:29
void add(const PetscAccessible &v)
Definition Array.cc:896
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition Array.hh:64
void add(double alpha, const Array2D< T > &x)
Definition Array2D.hh:65
void set(double c)
Result: v[j] <- c for all j.
Definition Array.cc:629
std::shared_ptr< const Grid > m_grid
virtual void normalize(double scale)
Determine the normalization constant for the functional.
virtual void valueAt(array::Vector &x, double *OUTPUT)
Computes the value of the functional at the vector x.
virtual void gradientAt(array::Vector &x, array::Vector &gradient)
Computes the gradient of the functional at the vector x.
void GlobalSum(MPI_Comm comm, double *local, double *result, int count)