Using Devel Codes
This document is intended to describe the use of devel codes for developers to speed up implementation of experimental parameters.
What are devel codes
Devel codes are handy tools for developers to control features while
they are not ready for public release. Devel codes are read from the
devel_code
block of the .param
file.
Devel codes are much simpler to use than keywords, however they do not have the rigorous type/value checking or unit conversion that keywords do. Nor are they searchable and do not provide any help. In order to use devel codes you have to explicitly know how to call them, the values they should take and what they do.
The devel code block is an arbitrary string which can be used to provide parameters to a function, however, the devel code block also has several useful standard structural elements to make it more useful than just a string one has to parse themselves.
Using devel codes
Devel code sub-blocks
Devel codes are divided into sub-blocks which are usually named related to the module or functions they support.
Examples include:
MD
- Relating to molecular dynamics optionsFIRE
- Relating to the FIRE geometry optimisation methodELECTRONIC
- Relating to electronic minimisation
However they can be anything the developer wants.
Note
While in principle block names are general and arbitrary, keeping them related to the module where they are used or their functionality is useful for remembering how to call them.
Another use of blocks is to have a block dedicated to a particular algorithm
or as a structured block in the style of .cell
style blocks (i.e.
%block ... %endblock
) ready for integration into the main parameters when
the feature is complete.
The structure of a sub-block in the .param
file (here XYZ
) is as follows:
Extracting devel codes
The devel code block is converted upon reading the param file into
parameters :: current_params%devel_code
. This block can then be
parsed using the following functions:
-
io :: io_code_present(code, key, block)
Check whether a particular parameter
key
is present in blockblock
. If block is not given check the top-level devel-code. -
io :: io_code_block(code, block)
Return the entire block
block
as a character array allowing you to manually process the data. Most useful for situations where the final parameter will be a block of data. -
io :: io_code_logical(code, key, block)
Parse given parameter
key
in blockblock
as a logical according to list-directed Fortran logical rules. -
io :: io_code_integer(code, key, block)
Parse given parameter
key
in blockblock
as an integer according to list-directed Fortran integer rules. -
io :: io_code_real(code, key, block)
Parse given parameter
key
in blockblock
as an real according to list-directed Fortran real rules. -
io :: io_code_complex(code, key, block)
Parse given parameter
key
in blockblock
as an complex according to list-directed Fortran complex rules. -
io :: io_code_string(code, key, block)
Parse given parameter
key
in blockblock
as a character string.
Example
For a devel_code
block that looks like:
The usual procedure for processing a devel code argument is as follows:
module my_module
...
! Can read into module parameters if necessary
integer :: module_param
...
function use_devel_code()
! Ensure the devel_codes are available
use parameters, only: current_params
! Ensure we can parse the devel-codes
use io, only: io_code_present, io_code_integer
! Have the param available
integer :: param
! Check that we're the master process for reading the strings
if (on_root_node) then
! Check if the devel code has been set
if (io_code_present(current_params%devel_code,'param','XYZ')) &
! Read and parse the parameter for use
& param = io_code_integer(current_params%devel_code,'param','XYZ')
!Since it's top-level we parse it without passing the block.
if (io_code_present(current_params%devel_code,'mod_param')) &
& module_param = io_code_integer(current_params%devel_code,'mod_param')
endif
! Distribute the parameters to all nodes
call comms_gcopy(param, 1)
...