this_is_a_variablesubroutine this_is_a_subroutine(var_a, var_b)Capitalization:
1.0_FPTWO_PIuse MPI, call MPI_allreduce(...), MPI_COMM_WORLD!$omp parallel do private(var_a, var_b).Line Length:
& at appropriate places. For strings, place & at the end of the line and at the beginning of the next.Indentation:
(sub)module and program declarations, type, subroutine/function declarations, and each level of do loops, if clauses, and case statements.Spaces:
call some_subroutine(var_a, var_b).real(FP), intent(in), dimension(dim) :: arr.var_a = 3.0_FP * x**2 + sin(var_b) / var_c.do loops and if clauses: do i = 1, 3, if (i == 7) then.a .or. b .and. c.arr(1:3, 1:5).call sub(x, y, z, mode=4, debug=1).Empty Lines:
type/subroutine/function definitions.Access/Privacy:
only when importing modules, except for external libraries like MPI, NetCDF, etc.intent for dummy variables.public/private access for module components.default(none) for OpenMP parallel regions.Documentation:
module/type/subroutine/function declaration using special FORD comments (!!), and normal comments (!) for everything else.Naming Conventions:
_m (e.g., some_module_m), and the corresponding file should be named some_module_m.f90._s (e.g., some_submodule_s), and the corresponding file should be named some_submodule_s.f90._t (e.g., some_type_t).i, j, l). Use descriptive names like mass_electron instead of vague ones like m or me.test_some_module should be placed in tests/test_some_module_m.pf, corresponding to the file some_module_m.f90.Error Handling:
Additional Guidelines:
common blocks and goto (except for error handling).implicit none at the beginning of modules.if (a /= b) then instead of if (a .ne. b) then.call sub(x, y, z, mode=4, debug=1) instead of call sub(x, y, z, 4, 1). If necessary, separate arguments across multiple lines.Here is an example source code for the file some_module_m.f90, illustrating the conventions mentioned above:
module some_module_m
!! Description of module --> in-browser documentation
! Some further comments, not meant to enter in-browser doucumentation
use MPI
use precision_m, only : FP
use error_handling_m, only : handle_error, error_info_t
use status_codes_m, only : PARALLAX_ERR_<CODE>
use some_other_module_m, only : some_variable
implicit none
type, public :: some_type_t
!! Description for some_type_t
integer, private :: foo
!! Description for foo
real(FP), public :: foo_bar
!! Description for foo_bar
contains
procedure, public :: something_useful
end type
contains
subroutine something_useful(self, dim_arr, arr)
!! Description for subroutine
class(some_type_t), intent(inout) :: self
!! Instance of the type
integer, intent(in) :: dim_arr
!! Dimension of arr
real(FP), intent(out), dimension(arr) :: dim_arr
!! Some array
integer :: i, foo, ierr
real(FP) :: tmp
! This loop does something very useful ;)
!$omp parallel default(none) private(i, tmp) &
!$omp shared(self, some_variable, dim_arr)
!$omp do
do i = 1, dim_arr
tmp = sqrt(2.0_FP) * i
dim_arr(i) = some_variable * self%foo_bar + tmp
enddo
!$omp end do
!$omp end parallel
! Sum foo over all MPI processes
call MPI_allreduce(MPI_IN_PLACE, self%foo, count=1, &
datatype=MPI_INTEGER, op=MP_SUM, comm=MPI_COMM_WORLD, &
ierr=ierr)
! Some error handling statement
if (foo == 0) then
call handle_error('foo must not be zero', &
PARALLAX_ERR_<CODE>, __LINE__, __FILE__, &
additional_info=error_info_t('foo=', [foo]))
endif
end subroutine
end module