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