All contributions to PIC are welcome! If you have an idea for a new feature, a bug fix, or an improvement, please open an issue or submit a pull request.
PIC is an open source project licensed under the MIT License, so you can use it in your own projects without any restrictions. If you use PIC in your project and your wrote a paper with it, please consider citing it by including a link to the repository in your paper.
All code that you contribute to PIC will be licensed under the MIT license, so please make sure that you are comfortable with this before submitting your changes.
The following guidelines will help you contribute effectively:
[type]/[description]
format; where type
is one of feat
, fix
, docs
, chore
, and experiment
.The most important thing in the code is that we are aiming to support int32
and int64
as the default integer types. This is why
we use the default_int
parameter in the pic_types.F90
module. When you are writing new code, please ensure that it is compatible with both integer types by always using integer(default_int)
instead of integer
or integer(kind=4)
or integer(kind=8)
.
I do not care. As long as your code is tested, works, and is well documented I could not care less if you used an AI to write it.
Can I copy paste code from PIC into ChatGPT, Claude, or whatever AI I use? Yes, you can. I don’t care. I do not consider this plagiarism, since the code is open source and you are free to use it as you wish.
We use Ford to generate the documentation. The idea is to have coverage of almost every function in the code, except those that
can be self explanatory or if they are module procedure
inside an interface
block. For example:
interface fill
!! fill provides a generic interface to assing a value
!! alpha of types (int32, int64, sp, dp) as defined in pic_types.F90
!! The inteface supports filling 1d and 2d arrays of the specified
!! variables
!!
!! Usage: call fill(array, value, [optional] threaded)
!!
!! This subroutine is threaded for performance purposes if threaded is set to .true.
!!
module procedure fill_vector_int32
module procedure fill_vector_int64
module procedure fill_vector_sp
module procedure fill_vector_dp
module procedure fill_matrix_int32
module procedure fill_matrix_int64
module procedure fill_matrix_sp
module procedure fill_matrix_dp
end interface
There’s really no need to go document each fill_vector_*
or fill_matrix_*
procedure, since the interface already provides
everything we need to know about the procedures within the fill
interface. Documenting each of these would mean to just
write fills a vector of type int32 with the value alpha, uses threads if enabled
which is redundant and not really useful.
We mostly follow the best practices outlined in the Fortran Best Practices guide.
We have a pre-commit hook that will run fprettify
to format the code before committing, this will ensure that the formatting is consistent across the codebase.
To install pre-commit do:
python3 -m pip install pre-commit
pre-commit install
You can also run pre-commit run --all-files
to format all the files in the repository.
All our of modules are named using the pic_
prefix, followed by the name of the module. For example, the module that provides the basic types is called pic_types
, and the module that provides the BLAS functionality is called pic_blas_interfaces
. MOst of the time the module name matches the name of the file, if you find an instance where this is not the case, please open an issue or submit a pull request to fix it.
Based on the file = module_name
convention, there should only be one module per file.
We follow the convention that the end module
statement should contain the name of the module.
All derived types should be named using the pic_
prefix, followed by the name of the type. For example, the type that represents a vector is called pic_vector
, and the type that represents a matrix is called pic_matrix
.
I really don’t care about naming conventions for functions or subroutines, I only suggest that you make the name descriptive and meaningful. Also, using interfaces to hide the name of the subroutine inside the module is a good practice, since it allows you to change the implementation without affecting the users of the module.
For example, in pic_timer.F90
we have the following interface:
type :: pic_timer_type
!! derived type for a timer, contains the start, stop, and count variables
!! can work with or without omp
private
real(dp) :: start_time = 0.0_dp
real(dp) :: stop_time = 0.0_dp
real(dp) :: walltime
logical :: is_running = .false.
integer(default_int) :: start_count = 0_default_int
integer(default_int) :: stop_count = 0_default_int
integer(default_int) :: count_rate = 1_default_int
contains
procedure :: start => timer_start
procedure :: stop => timer_stop
procedure :: print_time => timer_print_time
procedure :: get_elapsed_time => timer_get_elapsed_time
end type pic_timer_type
You can see that the start
procedure is mapped to timer_start
, this way it is more intuitive for people to use my_timer%start()
instead of my_timer%timer_start()
. This is a good practice to follow, since it makes the code more readable and easier to use.
We follow the same convention for functions and subroutines, as we do for modules. This is, the end function
or end subroutine
statement should contain the name of the function or subroutine.
Code reviews are an essential part of the contribution process. When you submit a pull request, it will be reviewed by the maintainers of the project. They will provide feedback on your code, suggest improvements, and ensure that it meets the project’s standards.
Please be open to feedback and willing to make changes to your code based on the review. The goal is to improve the quality of the code and ensure that it is maintainable in the long run.
If you are new to contributing to open source projects, don’t be discouraged by the review process. It is a learning experience, and the maintainers are here to help you improve your code and understand the project better.
If you feel connected to the project and want to help out with reviews, please let me know. I would be happy to invite as many people as possible to the main repository.