GMIN MOVES module

From Docswiki
Jump to navigation Jump to search

Introduction

Alongside the implementation of CUDA L-BFGS, we are currently in the process of re-working how GMIN takes 'steps', perturbing the coordinates before minimising during each quench. A document describing the current state of this project can be found on the group Google Drive here. If you do not have access, please request it.

The module itself is located here:

~/svn/GMIN/source/moves.f90

This page is intended to provide an outline for the re-implementation of existing GMIN moves within the new framework of the MOVES module, including appropriate sanity checks in the new GMIN SANITY module.

Design principles

Error creating thumbnail: Unable to save thumbnail to destination
Basic diagram showing the new GMIN step taking flow

The design of the new system is very simple and covered in detail in the working document. In short, a new parser is being developed by Kyle to allow the construction of a highly flexible move set. When a step is to be taken, this information is passed to a potential specific driver routine. This driver routine then modifies the coordinates using the subroutines in MOVES as appropriate.

Coding principles

Error creating thumbnail: Unable to save thumbnail to destination
A useful way of thinking while coding

In order to keep ourselves from repeating the mistakes of the past, we all need to keep to the following coding guidelines. Please make sure you have read and understood the following points. If you make commits which do not conform to these guidelines, they will be reverted.

  • code blocks must be indented in a manner consistent with the rest of the module (3 spaces)
  • variable names must be understandable e.g. MAX_STEP rather than S
  • avoid using GOTOs!
  • all subroutines must be fully commented (in English)
  • all required and optional arguments must be fully explained
  • every move routine must have an optional final argument ATOM_LIST to apply the move to a subset of atoms. See the example below
  • only utility modules (e.g. VEC3) may be USE'd from MOVES. This does NOT include COMMONS
  • no potential specific information may be required by any routine in MOVES - this should be dealt with in the driver routine
  • move routines should NOT print anything outside of STOP messages - printing should come from the appropriate driver routines
  • where appropriate, sanity checks (GMIN SANITY module) and tests (GMIN TESTS module) should be included in move routines

Example routine: CARTESIAN_SPHERE

As a working example of the principles of this rewrite, here is the implementation of James Farrell's spherically symmetric Cartesian move subroutine from TAKESTEP, now in the MOVES module. In particular, this demonstrates how to correctly implement the optional ATOM_LISTS argument and the sanity checks that should be used in every move routine:

SUBROUTINE CARTESIAN_SPHERE(XYZ, MAX_STEP, ATOM_LIST)
! Add a random spherically symmetric displacement of up to MAXSTEP to each atom
! in the ATOM_LIST array if present, or all atoms if not.
!
! Arguments
! ---------
!
! Required: 
! XYZ(in/out): coordinates array from GMIN, in Cartesian coordinates
! MAX_STEP(in): the maximum step size
!
! Optional:
! ATOM_LIST(in): list of atoms to be moved - if omitted, all are moved

! The VEC3 module (vec3.f90) contains helper functions for handling vectors and matricies
   USE VEC3
! The SANITY module contains sanity check functions
   USE SANITY
   IMPLICIT NONE
   INTEGER                                       :: I
   INTEGER                                       :: NUM_ATOMS
   INTEGER, OPTIONAL, DIMENSION(:), INTENT(IN)   :: ATOM_LIST
   DOUBLE PRECISION                              :: DPRAND
   DOUBLE PRECISION, INTENT(IN)                  :: MAX_STEP
   DOUBLE PRECISION, DIMENSION(:), INTENT(INOUT) :: XYZ
   LOGICAL, ALLOCATABLE, DIMENSION(:)            :: ATOM_MASK
   LOGICAL                                       :: TEST

! Sanity check - are the coordinates in XYZ Cartesian? 
! Check if the SIZE is a multiple of 3
   TEST=.FALSE.
   TEST=CHECK_DIMENSION(SIZE(XYZ),3)
   IF (.NOT.TEST) THEN
      STOP 'Coordinates in a non-Cartesian basis passed to CARTESIAN_SPHERE'
   ENDIF

! Set NUM_ATOMS
   NUM_ATOMS = SIZE(XYZ) / 3

! Set up ATOM_MASK
   ALLOCATE(ATOM_MASK(NUM_ATOMS))
   ATOM_MASK = .FALSE.

! Check to see if an ATOM_LIST was provided
   IF (PRESENT(ATOM_LIST)) THEN
! If so, determine which atoms the move applies to and set up ATOM_MASK
      DO I = 1, SIZE(ATOM_LIST)
         ATOM_MASK(ATOM_LIST(I)) = .TRUE.
      END DO
   ELSE
! Otherwise, apply the move to all atoms
      ATOM_MASK = .TRUE.
   ENDIF

! Apply the move to the atoms specified 
   DO I = 1, NUM_ATOMS
! Skip atoms we do not want to move
      IF (.NOT. ATOM_MASK(I)) CYCLE
! Otherwise apply the move
      XYZ(3*I-2:3*I)=XYZ(3*I-2:3*I)+VEC_RANDOM()*(DPRAND()**(1.0D0/3.0D0))*MAX_STEP
   ENDDO

END SUBROUTINE CARTESIAN_SPHERE

Testing new moves

As this is still a work in progress and the parser and driver routines are not currently functioning, the only way to test new moves is via the use of the NEWMOVES keyword in GMIN. This bypasses all existing step-taking routines in MC and will let you call your test move directly as required. Here is an example of this from mc.F showing a call to the old GROUPROTATION and new CARTESIAN_SPHERE routines that we have been using to test CUDAGMIN:

! csw34> Temporary calls to new step taking routines for testing
            IF (NEWMOVEST) THEN
! GROUPROTATION moves are in here for testing CUDAGMIN only
               IF (GROUPROTT) CALL GROUPROTSTEP(JP)
! Each new move should take a final, optional argument - ATOM_LIST
! This is the list of atoms in a integer array to which you want to
! apply the move. 
               CALL CARTESIAN_SPHERE(COORDS(:,JP),STEP(JP))
!               CALL CARTESIAN_SPHERE(COORDS(:,JP),STEP(JP),ATOM_LIST)
!               CALL CARTESIAN_SIMPLE(COORDS(:,JP),STEP(JP))
!               CALL CARTESIAN_SIMPLE(COORDS(:,JP),STEP(JP),ATOM_LIST)
            ELSE
...
...
OLD STEP TAKING FOLLOWS

Please feel free to modify this section of code as required to test your move routines, but do not delete anything without consulting the person who implemented it - just comment out anything you don't want to use while you test.

--Csw34 17:24, 14 April 2014 (UTC)