tchanges-06-07.rst - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
 (HTM) git clone git://src.adamsgaard.dk/pism
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
       tchanges-06-07.rst (22241B)
       ---
            1 Changes from 0.6 (February 2014) to 0.7
            2 =======================================
            3 
            4 Most of the work on PISM since the release of v0.6 was aimed at making
            5 PISM easier to maintain, test, extend, and couple to other models. These
            6 changes consist of approximately 1200 individual Git commits. They
            7 touched over 650 files, more than half of PISM's C++ code (44,000 out of
            8 84,000 lines).
            9 
           10 All changes listed below are included in v0.7 (May 12, 2015) and later.
           11 Some changes listed below were included in v0.6.1 or v0.6.2.
           12 
           13 User-visible changes
           14 ~~~~~~~~~~~~~~~~~~~~
           15 
           16 Installing PISM
           17 ^^^^^^^^^^^^^^^
           18 
           19 -  Support PETSc 3.5.
           20 -  Support PETSc ``--with-64-bit-indices=1``
           21 -  Require PETSc >= 3.5 for TAO-based code.
           22 -  Require FFTW >= 3.1 to limit the amount of time spent choosing DFT
           23    algorithms.
           24 -  Allow building PISM with GSL <= 1.15
           25    (`#304 <https://github.com/pism/pism/issues/304>`__).
           26 -  Updated installation instructions for Cray systems
           27    (`#316 <https://github.com/pism/pism/issues/316>`__).
           28 -  Put quick installation instructions in one spot
           29    (`#314 <https://github.com/pism/pism/issues/314>`__).
           30 -  Allow building documentation on systems without full PISM
           31    prerequisites (`#251 <https://github.com/pism/pism/issues/251>`__).
           32    Give better warnings about missing tools needed to build the source
           33    code browser (`#137 <https://github.com/pism/pism/issues/137>`__).
           34 
           35 New features
           36 ^^^^^^^^^^^^
           37 
           38 -  Implement ``KirchhoffEnthalpyConverter``, an enthalpy converter which
           39    approximates L, the latent heat of fusion of ice, using Kirchhoff's
           40    law of thermochemistry.
           41 -  Implement ``-atmosphere weather_station``. Reads scalar time-series
           42    of near-surface air temperature and precipitation and applies them to
           43    the whole domain. Use with lapse rate corrections to add spatial
           44    variability.
           45 -  Re-implement and document the ocean model which uses the 3-equation
           46    sub-shelf melting parameterization (Hellmer and Olbers,
           47    ``-ocean th``).
           48 -  The PDD model supports a spatially-variable standard deviation
           49    (`#179 <https://github.com/pism/pism/issues/179>`__) field used to
           50    model temperature variability and a parameterization of this standard
           51    deviation (`#265 <https://github.com/pism/pism/issues/265>`__).
           52 -  Add ``-atmosphere ...,frac_P``, an atmosphere "modifier" that scales
           53    precipitation using a time-dependent factor read from a file.
           54    (`#271 <https://github.com/pism/pism/issues/271>`__).
           55 -  Add a PETSc-based parallel version of the ``fill_missing`` script
           56    which can be used to fill gaps in high-resolution datasets.
           57 
           58 New diagnostics
           59 ^^^^^^^^^^^^^^^
           60 
           61 -  Add SIA-type shear stresses (``tauxz``, ``tauyz``) and hydrostatic
           62    pressure (``pressure``)
           63    (`#280 <https://github.com/pism/pism/issues/280>`__).
           64 -  Add the bed parallel basal shear stress (``taub``) and its magnitude
           65    (``taub_mag``) (`#266 <https://github.com/pism/pism/issues/266>`__).
           66 -  New names of vector diagnostic quantities:
           67 
           68    -  ``cbar`` was renamed to ``velbar_mag``,
           69    -  ``cbase`` was renamed to ``velbase_mag``,
           70    -  ``csurf`` was renamed to ``velsurf_mag``,
           71    -  ``cflx`` was renamed to ``flux_mag``.
           72 
           73 -  Mass-conserving hydrology models add conservation-related scalar
           74    diagnostics (`#256 <https://github.com/pism/pism/issues/256>`__).
           75 -  Add ``flux_divergence``
           76    (`#165 <https://github.com/pism/pism/issues/165>`__).
           77 -  Add ``uflux``, ``vflux``, 3D horizontal ice fluxes in the X and Y
           78    direction.
           79 -  Add hydrology diagnostics and CTS to ``-o_size big``
           80    (`#264 <https://github.com/pism/pism/issues/264>`__) and
           81    (`#262 <https://github.com/pism/pism/issues/262>`__).
           82 
           83 Some changes that may break run scripts
           84 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
           85 
           86 -  Replace ``-boot_file foo.nc`` with ``-bootstrap -i foo.nc``
           87    (`#308 <https://github.com/pism/pism/issues/308>`__).
           88 -  Rename ``-force_to_thk`` to ``-force_to_thickness``
           89    (`#268 <https://github.com/pism/pism/issues/268>`__).
           90 -  ``-atmosphere searise_greenland`` uses
           91    ``-atmosphere_searise_greenland_file``
           92    (`#263 <https://github.com/pism/pism/issues/263>`__).
           93 -  ``-surface ...,forcing`` requires ``ftt_mask``; floating ice is not
           94    affected.
           95 -  Remove automatic vertical grid extension.
           96 
           97 Minor changes
           98 ^^^^^^^^^^^^^
           99 
          100 -  Remove the "preliminary" time step
          101    `#210 <https://github.com/pism/pism/issues/210>`__.
          102 -  ``-topg_to_phi`` arguments are configuration parameters
          103    (`#289 <https://github.com/pism/pism/issues/289>`__).
          104 -  Add ``energy_advection_ice_thickness_threshold``
          105    (`#292 <https://github.com/pism/pism/issues/292>`__).
          106 -  Allow using a different ``ftt_alpha`` in "ice-free" areas. (`commit
          107    93c09d3d <https://github.com/pism/pism/commit/93c09d3d>`__)
          108 -  Close `#254 <https://github.com/pism/pism/issues/254>`__. Adds
          109    ``-timestep_hit_multiples X``.
          110 -  Close `#255 <https://github.com/pism/pism/issues/255>`__. (add
          111    ability to start ``-hydrology distributed`` model if ``bwp`` is
          112    missing)
          113 -  Close `#259 <https://github.com/pism/pism/issues/259>`__ (new
          114    adaptive time-stepping decision output).
          115 -  Fix discharge reporting (now it's the same for all calving
          116    mechanisms, cumulative only in 2D, cumulative and a "rate" as a
          117    scalar time-series).
          118 -  Include ``pism_config`` in output files
          119    (`#270 <https://github.com/pism/pism/issues/270>`__).
          120 -  Pressure is set to overburden in grounded-ice areas with empty
          121    subglacial aquifer, a change of "``-hydrology distributed``\ "
          122    behavior relative to v0.6 which avoids "sucking" water out at the
          123    margin. (The runs which went into Bueler & van Pelt (2015) used bmelt
          124    = -1 m/a to empty ice-free, but this is not necessary now.)
          125 -  Remove Storglaciaren example.
          126 -  Separate Glen exponents for SIA and SSA flow laws
          127    (`#285 <https://github.com/pism/pism/issues/285>`__).
          128 -  Use latitude and longitude bounds names compatible with CDO.
          129 -  Use the global attribute "``proj4``\ " instead of
          130    "``mapping:proj4``\ ".
          131 
          132 Some bug fixes
          133 ~~~~~~~~~~~~~~
          134 
          135 -  `#267 <https://github.com/pism/pism/issues/267>`__ (ensure that
          136    threshold thickness is non-negative).
          137 -  `#277 <https://github.com/pism/pism/issues/277>`__ (the time axis
          138    length of ``ts_times``).
          139 -  `#278 <https://github.com/pism/pism/issues/278>`__ (``-energy none``
          140    should start with either ``temp`` or ``enthalpy``).
          141 -  `#281 <https://github.com/pism/pism/issues/281>`__ (a bug related to
          142    (now-removed) vertical grid extension).
          143 -  `#283 <https://github.com/pism/pism/issues/283>`__ (unreasonable
          144    SSAFD velocities near the "cliff" at periodic boundary).
          145 -  `#297 <https://github.com/pism/pism/issues/297>`__ (record bed
          146    deformation choice in a configuration parameter).
          147 -  `#299 <https://github.com/pism/pism/issues/299>`__ (fix verbPrintf).
          148 -  `#315 <https://github.com/pism/pism/issues/315>`__ (segfault in the
          149    PDD model).
          150 -  unreported: Fix snow depth reset code in the PDD model `commit
          151    cae55774 <https://github.com/pism/pism/commit/cae55774>`__.
          152 
          153 Code changes that may be of interest to developers
          154 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          155 
          156 Most of the changes in this category come from trying to make PISM more
          157 library-like, which in the long run will make it easier to extend, test,
          158 maintain, and couple to other models. This transformation is not nearly
          159 done, but here's the current state of the code. I am not claiming that
          160 this is great design, so please do let me know if something looks broken
          161 to you.
          162 
          163 Use exceptions to handle errors in PISM
          164 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          165 
          166 PISM v0.7 uses exceptions to propagate information about runtime errors.
          167 
          168 Use the ``RuntimeError`` class to signal an error:
          169 
          170 ::
          171 
          172         throw RuntimeError("message");
          173         // or
          174         throw RuntimeError::formatted("format string %s", "data");
          175 
          176 Sometimes it is helpful to add context to an error message so that a
          177 user can get more information about a failure. Here's a way to do that:
          178 
          179 ::
          180 
          181         try {
          182           // code that may fail
          183           foo();
          184         } catch (RuntimeError &e) {
          185           e.add_context("doing foo to %s", "data");
          186           throw;                        // don't forget to re-throw!
          187         }
          188 
          189 Some benefits of using exceptions
          190 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          191 
          192 -  We can now use function return values instead of output arguments in
          193    most places.
          194 -  Better resource management. (No half-allocated objects because we can
          195    allocate in constructors and report allocation errors.)
          196 -  PISM code is easier to wrap with SWIG; the SWIG interface file is
          197    much easier to maintain.
          198 -  Error propagation from PISM (C++) to Python and back **works**.
          199 -  PISM's C++ code can be tested using Python scripts.
          200 
          201 Errors in parallel code sections
          202 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          203 
          204 If a computation fails on some (but not all) ranks in a communicator,
          205 the next blocking MPI call will, well, block. This can make PISM hang
          206 instead of stopping with an error message.
          207 
          208 We try to prevent this by wrapping all ``i,j`` loops in
          209 
          210 ::
          211 
          212         ParallelSection loop(communicator);
          213         try {
          214           // for loop goes here
          215         } catch (...) {
          216           loop.failed();
          217         }
          218         loop.check();
          219 
          220 ``loop.failed()`` prints an error message and sets a flag indicating a
          221 failure. Then ``loop.check()`` calls ``MPI_Allreduce()`` to tell **all**
          222 ranks in the communicator that something failed and then throws an
          223 exception on **all** ranks.
          224 
          225 All loops containing code that might throw should be wrapped this way.
          226 
          227 **Note:** This problem exists regardless of the error handling method in
          228 use.
          229 
          230 IceModelVec
          231 ^^^^^^^^^^^
          232 
          233 First of all, ``const IceModelVec`` is usable now, so it's OK to return
          234 a const reference to an internal field in a component's interface to
          235 provide read-only access.
          236 
          237 IceModelVec::AccessList
          238 ^^^^^^^^^^^^^^^^^^^^^^^
          239 
          240 Accessing PETSc ``Vec`` arrays requires wrapping code in
          241 ``DMDAVecGetArray`` and ``DMDAVecRestoreArray`` calls. This is a problem
          242 if we assume that all code can throw an exception.
          243 
          244 ::
          245 
          246         DMDAVecGetArray(...);
          247         // if do_work(...) throws, DMDAVecRestoreArray will not be called.
          248         do_work(i, j);
          249         DMDAVecRestoreArray(...);
          250 
          251 This issue affects ``IceModelVec`` fields, too.
          252 
          253 To get around this I created ``IceModelVec::AccessList`` which calls
          254 ``DMDAVecGetArray`` in the constructor and ``DMDAVecRestoreArray`` in
          255 the destructor. This guarantees that ``DMDAVecRestoreArray`` is called
          256 when we exit the scope. Here's how to use it:
          257 
          258 ::
          259 
          260         IceModelVec::AccessList list(f);
          261         list.add(g);
          262 
          263         f(i, j) = g(i, j);
          264 
          265 Accessing "raw" PETSc Vecs
          266 ^^^^^^^^^^^^^^^^^^^^^^^^^^
          267 
          268 To access "raw" PETSc Vecs and avoid the risk of not calling
          269 ``...RestoreArray...()``, use
          270 
          271 -  ``pism::petsc::VecArray`` to access a ``Vec`` by calling
          272    ``VecGetArray`` and ``VecRestoreArray``,
          273 -  ``pism::petsc::VecArray2D`` to use ``VecGetArray2d`` and
          274    ``VecRestoreArray2d`` calls,
          275 -  ``pism::petsc::DMDAVecArray`` to use ``DMDAVecGetArray`` and
          276    ``DMDAVecRestoreArray``,
          277 -  ``pism::petsc::DMDAVecArrayDOF`` to use ``DMDAVecGetArrayDOF`` and
          278    ``DMDAVecRestoreArrayDOF``.
          279 
          280 New ``IceModelVec2S`` methods for moving data to/from processor 0.
          281 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          282 
          283 ``IceModelVec2S`` takes care of allocating copies on processor 0 and
          284 communication.
          285 
          286 See this code from ``IcebergRemover`` for an example:
          287 
          288 ::
          289 
          290         // In the constructor: allocate a copy on processor 0
          291         m_mask_p0 = m_iceberg_mask.allocate_proc0_copy();
          292 
          293         // Later: identify icebergs using serial code on processor 0:
          294         {
          295           m_iceberg_mask.put_on_proc0(*m_mask_p0);
          296 
          297           ParallelSection rank0(m_grid->com);
          298           try {
          299             if (m_grid->rank() == 0) {
          300               petsc::VecArray mask(*m_mask_p0);
          301               cc(mask.get(), m_grid->Mx(), m_grid->My(), true, mask_grounded_ice);
          302             }
          303           } catch (...) {
          304             rank0.failed();
          305           }
          306           rank0.check();
          307 
          308           m_iceberg_mask.get_from_proc0(*m_mask_p0);
          309         }
          310 
          311 ``IceModelVec::has_nan()`` is gone
          312 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          313 
          314 Use PETSc's option ``-fp_trap`` to detect ``NaNs`` (on Linux).
          315 
          316 Wrappers for all PETSc objects used in PISM
          317 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          318 
          319 PISM has wrappers for all PETSc objects it uses: ``DM``, ``IS``,
          320 ``KSP``, ``Mat``, ``SNES``, ``Tao``, ``Vec``, ``VecScatter``,
          321 ``Viewer``.
          322 
          323 These wrappers ensure that the corresponding ``...Destroy()`` function
          324 is called when a ``DM``, ``Mat``, etc needs to be destroyed.
          325 
          326 To use, write code similar to
          327 
          328 ::
          329 
          330         pism::petsc::Vec my_vec;
          331         ierr = VecCreateSeq(PETSC_COMM_SELF, size, my_vec.rawptr());
          332         PISM_CHK(ierr, "VecCreateSeq");
          333         // my_vec will be destroyed automatically when we exit the scope
          334 
          335 Making PISM more library-like
          336 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          337 
          338 Execution context ``Context`` (`#150 <https://github.com/pism/pism/issues/150>`__).
          339 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          340 
          341 An execution context ``pism::Context`` collects objects that are shared
          342 by several (possibly all) components of a PISM instance:
          343 
          344 -  an MPI communicator
          345 -  a UDUNITS unit system
          346 -  a ``Config`` instance
          347 -  an ``EnthalpyConverter`` instance
          348 -  a ``Time`` manager object
          349 -  a ``Profiling`` object
          350 -  a ``Logger``
          351 
          352 Putting them in a ``Context`` instead of using global objects will allow
          353 running more than one PISM instance at the same time while preserving
          354 consistency of modeling choices.
          355 
          356 (Using PETSc's command-line options is still a problem, but this is a
          357 step in the right direction.)
          358 
          359 I imagine that we may have one or more ``Context``, with one or more
          360 ``IceGrid`` for each ``Context``, with multiple components for each
          361 ``IceGrid`` instance.
          362 
          363 The ``pism::Logger`` class.
          364 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
          365 
          366 PISM v0.6 uses the ``verbPrintf()`` function to print text to standard
          367 out.
          368 
          369 This may be a problem: - If two or more PISM instances run at the same
          370 time in the same MPI process their outputs will get intermixed, which
          371 will make this output useless. - If PISM is used as a library in a
          372 bigger system we may want to suppress or redirect PISM's output.
          373 
          374 To address this issue I created ``pism::Logger``, a simple class
          375 wrapping ``verbPrintf``. Its default implementation does not add
          376 anything new, but makes it possible to replace writing to ``stdout``
          377 with writing to a file, for example. (Just write a class derived from
          378 ``Logger`` and use it to create a ``Context`` instance.)
          379 
          380 New code for processing command-line options.
          381 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          382 
          383 PISM v0.7 has new classes
          384 
          385 -  ``pism::options::String``: an option with a string argument
          386 -  ``pism::options::StringList``: an option with the argument which is a
          387    comma-separated list of strings, used as a vector of strings
          388 -  ``pism::options::StringSet``: an option with the argument which is a
          389    comma-separated list of strings, used as a set of strings
          390 -  ``pism::options::Keyword``: an option which takes one of pre-defined
          391    keywords as an argument
          392 -  ``pism::options::Integer``: an option with an integer argument
          393 -  ``pism::options::IntegerList``: takes a comma-separated list of
          394    integers, returned as a vector
          395 -  ``pism::options::Real``: an option with an numerical argument
          396 -  ``pism::options::RealList``: takes a comma-separated list of numbers,
          397    returned as a vector of doubles
          398 -  ``pism::options::Bool``: is a function that returns ``true`` if an
          399    option was set and ``false`` if it was not (or if ``-no_...`` was
          400    set).
          401 
          402 Here's a way to use ``options::Integer``, for example.
          403 
          404 ::
          405 
          406         int default_value = 100;
          407         options::Integer N("-N", "description", default_value);
          408 
          409         if (N.is_set()) {
          410           // -N was set
          411           int M = N + 1;                // N is automatically converted to int
          412          }
          413 
          414 ``Real`` is automatically converted to ``double``, ``String`` and
          415 ``Keyword`` to ``std::string``, ``StringList``, ``IntegerList``,
          416 ``RealList`` to ``std::vector`` of strings, integers, and doubles.
          417 
          418 Config improvements
          419 ^^^^^^^^^^^^^^^^^^^
          420 
          421 The ``pism::Config`` is an interface class now. It was re-written so as
          422 to reduce dependencies on the rest of PISM.
          423 
          424 It should now be easy to create a ``Config`` derived classes that get
          425 parameter values from a model PISM is coupled to, for example.
          426 
          427 PISM automatically processes command-line options corresponding to
          428 configuration parameters: ``pism_config.cdl`` provides all the
          429 information needed to associate a configuration parameter with an option
          430 and process this command-line option (if ``set_config_from_options()``
          431 is called):
          432 
          433 For example:
          434 
          435 ::
          436 
          437         pism_config:bed_deformation_model_type = "keyword";
          438         pism_config:bed_deformation_model_option = "bed_def";
          439         pism_config:bed_deformation_model_choices = "none,iso,lc";
          440         pism_config:bed_deformation_model = "none";
          441         pism_config:bed_deformation_model_doc = "Selects a bed deformation model to use...";
          442 
          443 Each configuration parameter has a corresponding command-line option,
          444 either the one specified using ``..._option`` or the one that matches
          445 the parameter name.
          446 
          447 Overhaul pism::Vars
          448 ^^^^^^^^^^^^^^^^^^^
          449 
          450 No need for unsightly ``dynamic_casts`` when getting a field from this
          451 dictionary.
          452 
          453 ::
          454 
          455         const IceModelVec2S *field = vars.get_2d_scalar("field_name");
          456 
          457 This throws an exception if a field is not present; use
          458 ``is_available()`` to check first.
          459 
          460 Overhaul IceGrid
          461 ^^^^^^^^^^^^^^^^
          462 
          463 Now ``IceGrid`` contains grid information only and cannot be changed
          464 once it is allocated. (Previously ``IceGrid`` was a kind of a
          465 "context".)
          466 
          467 Each ``IceGrid`` instance still has a ``pism::Vars`` instance: fields
          468 (variables) are stored on a particular grid and so correspond to this
          469 grid.
          470 
          471 Previously ``IceModel`` was responsible for getting grid parameters from
          472 a file or command-line options and allocating a grid; now we can
          473 allocate an ``IceGrid`` using one of these methods:
          474 
          475 -  Fill all members of ``GridParameters`` and use the constructor of
          476    ``IceGrid``.
          477 -  Create a shallow grid using ``IceGrid::Shallow`` (a static method).
          478 -  Create a grid by getting its parameters from a variable in a file (or
          479    using a variable from a list of candidates) with
          480    ``IceGrid::FromFile``.
          481 -  Create a grid by processing command-line options ``-i``,
          482    ``-bootstrap``, ``-Mx``, ``-My``, ``-Mz``, ``-Lx``, ``-Ly``, ``-Lz``,
          483    ``-x_range``, ``-y_range``, and ``-periodicity`` by calling
          484    ``IceGrid::FromOptions``. (This is what ``pismr`` does.)
          485 
          486 (This makes it easier to run PISM's sub-models independently from
          487 ``IceModel``.)
          488 
          489 Point iterators ``Points`` and ``PointsWithGhosts``
          490 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          491 
          492 To simplify iterating over the part of the computational domain of the
          493 current processor PISM has an iterator ``Points``. This code is
          494 equivalent to the double for loop but hides the grid traversal order.
          495 
          496 ::
          497 
          498     for (Points p(grid); p; p.next()) {
          499       const int i = p.i(), j = p.j();
          500       field(i,j) = value;
          501     }
          502 
          503 To update ghost points locally, use ``PointsWithGhosts``:
          504 
          505 ::
          506 
          507     for (PointsWithGhosts p(grid, ghost_width); p; p.next()) {
          508       const int i = p.i(), j = p.j();
          509       field(i,j) = value;
          510     }
          511 
          512 Other
          513 ~~~~~
          514 
          515 -  Add ``make retest`` (re-run failed tests), ``make test-python`` (run
          516    Python tests only), ``make pylint`` (run ``pylint``).
          517 -  Reduce the number of ``-I`` flags needed to build code that uses PISM
          518    as a library.
          519 -  PISM tries not to terminate the run by calling ``MPI_Abort()`` and
          520    such.
          521 
          522    Note: ``PISMEnd`` in PISM v0.6 called ``exit()``, and according to
          523    the C++ standard ``exit()`` does not unwind the stack, i.e. cleanup
          524    done in destructors never happens. So, we should avoid ``exit()``.
          525 
          526 Less interesting internal changes
          527 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          528 
          529 Minor improvements
          530 ^^^^^^^^^^^^^^^^^^
          531 
          532 -  Effective viscosity under-relaxation as a first recovery strategy in
          533    SSAFD (`#282 <https://github.com/pism/pism/issues/282>`__).
          534 -  Isolate the basal melt rate computation
          535    (`#99 <https://github.com/pism/pism/issues/99>`__).
          536 -  Moving towards stand-alone bed deformation model runs
          537    (`#181 <https://github.com/pism/pism/issues/181>`__).
          538 -  Skip bootstrapping heuristics whenever possible
          539    (`#291 <https://github.com/pism/pism/issues/291>`__).
          540 -  Consistent metadata in NetCDF calls
          541    (`#151 <https://github.com/pism/pism/issues/151>`__).
          542 -  Re-use PETSc DMs to reduce memory footprint
          543    (`#132 <https://github.com/pism/pism/issues/132>`__).
          544 -  Use GSL binary search to speed up vertical index lookup.
          545 -  ``PIO``: make it possible to overwrite existing files without
          546    creating a backup copy
          547    (`#224 <https://github.com/pism/pism/issues/224>`__).
          548 -  Class ``MaxTimestep`` helps with comparing time-step restrictions.
          549 -  Class ``Profiling`` helps use PETSc's profiling; add ``-log_summary``
          550    to see results.
          551 -  Use automatically-generated docstrings in Python bindings.
          552 
          553 Regression testing
          554 ^^^^^^^^^^^^^^^^^^
          555 
          556 -  Use ``nose`` and ``coverage`` Python modules to test PISM's Python
          557    code and keep track of code coverage.
          558 -  Better regression tests
          559    (`#305 <https://github.com/pism/pism/issues/305>`__).
          560 -  Add unit (regression) tests for enthalpy converters
          561    (`#272 <https://github.com/pism/pism/issues/272>`__).
          562 -  Isolate vertical interpolation in the column (linear and quadratic;
          563    see ``ColumnInterpolation``). and horizontal linear interpolation
          564    code (``LinearInterpolation``); add regression tests.
          565 -  Improve regression test coverage
          566    (`#294 <https://github.com/pism/pism/issues/294>`__).
          567 
          568 Code organization and cleanup
          569 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          570 
          571 -  Give less confusing names to flow law classes.
          572 -  Remove some uses of STL ``upper_bound`` and ``lower_bound``
          573    (`#170 <https://github.com/pism/pism/issues/170>`__).
          574 -  Replace ``NCSpatialVariable`` and ``NCVariable`` with
          575    ``VariableMetadata`` and ``SpatialVariableMetadata``.
          576 -  Don't pass classes by value
          577    (`#269 <https://github.com/pism/pism/issues/269>`__).
          578 -  Use namespaces to organize PISM code (see
          579    `#188 <https://github.com/pism/pism/issues/188>`__).
          580 -  Reduce inter-dependencies of PISM code.
          581 -  Code formatting (see
          582    ```coding_style.md`` <https://github.com/pism/pism/blob/dev/doc/browser/coding_style.md>`__).
          583 -  ``autopep8`` the Python code, ``pylint`` support.
          584 -  Clean up FEM code.
          585