Tutorial -- How to build a new customized Collective Variable in Amber16-PMEMD

by Feng Pan, Christopher Roland and Celeste Sagui

This tutorial introduces how to build you own customized Collective Variable (CV) in NFE module of PMEMD in Amber16. After the implementation of the new CV, you can use it for SMD and ABMD simulations included in NFE module. Also it is free to use if you write new codes regarding with new sampling algorithms.

Here we choose an easy example to show the process of implementation. We define the new CV as:

DISTANCE_Z : projection of a distance vector on an axis.

This CV has been implemented in NAMD but not in AMBER. Here we just pick the easiest case: the distance is between two atoms and the axis is given by a constant vector. It will not be very hard to extend it to more complicated cases (like the distance is between two groups of atoms) once we are familiar of the process of implementation. I would be brilliant that we successfully finish the implementation and people can start to use this CV in AMBER.

This tutorial consists of the following step:

  1. Define the input format of CV.

  2. Decide the mathematical expression of the value and derivative of the new CV.

  3. Build new related subroutines inside the source code.

  4. Compile the new codes and get new executable.

  5. Test the new CV.


1. Define the input format of CV.

The first thing we should concern is that how can we read the CV from our input file. The default CV type in the source code has two arrays to read: cv_i and cv_r, so it is straightforward that we have the array cv_i to store the index of atoms and cv_r to store the unit vector of given axis.

In this way, an example of CV input file of the new CV could be:

&colvar

cv_type = 'DISTANCE_Z'

cv_i = 1, 2 ! the distance between atom 1 and atom 2

cv_r = 0, 0, 1 ! calculate the projection to z-axis

/


2. Decide the mathematical expression of the value and derivative of the new CV.

Before we write the code, we need to know the mathematical expression to calculate the value of DISTANCE_Z and the derivative with respect to coordinates. Then we can easily put it in Fortran code. For this, the calculation is pretty easy:

value = (r2 - r1) • v0

derivative(r1) = - v0

derivative(r2) = v0

Here r1,r2 are the coordinates of the two atoms, and v0 is the unit vector of given axis.


3. Build new related subroutines inside the source code.

All CV related subroutines are included inside the module nfe_colvar_mod in the file nfe_colvar.F90. So to build a new CV, we need to add certain subroutines in nfe_colvar.F90.

Here I give a template for creating a new customized CV custom_cv_template.F90, where I only list the part of codes that need to be changed.

To explain this in details, let's go to this example DISTANCE_Z. First, you need to add the new CV type to the parameters section:

integer, public, parameter :: COLVAR_DISTANCE_Z = 20

Then basically, four functions or subroutines are needed for a new CV:

  • v_DISTANCE_Z : to calculate the value of the CV

  • f_DISTANCE_Z : to calculate the force by the CV

  • b_DISTANCE_Z : a bootstrap subroutine to check CV before use

  • p_DISTANCE_Z : a print subroutine to print out CV information to mdout

    Here I have written the four subroutines in an individual file DISTANCE_Z.F90.

    (Comments: It is always not hard to write codes to get the value function. For the derivative, if you find it too hard to code the force subroutine, you can use Maple or Matlab to get the fortran code.)

    Now you can freely call the four subprograms from outside to use the new CV. If you want it be well-integrated in the NFE module. You need to add the selection of those subroutines to the select case sections in the following subroutines or functions:

          colvar_value; colvar_force; colvar_bootstrap; colvar_print

    For example, in colvar_value, you should do changes like this:

      select case(cv%type)
        case(COLVAR_ANGLE)
          value = v_ANGLE(cv, x)
          ......
        case(COLVAR_DISTANCE_Z)
          value = v_DISTANCE_Z(cv, x)

        case default
          nfe_assert_not_reached()
          value = dble(0)
      end select

    Similar changes should be made in the other three subprograms.


    4. Compile the new codes and get new executable.

    After finishing the coding part we need to recompile PMEMD to get updated executable. For example, to get new pmemd.cuda, we do

        cd $AMBERHOME && ./configure -cuda < compiler >
        cd src/pmemd && make install

    5. Test the new CV.

    To make sure our new CV works well, we should do a simple test..