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