-
Notifications
You must be signed in to change notification settings - Fork 114
Updating to F03 F08, Iterators for Data Structures
This article addresses two separate but related topics of interest; The implementation of iterators for the principal data structures in the model and the potential benefits, difficulties, and motivations for adopting the Fortran 2003 or Fortran 2008 standards. Information about these standards, object oriented programming, and compiler compatibility can be found below.
It should be noted that no portion of the current mainline appears to be incompatible with either of these standards; In principle one could take ED as it is, add most of the new F08 features, build it with a compiler supporting these, and have no problems. In fact, compilers with support for F03/F08 features even recognize *.f90 files as 'free form' rather than Fortran 90/95 specific. These points in themselves provide a strong argument in favor of 'updating' ED, because updating really means using modern compilers and OK-ing the use of newer features, thereby providing ED developers a larger toolkit and potentially generating better executables.
Adding variables to ED is a time consuming, tedious, and potentially error prone task. Every new variable must be added to the subroutines that will allocate, deallocate, nullify, initialize, rescale, copy, integrate, average, and output it, to give an incomplete list. Additionally, within many subroutines there is a heirarchy of nested conditionals to negotiate in properly accomplishing these tasks, and when adding a suite of variables (i.e. a variable and it's integrations) it is not difficult to put one of them in the wrong place. For example, one pernicious bug in creating output for a new variable, lassim_resp (leaf assimilate respiration) was recently resolved when the following code was amended:
subroutine reset_averaged_vars(cgrid)
...
cohortloop: do ico=1,cpatch%ncohorts
cpatch%leaf_respiration(ico) = 0.0
cpatch%root_respiration(ico) = 0.0
...
if (c_alloc_flg > 0) then
cpatch%lassim_resp (ico) = 0.0
cpatch%today_lassim_resp(ico) = 0.0
end if
...
end subroutine reset_averaged_vars
to remove today_lassim_resp. That is, it was changed to the code:
subroutine reset_averaged_vars(cgrid)
...
cohortloop: do ico=1,cpatch%ncohorts
cpatch%leaf_respiration(ico) = 0.0
cpatch%root_respiration(ico) = 0.0
...
if (c_alloc_flg > 0) then
cpatch%lassim_resp (ico) = 0.0
end if
...
end subroutine reset_averaged_vars
which resolved an anomalously low integration of the lassim_var. With 20/20 hindsight, it is clear the daily integration should not have been zeroed here. But given that e.g. leaf_resp and today_leaf_resp are paired in many routines pepperred throughout the model, it was an easy bug to create and a difficult bug to find.
This reflects a fundamental property of the data structures used within the model; They are not traversable. As the number of variables reflecting various scientific inquiries increases, the number of modifications to ed scales [.....]. One way of addressing this drawback of the current grid through patch data structures is to create a heirarchy of traversable sub-structures to which the grid/polygon/site/patch variables point, rather than the anonymous locations currently created via subroutines like allocate_patchtype. The implementation of these substructures need not necessarily use any more memory than the current (e.g. patchtype) variables; They will simply be indexed locations for the values of those variables.
If ED were to be restructured in this way, other improvements in the clarity of the structure would be facilitated; In particular, the adoption of certain object oriented programming techniques, namely data encapsulation and the packaging of subroutines with the data on which they act would be relatively straightforward. This would add conceptual clarity because it would centralize certain data manipulations at the core of how ED functions and draw a clearer boundary between the book-keeping necessary to ED and the science being modelled.
The technique of
Two Portland Group articles illustrating some of the basic OOP features in Fortran, related discussion, and an article about updating fortran code. Mainline ED doesn't seem to have any of the problematic features, as noted above.
- http://www.pgroup.com/lit/articles/insider/v3n1a3.htm
- http://www.pgroup.com/lit/articles/insider/v3n2a2.htm
- http://fortranwiki.org/fortran/show/OOP+discussion
- http://fortranwiki.org/fortran/show/Modernizing+Old+Fortran
A bunch of information on the compatibility of new standard code with GNU compilers.
- http://gcc.gnu.org/wiki/Fortran2008Status
- http://gcc.gnu.org/wiki/Fortran2003Status
- https://gcc.gnu.org/onlinedocs/gfortran/Fortran-2008-status.html
- https://gcc.gnu.org/wiki/GFortran/News#GCC4.10
- http://fortranwiki.org/fortran/show/Fortran+2003+status
- http://fortranwiki.org/fortran/show/Fortran+2008+status
A bunch of basic things to know about programming paradigms, i.e. useful background and food for thought on code structure.