Be very careful with globals. If possible at all, don't use them, as
function leak(i) integer,intent(in) :: i integer,pointer :: leak allocate (leak) leak=i end function leak integer, pointer :: data data=>leak(1) data=>leak(data) ! memory leak!
An array can be initialised with a lower boundary other than '1'. However, the boundary-information is lost if that array is then past to a subroutine with INTENT, but the information is kept if passed with POINTER. See also this example
Every 'TYPE' should have an initialize and finalize routine. This way, you can ensure that the object is in a valid state.
With the INTERFACE statement, you can make these routines have the same name, such that the code becomes better to understand.
An example can be found in omsourceparameter_mod. In ther you will find a construct/destruct routine.
It is a good practice to make everything in a module PRIVATE, and state explicitly what can be accessed publicly. This way, you can specify public INTERFACEs, and even hide the implementation of a TYPE
omsourcecelestial_mod shows an example of both.
Code re-use is achieved by the USE statement, and not by copying the module itself. The latter is even dangerous, as the module occurs twice in the include area, and it becomes a disaster if the contents is modified.
To improve the readability of the code, one should try to minimize the number of arguments, that are passed to a function/routine. Too many arguments, usually means that you are better of with a TYPE.
You should try to initialise your code once, and once only, as only then you can be sure that a module is in a good state.
The module should always have an 'IMPLICIT NONE' statement in the header.
module foo use bar implicit none ! interfaces/types/access goes here contains ! implementation goes here end module
It sometimes is a good idea to break up a type into sub-types.
Even better, if you make the contents PRIVATE, you are forced to create access routines to the contents.
OmSourceParameter is a candidate, as parts of it are set in different locations of the code. For example:
type(Counts) counts(type(Omsourceparameter)) ! same as above, but divided by the exposure ;-) type(Counts) rates(type(Omsourceparameter))