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!
- 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.
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!> @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!> @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_2dTo 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!> @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!> @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_constantsInsert 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!