Doxygen

Every developer is responsible to provide documentation. A full doxygen user guide is available on the official website1.

Laura Mendoza, wrote a script available on github2 to comment fortran modules, functions and subroutines of a file. Basically it will write the needed comment lines. It doesn’t write the documentation for you (of course) but it could save some time!

Doxygen configuration

  • Doxyfile and html layout files are in directory selalib/doc/doxygen

  • To generate html documentation type in your build directory:

make doc-dev
  • html pages are generated in directory selalib/build/doc/html.

  • These pages are published on GitHub pages if pushed on the main branch.

Document library in new directory

Add a fortran file suffixe _doc.F90 in the library directory. Here an example with file maxwell_solvers_doc.F90 in selalib/src/maxwell_solvers directory.

!> @defgroup maxwell_solvers sll_maxwell_solvers
!> @brief
!> Library to solve Maxwell system in 2D and 3D
!> @details
!> FDTD, PSTD and DG method are available
!> - Include file : <code>sll_maxwell_solvers.h</code>
!> - Link with : <code>sll_maxwell_solvers</code>
!>
!> @author Pierre Navaro
!> @todo implement sll_maxwell_3d_fdtd
!> @todo Add some examples in the documentation

Document a fortran module

!> @ingroup <DIRECTORY_NAME>
!> @author <MODULE_AUTHOR_NAME_AND_AFFILIATION>
!> @brief <BRIEF_DESCRIPTION>
!> @details <DETAILED_DESCRIPTION>

module <MODULE_NAME>

contains

end module <MODULE_NAME>

Every directory of the software should have an entry in the “Libraries” tab on the website generated by Doxygen. To create this entry, edit the fortran file “_doc.F90” and add the documentation of all fortran modules available in this directory. Add also some examples.

To see your documentation, remove the line containing your directory in file doc/doxygen/Doxyfile (line 691). A good way to document fortran module is to copy and paste this at the the top of your fortran file :

!> @ingroup file_io
!> @brief
!> Implements the functions to write data file plotable by GNUplot
!> @details
!> This is an example of how use the sll_gnuplot module.
!> More details about this example
!> @snippet file_io/unit_test_gnuplot.F90 example
!> Here a snapshot when you execute:
!> <code> gnuplot -persistent plot_2.gnu </code>
!
!> @image html gnuplot.png
module sll_gnuplot

use sll_ascii_io
use sll_utilities, only: sll_new_file_id, int2string

contains

Document a derived type

!> @brief 2D logical mesh
!> @details
!>  Use new_logical_mesh_2d to allocate the memory space,
!> initialize it and get a pointer to this object.
type, public :: sll_logical_mesh_2d
  sll_int32  :: num_cells1 !< number of cells in direction 1
  sll_int32  :: num_cells2 !< number of cells in direction 2
  sll_real64 :: eta1_min   !< minimum value of eta, direction 1
  sll_real64 :: eta1_max   !< maximum value of eta, direction 1
  sll_real64 :: eta2_min   !< minimum value of eta, direction 2
  sll_real64 :: eta2_max   !< maximum value of eta, direction 2
  sll_real64 :: delta_eta1 !< cell spacing, direction 1
  sll_real64 :: delta_eta2 !< cell spacing, direction 2
end type sll_logical_mesh_2d

Document a subroutine

To document function or subroutine :

 !> @brief <BRIEF_DESCRIPTION>
 !> @details <DETAILED_DESCRIPTION>
 !> @param [<in or out or inout>] <PARAM1> <DESCRIPTION>
 !> @param [<in or out or inout>] <PARAM2> <DESCRIPTION>
 function function_name(<PARAM1>,<PARAM2>)
!> @brief Create HDF5 file
!> @details To use this subroutine HDF5_ENABLE should be set to ON
!> in CMake configuration
subroutine sll_hdf5_file_create(filename,file_id,error)
  character(len=*) , intent(in)  :: filename  !< file name
  integer(hid_t)   , intent(out) :: file_id   !< unit number
  integer,           intent(out) :: error     !< error code

  call H5open_f(error)
  SLL_ASSERT(error==0)
  call H5Fcreate_f(filename,H5F_ACC_TRUNC_F,file_id,error)
  SLL_ASSERT(error==0)
end subroutine sll_hdf5_file_create

Document a function

!> @brief allocates the memory space for a new 1D logical mesh.
!> @details
!> initializes it with the given arguments and returns a pointer to the
!> object.
!> @param num_cells integer denoting the number of cells.
!> @param eta_min  minimum value of the eta1 parameter in the logical mesh.
!> @param eta_max maximum value of the eta1 parameter in the logical mesh.
!> @return a pointer to the newly allocated object.
function new_logical_mesh_1d( &
  num_cells,                  &
  eta_min,                    &
  eta_max ) result(m)

  type(sll_logical_mesh_1d), pointer :: m
  sll_int32,              intent(in) :: num_cells
  sll_real64, optional,   intent(in) :: eta_min
  sll_real64, optional,   intent(in) :: eta_max

  sll_int32 :: ierr

  SLL_ALLOCATE(m, ierr)
  call initialize_logical_mesh_1d( m, num_cells, eta_min, eta_max )
  
end function new_logical_mesh_1d

Document some variables

!> @ingroup constants
!> @brief
!> Fortran module where set some physical and mathematical constants.
!> @details
!> In this module, all variables must be protected
module sll_constants
use sll_working_precision

implicit none

!> @param PI number
sll_real64, parameter :: sll_pi = 3.1415926535897932384626433D8

!> @param speed of light in vacuum (def) m/s
sll_real64, parameter :: sll_c = 2.99792458D8

end module sll_constants

Document your test example

Insert some doxygen comments to mark the code you want to share :

!>@internal [example]
program test_io_gnuplot

use sll_gnuplot

call sll_gnuplot_2d(eta1_min, eta1_max, n1, &
                    eta2_min, eta2_max, n2, &
                    array, 'plot_1', iplot, error)

end program test_io_gnuplot
!>@internal [example]

Test program must be short!


1

http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html

2

https://github.com/lasofivec/python-scripts/blob/master/make_sll_doxygen_doc.py