PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
IPDesignVariableParameterization.hh
Go to the documentation of this file.
1 // Copyright (C) 2011, 2012, 2013, 2014, 2015, 2020 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 
20 #ifndef IPTAUCPARAMETERIZATION_HH_7ZRETI1S
21 #define IPTAUCPARAMETERIZATION_HH_7ZRETI1S
22 
23 #include <string>
24 
25 namespace pism {
26 
27 class Config;
28 namespace array { class Scalar; }
29 
30 namespace inverse {
31 
32 //! Encapsulates a parameterization of a design variable (e.g. \f$\tau_c\f$ for SSA inversions)
33 //! as a function of a different parameter \f$\zeta\f$.
34 /*!
35  When solving an inverse problem for a design variable \f$d\f$ (think of
36  \f$\tau_c\f$ or hardness for SSA inversions), one frequently does
37  not work with \f$d\f$ directly but with a different
38  variable \f$\zeta\f$, and a relationship \f$d=g(\zeta)\f$.
39  A common choice in the glaciology literature for \f$\tau_c\f$
40  is \f$\tau_c=g(\zeta)=\zeta^2\f$, which ensures that \f$\tau_c\f$ is
41  non-negative, but has the disadvantage that it is a 2-1 parameterization. A potentially
42  more satisfactory choice is \f$g(\zeta)=e^\zeta\f$, which ensures
43  positivitiy, is 1-1, and respects the wide scale variations of \f$\tau_c\f$.
44 
45  An IPDesignVariableParameterization implements such a parameterization map.
46 
47  This method of encoding mathematical expressions is flexible and convenient,
48  but is also slow; it has the overhead that many virtual function calls are
49  needed if the expression is being called over and over again. If this
50  proves to be a significant source of slowness, we could look at
51  using the Expression Template idiom, http://drdobbs.com/184401627.
52 
53  For certain Tikhonov inversions, it is important to mainain well-scaled
54  variables. If the design parameter name is 'foo', internally the parameterizations
55  use units of \f$d\f$ such that the config parameter \a design_param_foo_scale equals one. I.e.
56  if 'foo' is 'tauc', then for a conversion function \f$g(\zeta)=\zeta^2\f$,
57  \f[
58  \frac{d} = d_{\rm scale}g(\zeta^2).
59  \f]
60  where \f$d_{\rm scale}={\tt design_param_tauc_scale}\f$.
61 */
63 {
64 public:
65 
67 
69 
70  virtual void set_scales(const Config &config, const std::string &design_var_name);
71 
72  //! Converts from parameterization value \f$\zeta\f$ to \f$d=g(\zeta)\f$.
73  /*!
74  \param[in] zeta The parameter value.
75  \param[out] value The value \f$g(\zeta)\f$.
76  \param[out] derivative The value \f$g'(\zeta)\f$. */
77  virtual void toDesignVariable(double zeta, double *value, double *derivative) = 0;
78 
79  //! Converts from \f$d\f$ to a parameterization value \f$\zeta\f$ such that \f$d=g(\zeta)\f$.
80  /*! More than one such \f$\zeta\f$ may exist; only one is returned. */
81  virtual void fromDesignVariable(double d, double *OUTPUT) = 0;
82 
83  virtual void convertToDesignVariable(array::Scalar &zeta, array::Scalar &d, bool communicate = true);
84 
85  virtual void convertFromDesignVariable(array::Scalar &d, array::Scalar &zeta, bool communicate = true);
86 protected:
87 
88  /// Value of \f$d\f$ in PISM units that equals 1 for IPDesignVariableParameterization's units.
89  double m_d_scale;
90 };
91 
92 //! Parameterization \f$d=d_{\rm scale}g(\zeta)\f$ with \f$g(\zeta)=\zeta\f$.
94 {
95 public:
96  IPDesignVariableParamIdent() { /*do nothing*/ };
97 
99 
100  virtual void toDesignVariable(double p, double *value, double *derivative);
101 
102  virtual void fromDesignVariable(double tauc, double *OUTPUT);
103 };
104 
105 //! Parameterization \f$\tau_c=\tau_{\rm scale}g(\zeta)\f$ with \f$g(\zeta)=\zeta^2\f$.
107 {
108 public:
109  IPDesignVariableParamSquare() { /*do nothing*/ };
110 
112 
113  virtual void toDesignVariable(double p, double *value, double *derivative);
114 
115  virtual void fromDesignVariable(double tauc, double *OUTPUT);
116 };
117 
118 //! Parameterization \f$\tau_c=\tau_{\rm scale}g(\zeta)\f$ with \f$g(\zeta)=\exp(\zeta)\f$.
120 {
121 public:
122  IPDesignVariableParamExp() { /*do nothing*/ };
123 
125 
126  virtual void set_scales(const Config &config, const std::string &design_var_name);
127 
128  virtual void toDesignVariable(double p, double *value, double *derivative);
129 
130  virtual void fromDesignVariable(double tauc, double *OUTPUT);
131 
132 private:
133  double m_d_eps;
134 };
135 
136 
137 //! A monotone non-negative parameterization \f$\tau_c=\tau_{\rm scale}g(\zeta)\f$ that is approximately the identity away from small values of \f$\tau_c\f$
138 /*! More specifically, \f$g(\zeta)\rightarrow 0\f$ as \f$\zeta\rightarrow-\infty\f$ and \f$g(\zeta)\approx p\f$
139  for large values of \f$\zeta\f$. The transition from a nonlinear to an approximately linear
140  function occurs in the neighbourhood of the parameter \f$d_0\f$. */
142 {
143 public:
145 
147 
148  virtual void set_scales(const Config &config, const std::string &design_var_name);
149 
150  virtual void toDesignVariable(double p, double *value, double *derivative);
151 
152  virtual void fromDesignVariable(double d, double *OUTPUT);
153 
154 private:
155  double m_d0_sq;
156  double m_d_eps;
157 };
158 
159 } // end of namespace inverse
160 } // end of namespace pism
161 
162 #endif /* end of include guard: IPTAUCPARAMETERIZATION_HH_7ZRETI1S */
A class for storing and accessing PISM configuration flags and parameters.
virtual void set_scales(const Config &config, const std::string &design_var_name)
Initializes the scale parameters of the parameterization.
virtual void toDesignVariable(double p, double *value, double *derivative)
Converts from parameterization value to .
virtual void fromDesignVariable(double tauc, double *OUTPUT)
Converts from to a parameterization value such that .
virtual void toDesignVariable(double p, double *value, double *derivative)
Converts from parameterization value to .
virtual void fromDesignVariable(double tauc, double *OUTPUT)
Converts from to a parameterization value such that .
virtual void toDesignVariable(double p, double *value, double *derivative)
Converts from parameterization value to .
virtual void fromDesignVariable(double tauc, double *OUTPUT)
Converts from to a parameterization value such that .
virtual void toDesignVariable(double p, double *value, double *derivative)
Converts from parameterization value to .
virtual void set_scales(const Config &config, const std::string &design_var_name)
Initializes the scale parameters of the parameterization.
virtual void fromDesignVariable(double d, double *OUTPUT)
Converts from to a parameterization value such that .
A monotone non-negative parameterization that is approximately the identity away from small values o...
double m_d_scale
Value of in PISM units that equals 1 for IPDesignVariableParameterization's units.
virtual void convertToDesignVariable(array::Scalar &zeta, array::Scalar &d, bool communicate=true)
Transforms a vector of values to a vector of values.
virtual void convertFromDesignVariable(array::Scalar &d, array::Scalar &zeta, bool communicate=true)
Transforms a vector of values to a vector of values.
virtual void fromDesignVariable(double d, double *OUTPUT)=0
Converts from to a parameterization value such that .
virtual void toDesignVariable(double zeta, double *value, double *derivative)=0
Converts from parameterization value to .
virtual void set_scales(const Config &config, const std::string &design_var_name)
Initializes the scale parameters of the parameterization.