CHARMM c39b2 developer.doc



File: developer.doc -=- Node: Top
Up: (charmm.doc) -=- Previous: (testcase.doc) -=- Next: (changelog.doc)



                        CHARMM Developer Guide

This document provides a basic guide for understanding CHARMM's 
architecture, implementation, and development protocols and tools. 
Prospective developers are urged to familiarize themselves with
its contents.

* Menu:

* Implement::   CHARMM Implementation and Management
* Directories:: What directories are used to store what information
* Standards::   Standards (rules) for writing CHARMM code
* Tools::       Tools for CHARMM developers
* Modify::      The procedure for modifying anything in CHARMM
* Document::    How to document CHARMM commands and features
* API::         How to generate low-level documentation from code
* Checkin::     How to deposit your development version into the
                central library



File: Develop -=- Node: Implement
Up: Top -=- Previous: Top -=- Next: Directories



                  CHARMM Implementation and Management

    CHARMM is implemented as a single program package, which is
developed for use on a variety of platforms.  The single source 
structure makes the program easier to handle and promotes the
program's integrity.

    CHARMM was originally written in FLECS, FORTRAN77 and C languages.
Before FORTRAN77, FLECS allowed us to use a variety of
control constructs, e.g., WHEN-ELSE, WHILE, UNLESS, etc.  A FLECS to
FORTRAN translator was used to process FLECS source code to produce
FORTRAN source.  With CHARMM 23, the FLECS source code was converted
to FORTRAN 77. CHARMM 23f2 and later versions are fully in FORTRAN,
except for some machine-specific codes written in C.  All new
code should be written in FORTRAN 95.

    Since CHARMM version 22, all files are maintained by utilizing
software engineering tools.  The Subversion utility is used to maintain
the CHARMM source code, documentation and other supporting files.
The Subversion repository resides on charmm.hanyang.ac.kr.  The CHARMM
manager controls both the developmental and released versions of the code.
He schedules contributions from all CHARMM developers.



File: Develop -=- Node: Directories
Up: Top -=- Previous: Implement -=- Next: Standards



                       CHARMM Directory Structure


CHARMM files are organized in the following directories.  UNIX pathnames
are used throughout the document.  ~/ is the parent directory that
contains the CHARMM main directory, ~/cnnXm.  nn is the version
number, X is the version trunk designator (a for alpha or
developmental, b for beta release and c for gamma or general release)
and m is the revision number.  For example, c24b1 is CHARMM version 24
beta release revision 1.

Directory           Purpose
------------------  ---------------------------------------------------
~/cnnXm             The main directory of the current CHARMM version.
                    The install.com installation script runs in this directory.

~/cnnXm/source      Source files.

~/cnnXm/doc         Documentation

~/cnnXm/test        Testcases

~/cnnXm/toppar      Standard topology and parameter files.

~/cnnXm/support     Holds various support programs and data files for
                    CHARMM.  See *note Support: (support.doc).

~/cnnXm/tool        Contains the preprocessor, prefx, and other
                    CHARMM processing/management tools. 

~/cnnXm/build       Contains Makefile, module makefiles and the log
                    file of the install make command for each machine
                    in the subdirectory named after the machine type.

~/cnnXm/lib         Contains library files

~/cnnXm/exec        Will hold executables



File: developer.doc -=- Node: Standards
Up: Top -=- Previous: Directories -=- Next: Tools



                Standards (rules) for writing CHARMM code


Because CHARMM is developed by various groups, there are a number of
standards to which all contributors must adhere in order for the 
program to remain modifiable, usable, and transferable.  The rules
which have been established towards this end are listed below.

 1) CHARMM module and subroutine structure:
   
    Fortran modules should be used for all code when possible. The
    general form of a CHARMM fortran module is:

    module SAMPLEMOD 
    ! Comments describing the general function of the module 
      use chm_kinds
      implicit none

      ! Declarations of public variables
      ! Declarations of private variables

    contains
      
      subroutine SUBROUTINE1(arg1,arg2,...) 
         .
      end subroutine SUBROUTINE1

      subroutine SUBROUTINE2(arg1,arg2,...)
         .
      end subroutine SUBROUTINE2
         .
         .

      !----- other subroutines and functions --------------!

    end module SAMPLEMOD 

    The subroutines in a CHARMM module might include, for example,
    setup subroutines, memory allocation/deallocation subroutines,
    output subroutines, and the principal subroutines for the 
    method.
   
    A subroutine in CHARMM should have the following general form:
      
    subroutine DOTHIS(arg1,arg2,....
    ! A comment which describes the purpose of this subroutine.
    ! This may include important variables and what their use is
    ! to aid in understanding and modifying the routine.
    ! A description of all passed arrays and arguments if
    ! users need to call this routine. 

      use chm_kinds
      use dimens (if dimensioned common blocks are included)
      use number (if commonly used real numbers are used)
      use somemodule, only: var1, var2, func1, sub1

      implicit none

      !---- declare all passed variables here --------
      real(chm_real), intent(in) :: arg1
      integer(chm_int), intent(out) :: arg2

      !---- local ------------
      Declarations of ALL local variables and parameters.
         .
      data statements at end of declarations.

      !----- begin -----------
         .
      Code (liberally documented through comments)
         .
    end subroutine DOTHIS 

    Note that data statements, if present, come after all declarations
    and parameter statements, but before the first line of executable code.

    The use of subroutines outside of modules should be avoided because
    the compiler does not check their arguments.

 2) All code should be written clearly.  Since the code must be
    largely self-documenting, clarity should not be sacrificed for 
    insignificant gains in efficiency.  Variable, function, subroutine 
    and module names should be chosen with care so as to help illustrate
    their purpose.  Avoid using single letter variable names except 
    for scratch variables in simple loop constructs.  Comments should be 
    used where the function of the code is not obvious. Define/explain
    important variables.  Use the appropriate "intent" attribute (in, out,
    inout) in variable declarations wherever possible.

 3) Input/Output
    a) The RDCMND routine should be used to read lines from the
       command stream.  XTRANE should be called to be sure that the
       entire command line is parsed.
    b) Short outputs, messages, warnings, and error should be sent to
       unit OUTU (accessed by USE stream) for output. All output should
       posess print level protection, e.g., if(prnlev>2) write(outu...
    c) Any warning and error message should state which subroutine 
       generated it.
    d) PSF and parameter unformatted I/O file formats must remain
       upward compatible. Use an ICNTRL array element to indicate
       which version of CHARMM wrote the file. Such upward
       compatibility must be maintained only across release
       versions of CHARMM. In other words, a file format for the
       developmental version may be freely changed until a new release 
       version is generated, at which point all future versions must 
       be able to read it.
    e) Use as many significant digits as needed but not more.
       Do not use list directed output (use of "*" for format) or print.
       In particular,
             write(outu,*) var1, var2
             print *, "Value is", e_variable 
       should not be used. It makes output unreadable and makes testing on
       different machines difficult.
    g) All output must be performed based on the PRNLEV value.  This
       is used, for example, to restrict I/O to node_0 in parallel
       implementations of the code.  For example,

         write (OUTU,'(FORMAT)') ITEMs

       should be coded as

         if (PRNLEV.GT.2) write (OUTU,'(FORMAT)') ITEMs

       where N is an appropriate print level (always >= 2; see also
       miscom.doc).

 4) All error conditions must terminate with a CALL WRNDIE(...) statement;
    direct calls to DIE should not be used. The first argument is the
    severity of the error, the second argument must contain the source
    file in angle brackets, and the routine name of the location of
    the error condition. The third argument contains a string
    describing the error condition.

      call WRNDIE(-3,'<tamd.src> tamd_allocate', &
           'Failed to allocate memory for islct array')

 5)
   A. Use subroutines chmalloc and chmdealloc from module memory
      to allocate and deallocate memory.

    Example:

    module mymod

      use chm_kinds
      integer, allocatable, dimension(:) :: myints
      real(chm_real), allocatable, dimension(:) :: myreals

    contains

      subroutine mystart(natom)
        use memory
        integer, intent(in) :: natom
        call chmalloc('mymod.src', 'mystart', 'myints', natom, intg=myints)
        call chmalloc('mymod.src', 'mystart', 'myreals', natom, crl=myreals)
      end subroutine mystart

      subroutine myfinish(natom)
        use memory
        integer, intent(in) :: natom
        call chmdealloc('mymod.src', 'myfinish', 'myreals', natom, crl=myreals)
        call chmdealloc('mymod.src', 'myfinish', 'myints', natom, intg=myints)
      end subroutine myfinish

    end module mymod

   B. If possible, combine memory allocation statements in a 
      separate subroutine.  Do the same for memory deallocation.

 6) Arrays should be dimensioned with a constant or integer variable
    where possible. Do not use (*) when dimensioning arrays passed as
    arguments; be sure to pass the dimensioning information
    also. Arrays cannot change shape or type when passed.

    subroutine NEWFORCE(natom,force,fsum)
      use chm_kinds
      implicit none
      integer(chm_int),intent(in) :: natom 
      real(chm_real),intent(out) :: fsum
      real(chm_real),intent(inout),dimension(3,natom) :: force
         ---or---
      real(chm_real),intent(inout) :: force(3,natom)

    Check for array overflows.

 7) Error checking in general should be as complete as possible.
    Consider checking for overflows (reciprocals of very small
    numbers, exponentials of very large numbers, etc.), square roots
    of negative numbers, arccosine or arcsine of numbers of absolute
    value greater than one, etc. Code should contain checks for error
    conditions where it will not impact performance. Use compiler
    flags for checking, then remove checking flags for production
    compiling and code submission.

 7) The code should not use non-standard Fortran 95 features.
    Such features must be restricted to the machine dependent modules,
    or encapsulated in "##IF - ##ELSE - ##ENDIF" preprocessor or
    equivalent CPP #if KEY_THISKEY==1 - #else - #endif constructs.

 8) Do not use obsolescent or deprecated Fortran constructs, only use
    what is in the current standard.
    Do not create common blocks, and use the established common blocks
    only when necessary.  
    Do not use entry points.
    Do not use computed or assigned goto statements.
    Avoid "goto" when other constructs are available such as "if," "case,"
    "cycle," and "exit."

 9) Functions should never be called with a "call" statement.

10) The generic form of an intrinsic function should be used whenever
    possible.  For example, use SQRT(DP) rather than DSQRT(DP).

11) Real or integer constants should be defined as parameters.
      real(chm_real),parameter :: ONE=1.0D0, THREE=3.0D0, FIVE=5.0D0, &
                                  SEVEN=7.0D0
      integer(chm_int),parameter :: MAXATM=99999

    See ltm/number_ltm.src for frequently used numbers.
    Real numbers may never be placed in a calling sequence.
    All physical constants should be declared as parameters in
    ltm/consta_ltm.src
    Constants and numbers can be used by adding 
    
    use consta
    
    to routines or modules. 

12) Routines should have no implicitly declared variables.  This means that
    all variables and arrays, whether passed or not, must be explicitly 
    declared. Each module must thus contain

      implicit none

    as the first statement after any "use" statements and before any
    declarations. This obviates the need for having the implicit none
    statement in each of the subroutines contained in the module.
    A routine that is not contained in a module must have the
    implicit none statement as the first statement after any "use"
    statements and before any declarations.

13) There is no upper or lower case rule in CHARMM except that any
    variable or subroutine name should have consistent case throughout
    all of CHARMM code. It is helpful to use all caps for parameter
    variables.

14) No tabs should appear in code or documentation.

15) All strings must be stored in character variables. Use
    character(len=<n>) for character declarations, where <n> is the
    length of the string. a "*" may be used for the length of a passed
    string but this is discouraged.

16) For routine command parsing, the keyword parsing functions INDXA,
    GTRMA, GTRMF, GTRMI, and NEXTA4 should be used.

17) The recommended length for names of frequently used variables is
    4-10 characters.  Avoid single letter variables, except as indices
    for simple loops. Avoid overriding standard Fortan words such as
    SUM or TYPE.

18) All variables must be declared with a kind. Use the kinds available
    in chm_kinds_ltm.src, the CHARMM variable kinds (chm_kinds) module.  If a 
    new kind is used, add it to the chm_kinds module.

19) All variables must be initialized before first use. Most
    initialization is done in the setup or initialization routine in a
    module.

20) Other coding conventions make it easier to search through text for
    particular strings using the SEARCH, fpat, or grep commands.
    Poorly placed spaces can make it very difficult to maintain code.
    There cannot be a space within a variable name.  Here are some
    other examples;

         Good                         Please Avoid
        -----------------            ------------------
         GOTO                         GO TO
         CALL DOSOME(...              CALL  DOSOME(...
                                      CALL DOSOME (...
         ARRAY(5) = 20
         ARRAY(5)=20                  ARRAY (5) = 20

21) The ltm directory contains modules that have no dependencies on
    other modules, except for the chm_kinds module. Examples are modules
    containing global parameters and variables. 

22) Avoid duplicating code. If a defect is found in some code, and there
    are multiple copies of it, the remedy must be applied to all copies.
    If code is not duplicated, all its users benefit from any improvement
    to it.



File: developer.doc -=- Node: Tools
Up: Top -=- Previous: Standards -=- Next: Modify



                        CHARMM Developer Tools

CHARMM is available on a variety of computational devices and we
strongly support multiplatform development efforts.  CHARMM tools are
utility programs/procedures for installation, modification, 
optimization, etc.  The preprocessor PREFX and utility procedures
for makefile generation are located in ~/cnnXm/tool.  The
FLECS to FORTRAN translator FLEXFORT is no longer needed since CHARMM
c23f2 and was removed from this and later distribution versions.

* Menu:

* (prefx.doc)::  CHARMM Source Code Preprocessor
* makemod::      Module Makefiles and Optimization Procedure



File: developer.doc -=- Node: makemod
Up: Tools -=- Previous: (prefx.doc) -=- Next: Modify



                  Module Makefiles and Optimization

The installation script install.com works with a set of makefiles in
~/cnnXm/build/{machine_type}.  These makefiles play the key role in
developing, optimizing and porting CHARMM code on the machine you are
working with.


[1] Porting to Other Machines

    You may begin with the given set of makefiles for a machine close
in the architecture to the one to which you intend to port CHARMM.
First you have to decide a name for the machine platform.  For
example, IBMRS was chosen for the IBM RS/6000 series.

cp -r  ~/cnnXm/build/{closely_related_machine_type} \
       ~/cnnXm/build/{your_chosen_machine_type}

Then delete Makefile in the new build directory and remane
Makefile_{closely_related_machine_type} to Makefile_{your_machine_type}.
You may have to modify compile commands and compiler flags in the
Makefile template.
    Study carefully ~/cnnXm/install.com and modify it if necessary.
In most cases, you just need to correct echo messages to address your
machine properly.  Then issue the install.com command.


[2] Optimization

    Once the makefiles are working properly, you can carry out a
compiler level optimization for the CHARMM version.  FORTRAN compile
macro's are defined in Makefile_{machine_type}, e.g., $(FC1), $(FC2),
$(FC3), etc.  Compiler options are bound to these compile macros.  You
may inspect each module makefiles and set a proper compile command for
a given FORTRAN source.  For example, the following are the default
optimization flags for the c24b1 release.  Most of source files are
compiled by $(FC2) execpt

  build/convex/energy.mk
       $(FC0) ehbond.f
       $(FCR) enefst2.f
       $(FCR) enefst2q.f
       $(FC3) enefvect.f

  build/convex/image.mk
       $(FCR) imnbf2p.f
       $(FC3) imnbfp.f
       $(FC0) nbondm.f

  build/convex/manip.mk
       $(FC0) corman.f
       $(FC3) fshake.f
       $(FCR) fshake2.f

  build/convex/nbonds.mk
       $(FCR) enbf2.f
       $(FCR) enbf3.f
       $(FCR) enbf4.f
       $(FCR) enbf5.f
       $(FC3) ewaldf.f
       $(FCR) ewaldf2.f
       $(FCR) nbndf2p.f
       $(FC3) nbndfp.f

  build/convex/quantum.mk
       $(FC0) qmdata.f
       $(FC0) qmene.f
       $(FC0) qmjunc.f
       $(FC0) qmpac.f
       $(FC0) qmset.f


[3] Generating Module Makefiles

    We have included scripts that find all module dependencies.  When you
want to create the full set of module makefiles, you may use setmk.com
in ~/cnnXm/tool.

        setmk.com UNX

    This generates makefiles in ~/cnnXm/build/UNX, which install.com
copies to ~/cnnXm/build/{machine-type} as needed.


[4] Usage Note on makemod

    When you generate module.mk files from scratch, the FORTRAN
compile macro $(FC2) is used for all source files.  In order to set
the compiler option for further optimization, you have to modify
the module makefiles to set the macro manually.



File: developer.doc -=- Node: Modify
Up: Top -=- Previous: Tools -=- Next: Document



          The procedure for modifying anything in CHARMM

This procedure describes the steps which should be taken when
modifying a source file in CHARMM.  When you are developing CHARMM
source code, always maintain close contact with the CHARMM manager
and other developers.  Inform them your development plan and which
files you are working on.  See *note Checkin:: for the procedures
to follow when submitting your developmental code to the CHARMM manager.

 1) Get a copy of the current development code.  If you are a CHARMM
    developer and plan to integrate your program into CHARMM in the
    future, make sure that you obtain the most current revision from
    Subversion.  Check with the CHARMM manager.

 2) Once you obtain the code, you are branching out from the main
    CHARMM source code control system.  You should record details
    of modification so that you may reproduce them when you check your
    files in with the CHARMM manager.

 3) While you make modifications and debug them, follow the guidelines
    in *note Standards::, so that CHARMM code will be consistent.
    If your modification does not involve any changes in the source file
    directory structure and makes no changes in USE statements,
    you may use the module makefiles supplied (with the extension .mk)
    in ~/cnnXm/build/UNX.  If you add/remove any source files,
    reorganize them, modify any USE statements or are porting to
    a machine that is not already supported, you have to build the
    relevant module make files.  See *note makemod:: for more
    information on makemod.

 4) In your local ~/cnnXm directory, you may issue the install.com
    command to build the library and the executable.
    See *note Install: (install.doc)Install.
    Your library is built in ~/cnnXm/lib/{machine_type} and the
    executable will be in ~/cnnXm/exec/{machine_type}.  You may find
    the log file {machine_type}.log in ~/cnnXm/build/{machine_type}.

 5) If your modification involves a new feature, you should either
    modify an existing test case or make a new test case to demonstrate
    and check its operation.  See *note testing: (testcase.doc), for a
    description of the tests currently available.  If you add a new test
    case, update the ~charmm/doc/testcase.doc file.  Each new test case
    should run in 1 second or less on a modern workstation.

 6) If your change involves adding or modifying a command or adding or
    modifying a feature, modify the existing documentation or if none is
    available, create new documentation.  Make sure that the emacs info
    program can read the document and the format of your documentation
    is consistent with other documents. See *note Document::.



File: developer.doc -=- Node: Document
Up: Top -=- Previous: Modify -=- Next: API



          How to Document CHARMM Commands and Features

Documentation is an integral part of CHARMM developments.  In order to
document commands and features under development in a consistent
manner, the following documentation format is recommended.  All
documentation should be accessible (readable) through the emacs info
facility.  If you do not know how to insert the info directives, ask the
CHARMM manager for assistance.  If a new functional module is being 
introduced, a new .doc file should be created.  For modifications or
extensions of existing CHARMM modules/functions, the preexisting .doc
file should be revised. 

     Each documentation file, with the extension .doc, should contain

     1) One brief paragraph describing the motivation, theory, or 
        procedure relevant to the feature being documented.  Here,
        a few references can be given.

     2) A table of contents of the documentation (to serve as the info
        menu).

     3) The command syntax.

     4) A complete description of all the commands, sub-commands, and
        command options.  The syntax, defaults and file names involved
        should be described.  A brief description of what the command 
        accomplishes should also be given.  The order in which various 
        commands should be invoked should be described.  Relevant commands 
        and subcommands can be cross-referenced with a key.

     5) One or two examples involving the concepts and commands described
        (No output listing).

     The same notation should be followed throughout the documentation.

     [...]   optional, can be present only once, if at all.

     {...}   can be repeated any number of times, must be present
             at least once.

     [{...}] or [{...}]  can either be missing or be present any
                         number of times. 

     n{...}  must be present exactly n times.

     <A|b>   either  A or B must be present.

     Syntax definitions will use literal keywords such as VIBRan,
READ, MINI, VERLet, etc.  These are to be typed as such. 
         
     Syntax definitions can also use dummy keywords such as atom_name,
atom_index and atom_type.  The meaning and variable type can be listed
just after the syntax notation.

     For literal keywords the documentation and examples will use
uppercase characters immediately followed by zero or more lower case
characters.  Dummy keywords will be written in all lower case.



File: developer.doc -=- Node: API
Up: Top -=- Previous: Document -=- Next: Checkin



                            API Documentation

     As a complement to the required command and feature documentation,
the free Doxygen tool (http://www.doxygen.org/) can automatically
generate low-level documentation from the source code. Doxygen reads
declarations of modules, subroutines, and variables, and generates HTML
with cross-references showing the relationships between them.

     Doxygen also recognizes Fortran comments beginning with !> as text to
include in the HTML output. Some examples of such comments are in
source/pert/lambdadyn.src.

     Before you run Doxygen on CHARMM code, download the Doxygen 1.6
source distribution and apply tool/doxygen.patch as follows:

     cd doxygen-1.6
     patch -p0 < ../charmm/tool/doxygen.patch

and follow the Doxygen installation instructions. Then the shell command

     cd ../charmm
     doxygen tool/Doxyfile

generates documentation in a directory named apidoc. A good starting
point for browsing is apidoc/html/files.html.

     If you have Graphviz (http://www.graphviz.org/) installed, Doxygen
can generate call diagrams for each subroutine. To do this, edit
tool/Doxyfile and change CALL_GRAPH and CALLER_GRAPH to YES.



File: developer.doc -=- Node: Checkin
Up: Top -=- Previous: API -=- Next: Top



          Checkin Procedure in CHARMM Management System

CHARMM is maintained as a single-source software package.
The following rules have been established to minimize conflicts
and delays and to allow for error-free integration of CHARMM   
developments from many scientists.

 1) It is always wise to inform the CHARMM manager about your
    development plan and timetable so that he may better arrange the 
    administrative schedule and also prevent you from duplicating the work
    of others.  The list of files you are working on and the nature of
    the modifications should be reported in advance. 
 
 2) Developments must be submitted to the CHARMM manager by
    December 30 for inclusion in the February distributions or
    June 30 for the August distributions.

 3) Be certain that the submitted developments are based on the most
    recent development version of CHARMM.  The check-in package
    (see below) should compile out-of-the-box when merged with the
    base version.

 4) Prior to check-in, run "test.com" after integration of the
    check-in package with the appropriate base version of CHARMM.
    Compare the results in the output directory with those obtained
    when using the base version.  If you are introducing new
    preprocessor (pref.dat) keywords to control the compilation of
    code for new features (which is recommended), check the test.com
    results for executables produced both with and without the new
    keyword(s).
 
 5) The check-in or submission package should include the following:
     *  modified source files (using the CHARMM source directory structure),
     *  updated or new documentation (doc/*.doc) files, and
     *  updated testcase files

    These files should be assembled in a tar archive conforming to the
    CHARMM distribution directory structure.

 6) Post a completed project form (http://charmm.hanyang.ac.kr/172) to
    the CHARMM development bulletin board (http://charmm.hanyang.ac.kr/).
    The project form should contain a succinct description of the 
    submitted modifications and new features, the name(s) and institutional
    affiliations of the developer(s), the date, the base CHARMM version,
    new preprocessor keywords, and lists of the new and modified files.
    Upload your tar archive as an attachment to the project form.

NIH Helix/Biowulf Systems
charmm.org Homepage