forked from lijiext/lammps
git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@11711 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
parent
3eac8574a6
commit
d94e1e1ac5
|
@ -25,5 +25,7 @@ poems POEMS rigid-body integration package, POEMS package
|
|||
from Rudranarayan Mukherjee (RPI)
|
||||
meam modified embedded atom method (MEAM) potential, MEAM package
|
||||
from Greg Wagner (Sandia)
|
||||
qmmm quantum mechanics/molecular mechanics coupling interface
|
||||
from Axel Kohlmeyer (Temple U)
|
||||
reax ReaxFF potential, REAX package
|
||||
from Adri van Duin (Penn State) and Aidan Thompson (Sandia)
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
# -*- Makefile -*- for coupling LAMMPS to PWscf for QM/MM molecular dynamics
|
||||
|
||||
# this file will be copied to Makefile.lammps
|
||||
EXTRAMAKE = Makefile.lammps.empty
|
||||
|
||||
# top level directory of Quantum ESPRESSO 5.1 or later
|
||||
QETOPDIR=$(HOME)/compile/espresso
|
||||
|
||||
# import compiler settings from Quantum ESPRESSO
|
||||
sinclude $(QETOPDIR)/make.sys
|
||||
|
||||
# FLAGS for c++ OpenMPI when QE was compiled with GNU Fortran 4.x
|
||||
MPICXX=mpicxx
|
||||
MPICXXFLAGS=-DOMPI_SKIP_MPICXX=1 -O2 -Wall -g \
|
||||
-I../../src -I$(QETOPDIR)/COUPLE/include
|
||||
MPILIBS=-fopenmp -lgfortran -ldl -ljpeg -lmpi_f77 -lmpi
|
||||
|
||||
# location of required libraries
|
||||
# part 1: hi-level libraries for building pw.x
|
||||
PWOBJS = \
|
||||
$(QETOPDIR)/COUPLE/src/libqecouple.a \
|
||||
$(QETOPDIR)/PW/src/libpw.a \
|
||||
$(QETOPDIR)/Modules/libqemod.a
|
||||
# part 2: lo-level libraries for all of Q-E
|
||||
LIBOBJS = \
|
||||
$(QETOPDIR)/flib/ptools.a \
|
||||
$(QETOPDIR)/flib/flib.a \
|
||||
$(QETOPDIR)/clib/clib.a \
|
||||
$(QETOPDIR)/iotk/src/libiotk.a
|
||||
|
||||
# part 3: add-on libraries and main library for LAMMPS
|
||||
sinclude ../../src/Makefile.package
|
||||
LAMMPSCFG = openmpi-omp
|
||||
LAMMPSLIB = ../../src/liblammps_$(LAMMPSCFG).a
|
||||
|
||||
# part 4: local QM/MM library and progams
|
||||
SRC=pwqmmm.c libqmmm.c
|
||||
OBJ=$(SRC:%.c=%.o)
|
||||
|
||||
|
||||
default: libqmmm.a
|
||||
|
||||
all : tldeps libqmmm.a pwqmmm.x
|
||||
|
||||
pwqmmm.x : pwqmmm.o $(OBJ) $(PWOBJS) $(LIBOBJS) $(LAMMPSLIB)
|
||||
$(MPICXX) $(LDFLAGS) -o $@ $^ $(PKG_PATH) $(PKG_LIB) $(MPILIBS) $(LIBS)
|
||||
|
||||
libqmmm.a: libqmmm.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
@cp $(EXTRAMAKE) Makefile.lammps
|
||||
|
||||
%.o: %.c
|
||||
$(MPICXX) -c $(LAMMPSFLAGS) $(MPICXXFLAGS) $< -o $@
|
||||
|
||||
tldeps:
|
||||
( cd $(QETOPDIR) ; $(MAKE) $(MFLAGS) couple || exit 1)
|
||||
$(MAKE) -C ../../src $(MFLAGS) makelib
|
||||
$(MAKE) -C ../../src $(MFLAGS) $(LAMMPSCFG)
|
||||
$(MAKE) -C ../../src $(MFLAGS) -f Makefile.lib $(LAMMPSCFG)
|
||||
|
||||
clean :
|
||||
- /bin/rm -f *.x *.o *.a *~ *.F90 *.d *.mod *.i *.L
|
||||
|
||||
# explicit dependencies
|
||||
|
||||
pwqmmm.o: pwqmmm.c libqmmm.h
|
||||
libqmmm.o: libqmmm.c libqmmm.h
|
|
@ -0,0 +1,5 @@
|
|||
# Settings that the LAMMPS build will import when this package library is used
|
||||
|
||||
qmmm_SYSINC =
|
||||
qmmm_SYSLIB =
|
||||
qmmm_SYSPATH =
|
|
@ -0,0 +1,108 @@
|
|||
QM/MM support toplevel library
|
||||
|
||||
Axel Kohlmeyer, akohlmey@gmail.com
|
||||
Temple University, Philadelphia and ICTP, Trieste
|
||||
|
||||
This library provides the basic glue code to combine LAMMPS with the
|
||||
Quantum ESPRESSO package plane wave density functional theory code for
|
||||
performing QM/MM molecular dynamics simulations. More information on
|
||||
Quantum ESPRESSO can be found at: http://www.quantum-espresso.org
|
||||
|
||||
The interface code itself is designed so it can also be combined with
|
||||
other QM codes, however only support for Quantum ESPRESSO is currently
|
||||
the only option. Adding support for a different QM code will require
|
||||
to write a new version of the top-level wrapper code, pwqmmm.c, and
|
||||
also an interface layer into the QM code similar to the one in QE.
|
||||
|
||||
-------------------------------------------------
|
||||
|
||||
This directory has the source files to build a library and an
|
||||
executable for combining the pw.x program from Quantum ESPRESSO and
|
||||
LAMMPS into a single executable that can be used for QM/MM molecular
|
||||
dynamics simulations. LAMMPS will act as the MD "driver" and will
|
||||
delegate computation of forces for the QM subset of the system to
|
||||
Quantum ESPRESSO.
|
||||
|
||||
The toplevel code provided here will split the total number of cpus
|
||||
into three partitions: the first for running a DFT calculation, the
|
||||
second for running the "master" classical MD calculation, and the
|
||||
third for a "slave" classical MD calculation. Each calculation will
|
||||
have to be run in its own subdirectory with its own specific input
|
||||
data and will write its output there as well. This and other settings
|
||||
are provided in the QM/MM input file that is mandatory argument to the
|
||||
QM/MM executable. The number of MM cpus is provided as the optional
|
||||
second argument. The MM "slave" partition is always run with only 1
|
||||
cpu thus the minimum number is 2, which is also the default. Therefore
|
||||
a QM/MM calculation with this code requires at least 3 processes.
|
||||
|
||||
Thus the overall calling sequence is like this:
|
||||
|
||||
mpirun -np <total #cpus> ./pwqmmm.x <QM/MM input> [<#cpus for MM>]
|
||||
|
||||
A commented example is given below.
|
||||
|
||||
-------------------------------------------------
|
||||
|
||||
Build the library using one of the provided Makefile.* files or create
|
||||
your own, specific to your compiler and system. For example:
|
||||
|
||||
make -f Makefile.gfortran
|
||||
|
||||
When you are done building this library, two new files should
|
||||
exist in this directory:
|
||||
|
||||
libqmmm.a the library LAMMPS will link against
|
||||
Makefile.lammps settings the LAMMPS Makefile will import
|
||||
|
||||
Makefile.lammps is created by the make command by simply copying the
|
||||
Makefile.lammps.empty file. Currently no additional dependencies for
|
||||
this library exist.
|
||||
|
||||
-------------------------------------------------
|
||||
|
||||
To compile and link the final QM/MM executable, you have to build
|
||||
quantum espresso with the "pw" and "couple" targets. You also have
|
||||
to to install the USER-QMMM package for LAMMPS. You have to specify
|
||||
the path to the toplevel Quantum ESPRESSO directory, so that the
|
||||
compiler and linker settings can be imported.
|
||||
|
||||
The makefile variable MPILIBS needs to be set to include all linker
|
||||
flags that will need to be used in addition to the various libraries
|
||||
from the two packages. Please see the provided example(s).
|
||||
|
||||
"make -f Makefile.gfortran" all by itself will only compile the
|
||||
library (so that LAMMPS can be compiled into a standalone executable
|
||||
as well, when the USER-QMMM package is installed).
|
||||
"make -f Makefile.gfortran pwqmmm.x" will compile and link the QM/MM
|
||||
executable; "make -f Makefile.gfortran all" will recurse through the
|
||||
Quantum ESPRESSO and LAMMPS directories to compile all files that
|
||||
require recompilation and then link the executable.
|
||||
|
||||
Please refer to the specific LAMMPS and Quantum ESPRESSO documentation
|
||||
for details on how to set up compilation for each package and make
|
||||
sure you have a set of settings and flags that allow you to build
|
||||
each package successfully, so that it can run on its own.
|
||||
|
||||
-------------------------------------------------
|
||||
|
||||
# configuration file for QMMM wrapper
|
||||
|
||||
mode mech # coupling choices: o(ff), m(echanical), e(lectrostatic)
|
||||
steps 20 # number of QM/MM (MD) steps
|
||||
verbose 1 # verbosity level (0=no QM/MM output during run)
|
||||
restart water.restart # checkpoint/restart file to write out at end
|
||||
|
||||
# QM system config
|
||||
qmdir qm-pw # directory to run QM system in
|
||||
qminp water.in # input file for QM code
|
||||
qmout NULL # output file for QM code (or NULL to print to screen)
|
||||
|
||||
# MM master config
|
||||
madir mm-master # directory to run MM master in
|
||||
mainp water.in # input file for MM master
|
||||
maout water.out # output file for MM master (or NULL to print to screen)
|
||||
|
||||
# MM slave config
|
||||
sldir mm-slave # directory to run MM slave in
|
||||
slinp water_single.in # input file for MM slave
|
||||
slout water_single.out # output file for MM slave (or NULL to print to screen)
|
|
@ -0,0 +1,236 @@
|
|||
LAMMPS data file for water
|
||||
|
||||
96 atoms
|
||||
64 bonds
|
||||
32 angles
|
||||
0 dihedrals
|
||||
0 impropers
|
||||
|
||||
2 atom types
|
||||
1 bond types
|
||||
1 angle types
|
||||
0 dihedral types
|
||||
0 improper types
|
||||
|
||||
0.0 9.865 xlo xhi
|
||||
0.0 9.865 ylo yhi
|
||||
0.0 9.865 zlo zhi
|
||||
|
||||
Masses
|
||||
|
||||
1 15.9994
|
||||
2 1.008
|
||||
|
||||
Pair Coeffs
|
||||
|
||||
1 0.102 3.188
|
||||
2 0.000 0.000
|
||||
|
||||
Bond Coeffs
|
||||
|
||||
1 450 0.9572
|
||||
|
||||
Angle Coeffs
|
||||
|
||||
1 55.0 104.52
|
||||
|
||||
Atoms
|
||||
|
||||
1 0 1 -0.83400 -4.943157 4.999555 1.106073
|
||||
2 0 2 0.41700 -3.989383 5.319684 0.882671
|
||||
3 0 2 0.41700 -4.970859 4.118886 0.645414
|
||||
4 0 1 -0.83400 0.087651 3.997966 0.245184
|
||||
5 0 2 0.41700 -0.189448 3.238564 0.737637
|
||||
6 0 2 0.41700 0.340165 3.716546 -0.646859
|
||||
7 0 1 -0.83400 -1.476825 2.573003 3.969964
|
||||
8 0 2 0.41700 -2.476262 2.342909 3.971242
|
||||
9 0 2 0.41700 -1.177059 2.137822 4.797386
|
||||
10 0 1 -0.83400 -2.866718 -2.698567 -5.842805
|
||||
11 0 2 0.41700 -2.116039 -2.563955 -6.460863
|
||||
12 0 2 0.41700 -2.633035 -3.566300 -5.365619
|
||||
13 0 1 -0.83400 4.305354 0.916065 2.310797
|
||||
14 0 2 0.41700 4.681590 1.456886 1.564890
|
||||
15 0 2 0.41700 4.477897 -0.001266 2.162118
|
||||
16 0 1 -0.83400 3.140624 -2.958877 0.699556
|
||||
17 0 2 0.41700 2.416048 -3.267548 1.282072
|
||||
18 0 2 0.41700 3.733007 -3.780312 0.657627
|
||||
19 0 1 -0.83400 -2.702605 -5.503344 -2.185117
|
||||
20 0 2 0.41700 -2.503651 -6.454759 -1.864686
|
||||
21 0 2 0.41700 -2.445484 -4.875090 -1.412444
|
||||
22 0 1 -0.83400 -0.499359 1.396504 -3.109410
|
||||
23 0 2 0.41700 -0.051681 2.161550 -2.706675
|
||||
24 0 2 0.41700 -1.148357 1.125379 -2.447316
|
||||
25 0 1 -0.83400 4.890520 4.325756 3.842052
|
||||
26 0 2 0.41700 3.893761 4.308535 3.950637
|
||||
27 0 2 0.41700 4.946166 4.514250 2.851741
|
||||
28 0 1 -0.83400 5.691644 1.713787 4.310484
|
||||
29 0 2 0.41700 5.228679 2.581555 4.361998
|
||||
30 0 2 0.41700 5.119255 1.176301 3.635805
|
||||
31 0 1 -0.83400 0.560959 0.041910 -5.382932
|
||||
32 0 2 0.41700 1.221529 -0.722558 -5.312134
|
||||
33 0 2 0.41700 -0.033504 0.016189 -4.590395
|
||||
34 0 1 -0.83400 -0.740775 1.579130 1.430754
|
||||
35 0 2 0.41700 0.200064 1.382700 1.565649
|
||||
36 0 2 0.41700 -0.918129 1.879209 2.375874
|
||||
37 0 1 -0.83400 3.602330 -0.138439 -3.581327
|
||||
38 0 2 0.41700 4.487536 -0.216376 -4.000513
|
||||
39 0 2 0.41700 3.049262 -0.796203 -4.061640
|
||||
40 0 1 -0.83400 -2.574131 1.816065 -0.773020
|
||||
41 0 2 0.41700 -1.984990 1.759512 0.021520
|
||||
42 0 2 0.41700 -2.623056 0.813950 -0.951715
|
||||
43 0 1 -0.83400 -0.681860 -2.105217 2.617966
|
||||
44 0 2 0.41700 0.075591 -2.677482 2.470155
|
||||
45 0 2 0.41700 -0.381447 -1.260528 3.119035
|
||||
46 0 1 -0.83400 0.877670 3.520059 -2.346170
|
||||
47 0 2 0.41700 0.962603 4.130609 -3.093700
|
||||
48 0 2 0.41700 1.694708 2.956694 -2.260009
|
||||
49 0 1 -0.83400 4.626681 -5.379887 -3.195904
|
||||
50 0 2 0.41700 5.384273 -5.281869 -2.664131
|
||||
51 0 2 0.41700 4.959718 -5.195755 -4.090586
|
||||
52 0 1 -0.83400 -2.975363 -0.549128 -4.157351
|
||||
53 0 2 0.41700 -3.005586 -1.347160 -4.749504
|
||||
54 0 2 0.41700 -3.484397 0.188753 -4.601707
|
||||
55 0 1 -0.83400 -1.784475 4.961314 -4.576682
|
||||
56 0 2 0.41700 -1.799259 4.090209 -5.083548
|
||||
57 0 2 0.41700 -2.115771 4.808141 -3.667451
|
||||
58 0 1 -0.83400 3.259544 2.452140 -2.230180
|
||||
59 0 2 0.41700 3.323170 1.530411 -2.542184
|
||||
60 0 2 0.41700 3.802574 3.049282 -2.844435
|
||||
61 0 1 -0.83400 1.201227 -3.873074 1.979232
|
||||
62 0 2 0.41700 0.666072 -4.403011 1.263244
|
||||
63 0 2 0.41700 1.518668 -4.606497 2.643697
|
||||
64 0 1 -0.83400 1.656255 1.671444 2.585800
|
||||
65 0 2 0.41700 2.558345 1.396868 2.334225
|
||||
66 0 2 0.41700 1.332188 1.089240 3.372965
|
||||
67 0 1 -0.83400 2.403906 -1.938370 -5.265845
|
||||
68 0 2 0.41700 2.088628 -2.761173 -4.852894
|
||||
69 0 2 0.41700 3.112550 -2.143084 -5.990367
|
||||
70 0 1 -0.83400 6.671015 -0.695457 -1.582148
|
||||
71 0 2 0.41700 5.710948 -0.796794 -1.184378
|
||||
72 0 2 0.41700 6.545527 -0.771012 -2.574381
|
||||
73 0 1 -0.83400 -5.424609 -1.825624 2.814190
|
||||
74 0 2 0.41700 -4.617447 -2.210882 3.171264
|
||||
75 0 2 0.41700 -5.776719 -2.412234 2.075929
|
||||
76 0 1 -0.83400 1.150487 -4.096740 5.844391
|
||||
77 0 2 0.41700 1.076286 -3.915393 6.837958
|
||||
78 0 2 0.41700 0.183470 -4.044319 5.594055
|
||||
79 0 1 -0.83400 2.061664 4.194185 3.777119
|
||||
80 0 2 0.41700 1.882571 3.326557 3.243961
|
||||
81 0 2 0.41700 1.683407 4.114458 4.646069
|
||||
82 0 1 -0.83400 -2.311755 -4.122312 0.194948
|
||||
83 0 2 0.41700 -1.444386 -4.631613 0.333538
|
||||
84 0 2 0.41700 -2.118545 -3.162947 0.233986
|
||||
85 0 1 -0.83400 1.118351 -3.252459 -1.395623
|
||||
86 0 2 0.41700 0.435993 -2.622296 -1.064746
|
||||
87 0 2 0.41700 1.972678 -3.141898 -0.956755
|
||||
88 0 1 -0.83400 4.038733 -0.963636 -0.898121
|
||||
89 0 2 0.41700 3.616635 -1.752805 -0.471089
|
||||
90 0 2 0.41700 3.665491 -0.726014 -1.803310
|
||||
91 0 1 -0.83400 -0.910973 -1.540333 -0.388194
|
||||
92 0 2 0.41700 -1.741083 -1.200928 -0.798897
|
||||
93 0 2 0.41700 -0.901836 -1.451834 0.541945
|
||||
94 0 1 -0.83400 4.850315 2.494782 0.151704
|
||||
95 0 2 0.41700 4.126910 2.456315 -0.566034
|
||||
96 0 2 0.41700 5.642328 2.128654 -0.307363
|
||||
|
||||
Bonds
|
||||
|
||||
1 1 1 2
|
||||
2 1 1 3
|
||||
3 1 4 5
|
||||
4 1 4 6
|
||||
5 1 7 8
|
||||
6 1 7 9
|
||||
7 1 10 11
|
||||
8 1 10 12
|
||||
9 1 13 14
|
||||
10 1 13 15
|
||||
11 1 16 17
|
||||
12 1 16 18
|
||||
13 1 19 20
|
||||
14 1 19 21
|
||||
15 1 22 23
|
||||
16 1 22 24
|
||||
17 1 25 26
|
||||
18 1 25 27
|
||||
19 1 28 29
|
||||
20 1 28 30
|
||||
21 1 31 32
|
||||
22 1 31 33
|
||||
23 1 34 35
|
||||
24 1 34 36
|
||||
25 1 37 38
|
||||
26 1 37 39
|
||||
27 1 40 41
|
||||
28 1 40 42
|
||||
29 1 43 44
|
||||
30 1 43 45
|
||||
31 1 46 47
|
||||
32 1 46 48
|
||||
33 1 49 50
|
||||
34 1 49 51
|
||||
35 1 52 53
|
||||
36 1 52 54
|
||||
37 1 55 56
|
||||
38 1 55 57
|
||||
39 1 58 59
|
||||
40 1 58 60
|
||||
41 1 61 62
|
||||
42 1 61 63
|
||||
43 1 64 65
|
||||
44 1 64 66
|
||||
45 1 67 68
|
||||
46 1 67 69
|
||||
47 1 70 71
|
||||
48 1 70 72
|
||||
49 1 73 74
|
||||
50 1 73 75
|
||||
51 1 76 77
|
||||
52 1 76 78
|
||||
53 1 79 80
|
||||
54 1 79 81
|
||||
55 1 82 83
|
||||
56 1 82 84
|
||||
57 1 85 86
|
||||
58 1 85 87
|
||||
59 1 88 89
|
||||
60 1 88 90
|
||||
61 1 91 92
|
||||
62 1 91 93
|
||||
63 1 94 95
|
||||
64 1 94 96
|
||||
|
||||
Angles
|
||||
|
||||
1 1 2 1 3
|
||||
2 1 5 4 6
|
||||
3 1 8 7 9
|
||||
4 1 11 10 12
|
||||
5 1 14 13 15
|
||||
6 1 17 16 18
|
||||
7 1 20 19 21
|
||||
8 1 23 22 24
|
||||
9 1 26 25 27
|
||||
10 1 29 28 30
|
||||
11 1 32 31 33
|
||||
12 1 35 34 36
|
||||
13 1 38 37 39
|
||||
14 1 41 40 42
|
||||
15 1 44 43 45
|
||||
16 1 47 46 48
|
||||
17 1 50 49 51
|
||||
18 1 53 52 54
|
||||
19 1 56 55 57
|
||||
20 1 59 58 60
|
||||
21 1 62 61 63
|
||||
22 1 65 64 66
|
||||
23 1 68 67 69
|
||||
24 1 71 70 72
|
||||
25 1 74 73 75
|
||||
26 1 77 76 78
|
||||
27 1 80 79 81
|
||||
28 1 83 82 84
|
||||
29 1 86 85 87
|
||||
30 1 89 88 90
|
||||
31 1 92 91 93
|
||||
32 1 95 94 96
|
|
@ -0,0 +1,28 @@
|
|||
units real
|
||||
neigh_modify delay 0 every 1 check yes
|
||||
atom_style full
|
||||
bond_style harmonic
|
||||
angle_style harmonic
|
||||
pair_style lj/cut/coul/long 10.0
|
||||
pair_modify mix arithmetic
|
||||
kspace_style pppm 1e-4
|
||||
special_bonds amber
|
||||
|
||||
#atom_modify sort 0.0 0
|
||||
|
||||
read_data data.water
|
||||
|
||||
timestep 1.0
|
||||
|
||||
dump 1 all custom 1 dump.lammpstrj id element xu yu zu
|
||||
dump_modify 1 element O H
|
||||
|
||||
thermo_style multi
|
||||
thermo 1
|
||||
|
||||
group wat id 25:27
|
||||
|
||||
fix 1 wat qmmm
|
||||
|
||||
fix 2 all nvt temp 300.0 300.0 70.0
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
LAMMPS data file for water
|
||||
|
||||
3 atoms
|
||||
2 bonds
|
||||
1 angles
|
||||
|
||||
2 atom types
|
||||
1 bond types
|
||||
1 angle types
|
||||
|
||||
0.0 9.865 xlo xhi
|
||||
0.0 9.865 ylo yhi
|
||||
0.0 9.865 zlo zhi
|
||||
|
||||
Masses
|
||||
|
||||
1 15.9994
|
||||
2 1.008
|
||||
|
||||
Pair Coeffs
|
||||
|
||||
1 0.102 3.188
|
||||
2 0.000 0.000
|
||||
|
||||
Bond Coeffs
|
||||
|
||||
1 450 0.9572
|
||||
|
||||
Angle Coeffs
|
||||
|
||||
1 55.0 104.52
|
||||
|
||||
Atoms
|
||||
|
||||
1 0 1 -0.8340 4.890520 4.325756 3.842052
|
||||
2 0 2 0.41700 3.893761 4.308535 3.950637
|
||||
3 0 2 0.41700 4.946166 4.514250 2.851741
|
||||
|
||||
Bonds
|
||||
|
||||
1 1 1 2
|
||||
2 1 1 3
|
||||
|
||||
Angles
|
||||
|
||||
1 1 2 1 3
|
|
@ -0,0 +1,20 @@
|
|||
units real
|
||||
neigh_modify delay 0 every 1 check yes
|
||||
atom_style full
|
||||
bond_style harmonic
|
||||
angle_style harmonic
|
||||
pair_style lj/cut/coul/long 10.0
|
||||
pair_modify mix arithmetic
|
||||
kspace_style pppm 1e-4
|
||||
special_bonds amber
|
||||
|
||||
#atom_modify sort 0.0 0
|
||||
|
||||
read_data data.single_water
|
||||
|
||||
timestep 1.0
|
||||
|
||||
thermo_style multi
|
||||
thermo 1
|
||||
|
||||
fix 1 all qmmm
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,38 @@
|
|||
&CONTROL
|
||||
title="QMMM"
|
||||
calculation='md',
|
||||
restart_mode = 'from_scratch',
|
||||
tprnfor=.t.,
|
||||
prefix='ms2',
|
||||
pseudo_dir='pseudo'
|
||||
nstep = 2000,
|
||||
tqmmm = .true.
|
||||
/
|
||||
|
||||
&SYSTEM
|
||||
ibrav = 1,
|
||||
celldm(1) = 18.642155649244,
|
||||
nat = 3,
|
||||
ntyp = 2,
|
||||
ecutwfc = 25.0 ,
|
||||
ecutrho = 250.0 ,
|
||||
/
|
||||
|
||||
&ELECTRONS
|
||||
conv_thr = 1.D-8,
|
||||
/
|
||||
|
||||
&IONS
|
||||
ion_positions = 'default'
|
||||
/
|
||||
|
||||
ATOMIC_SPECIES
|
||||
O 16.0000 O.pbe-van_bm.UPF
|
||||
H 1.0000 H.pbe-van_ak.UPF
|
||||
|
||||
ATOMIC_POSITIONS angstrom
|
||||
O 4.890520 4.325756 3.842052
|
||||
H 3.893761 4.308535 3.950637
|
||||
H 4.946166 4.514250 2.851741
|
||||
|
||||
K_POINTS gamma
|
|
@ -0,0 +1,24 @@
|
|||
# configuration file for QMMM wrapper
|
||||
|
||||
mode mech # coupling choices: o(ff), m(echanical), e(lectrostatic)
|
||||
#mode elec # coupling choices: o(ff), m(echanical), e(lectrostatic)
|
||||
handle qmmm # name of sysv shmem handle
|
||||
steps 20 # number of QM/MM (MD) steps
|
||||
verbose 1
|
||||
restart water.restart # checkpoint/restart file to write out at end
|
||||
|
||||
# QM system config
|
||||
qmdir qm-pw # directory to run QM system in
|
||||
qminp water.in # input file for QM code
|
||||
qmout NULL # output file for QM code (or NULL to print to screen)
|
||||
|
||||
# MM master config
|
||||
madir mm-master # directory to run MM master in
|
||||
mainp water.in # input file for MM master
|
||||
maout water.out # output file for MM master (or NULL to print to screen)
|
||||
|
||||
# MM slave config
|
||||
sldir mm-slave # directory to run MM slave in
|
||||
slinp water_single.in # input file for MM slave
|
||||
slout water_single.out # output file for MM slave (or NULL to print to screen)
|
||||
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
* This file is distributed under the terms of the
|
||||
* GNU General Public License. See the file `License'
|
||||
* in the root directory of the present distribution,
|
||||
* or http://www.gnu.org/copyleft/gpl.txt .
|
||||
*
|
||||
* generic QM/MM support library
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include "libqmmm.h"
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
/* global variable for global QM/MM configuration */
|
||||
qmmm_config_t qmmmcfg;
|
||||
|
||||
/* local helper function: advance char pointer beyond leading whitespace */
|
||||
static char *skip_whitespace(char *ptr)
|
||||
{
|
||||
while ((*ptr == ' ') || (*ptr == '\t')
|
||||
|| (*ptr == '\r') || (*ptr == '\n')) ++ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* local helper function: trim string to remove trailing whitespace */
|
||||
static void trim_whitespace(char *ptr)
|
||||
{
|
||||
while ((*ptr != ' ') && (*ptr != '\t')
|
||||
&& (*ptr != '\r') && (*ptr != '\n')) ++ptr;
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
|
||||
/* read and parse global QM/MM configuration file and
|
||||
store the result in a qmmm_config_t struct */
|
||||
int read_qmmm_config(const char *file, qmmm_config_t *cfg)
|
||||
{
|
||||
FILE *fp;
|
||||
char *ptr;
|
||||
int i, lineno, len;
|
||||
char buf[BUF_SIZE];
|
||||
|
||||
/* need to have config file and storage for config provided */
|
||||
if ((file == NULL) || (cfg == NULL))
|
||||
return QMMM_ERROR;
|
||||
|
||||
/* clear config */
|
||||
memset(cfg, 0, sizeof(qmmm_config_t));
|
||||
|
||||
fp = fopen(file,"r");
|
||||
if (fp == NULL) return QMMM_ERROR;
|
||||
|
||||
lineno = 0;
|
||||
while (fgets(buf,BUF_SIZE,fp)) {
|
||||
++lineno;
|
||||
|
||||
/* remove comments */
|
||||
ptr = strchr(buf,'#');
|
||||
if (ptr != NULL) *ptr = '\0';
|
||||
|
||||
/* skip over leading whitespace */
|
||||
ptr = skip_whitespace(buf);
|
||||
len = strlen(ptr);
|
||||
if (len == 0) continue;
|
||||
|
||||
/* convert keyword to lower case */
|
||||
for (i=0; i < len; ++i) {
|
||||
if ((ptr[i]=='\0') || (ptr[i]==' ') || (ptr[i]=='\t'))
|
||||
break;
|
||||
ptr[i] = tolower(ptr[i]);
|
||||
}
|
||||
|
||||
/* handle keywords */
|
||||
if (strncmp(ptr,"mode",4) == 0) {
|
||||
ptr = skip_whitespace(ptr+4);
|
||||
if ((*ptr=='m') || (*ptr=='M'))
|
||||
cfg->qmmm_mode = QMMM_MODE_MECH;
|
||||
else if ((*ptr=='e') || (*ptr=='E'))
|
||||
cfg->qmmm_mode = QMMM_MODE_ELEC;
|
||||
else if ((*ptr=='o') || (*ptr=='O'))
|
||||
cfg->qmmm_mode = QMMM_MODE_OFF;
|
||||
else cfg->qmmm_mode = QMMM_ERROR;
|
||||
|
||||
} else if (strncmp(ptr,"comm",4) == 0) {
|
||||
ptr = skip_whitespace(ptr+4);
|
||||
if ((*ptr=='m') || (*ptr=='M'))
|
||||
cfg->comm_mode = QMMM_COMM_MPI;
|
||||
else if ((*ptr=='s') || (*ptr=='S'))
|
||||
cfg->comm_mode = QMMM_COMM_SHM;
|
||||
else cfg->comm_mode = QMMM_ERROR;
|
||||
|
||||
} else if (strncmp(ptr,"steps",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
trim_whitespace(ptr);
|
||||
cfg->steps = atoi(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"verbose",7) == 0) {
|
||||
ptr = skip_whitespace(ptr+7);
|
||||
trim_whitespace(ptr);
|
||||
cfg->verbose = atoi(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"handle",6) == 0) {
|
||||
ptr = skip_whitespace(ptr+6);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->handle) free(cfg->handle);
|
||||
cfg->handle = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"restart",7) == 0) {
|
||||
ptr = skip_whitespace(ptr+7);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->restart) free(cfg->restart);
|
||||
cfg->restart = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"qmdir",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->qmdir) free(cfg->qmdir);
|
||||
cfg->qmdir = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"madir",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->madir) free(cfg->madir);
|
||||
cfg->madir = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"sldir",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->sldir) free(cfg->sldir);
|
||||
cfg->sldir = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"qminp",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->qminp) free(cfg->qminp);
|
||||
cfg->qminp = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"mainp",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->mainp) free(cfg->mainp);
|
||||
cfg->mainp = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"slinp",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->slinp) free(cfg->slinp);
|
||||
cfg->slinp = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"qmout",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->qmout) free(cfg->qmout);
|
||||
cfg->qmout = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"maout",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->maout) free(cfg->maout);
|
||||
cfg->maout = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"slout",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
trim_whitespace(ptr);
|
||||
if (cfg->slout) free(cfg->slout);
|
||||
cfg->slout = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"qmcmd",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
if (cfg->qmcmd) free(cfg->qmcmd);
|
||||
cfg->qmcmd = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"macmd",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
if (cfg->macmd) free(cfg->macmd);
|
||||
cfg->macmd = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"slcmd",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
if (cfg->slcmd) free(cfg->slcmd);
|
||||
cfg->slcmd = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"qmarg",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
if (cfg->qmarg) free(cfg->qmarg);
|
||||
cfg->qmarg = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"maarg",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
if (cfg->maarg) free(cfg->maarg);
|
||||
cfg->maarg = strdup(ptr);
|
||||
|
||||
} else if (strncmp(ptr,"slarg",5) == 0) {
|
||||
ptr = skip_whitespace(ptr+5);
|
||||
if (cfg->slarg) free(cfg->slarg);
|
||||
cfg->slarg = strdup(ptr);
|
||||
|
||||
} else {
|
||||
fprintf(stderr,"\nParse error in line %d of file %s\n>>%s<<\n\n",
|
||||
lineno, file, buf);
|
||||
return QMMM_ERROR;
|
||||
}
|
||||
|
||||
if (feof(fp)) break;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return QMMM_OK;
|
||||
}
|
||||
|
||||
|
||||
/* perform consistency checks on a qmmm_config_t struct */
|
||||
const char *check_qmmm_config(qmmm_config_t *cfg) {
|
||||
const char *msg = NULL;
|
||||
|
||||
if (cfg->qmmm_mode == QMMM_MODE_NONE) {
|
||||
msg = "QM/MM coupling mode not set";
|
||||
} else if (cfg->steps < 1) {
|
||||
msg = "Number of QM/MM steps must be > 0";
|
||||
} else if (cfg->qmdir == NULL) {
|
||||
msg = "QM directory not set";
|
||||
} else if (cfg->madir == NULL) {
|
||||
msg = "MM master directory not set";
|
||||
} else if (cfg->sldir == NULL) {
|
||||
msg = "MM slave directory not set";
|
||||
} else if (cfg->qminp == NULL) {
|
||||
msg = "QM input file not set";
|
||||
} else if (cfg->mainp == NULL) {
|
||||
msg = "MM master input file not set";
|
||||
} else if (cfg->slinp == NULL) {
|
||||
msg = "MM slave input file not set";
|
||||
} else if (cfg->qmout == NULL) {
|
||||
msg = "QM output file not set";
|
||||
} else if (cfg->maout == NULL) {
|
||||
msg = "MM master output file not set";
|
||||
} else if (cfg->slout == NULL) {
|
||||
msg = "MM slave output file not set";
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
/* take the existing global QM/MM configuration and write it to a file */
|
||||
int write_qmmm_config(const char *file, qmmm_config_t *cfg)
|
||||
{
|
||||
FILE *fp;
|
||||
time_t now;
|
||||
|
||||
if (cfg == NULL)
|
||||
return QMMM_ERROR;
|
||||
|
||||
if (file == NULL)
|
||||
fp = stderr;
|
||||
else {
|
||||
fp = fopen(file,"w");
|
||||
if (fp == NULL) return QMMM_ERROR;
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
fprintf(fp,"# QM/MM global configuration. %s\n",ctime(&now));
|
||||
fprintf(fp,"# comm_mode: %d\n", cfg->comm_mode);
|
||||
if (cfg->qmmm_mode == QMMM_MODE_OFF) {
|
||||
fputs("mode off\n",fp);
|
||||
} else if (cfg->qmmm_mode == QMMM_MODE_NONE) {
|
||||
fputs("mode none\n",fp);
|
||||
} else if (cfg->qmmm_mode == QMMM_MODE_MECH) {
|
||||
fputs("mode mechanical\n",fp);
|
||||
} else if (cfg->qmmm_mode == QMMM_MODE_ELEC) {
|
||||
fputs("mode electrostatic\n",fp);
|
||||
} else fputs("mode unknown\n",fp);
|
||||
|
||||
if (cfg->restart) fprintf(fp,"restart %s\n",cfg->restart);
|
||||
if (cfg->handle) fprintf(fp,"handle %s\n", cfg->handle);
|
||||
fprintf(fp,"steps %d\n",cfg->steps);
|
||||
fprintf(fp,"verbose %d\n",cfg->verbose);
|
||||
|
||||
fputs("\n# QM system configuration:\n",fp);
|
||||
if (cfg->qmdir) fprintf(fp,"qmdir %s\n", cfg->qmdir);
|
||||
else fputs("qmdir (required input not set)\n",fp);
|
||||
|
||||
if (cfg->qminp) fprintf(fp,"qminp %s\n", cfg->qminp);
|
||||
else fputs("qminp (required input not set)\n",fp);
|
||||
|
||||
if (cfg->qmout) fprintf(fp,"qmout %s\n", cfg->qmout);
|
||||
else fputs("qmout NULL\n",fp);
|
||||
|
||||
if (cfg->qmcmd) fprintf(fp,"qmcmd %s\n", cfg->qmcmd);
|
||||
if (cfg->qmarg) fprintf(fp,"qmarg %s\n", cfg->qmarg);
|
||||
|
||||
fputs("\n# MM master system configuration:\n",fp);
|
||||
if (cfg->madir) fprintf(fp,"madir %s\n", cfg->madir);
|
||||
else fputs("madir (required input not set)\n",fp);
|
||||
|
||||
if (cfg->mainp) fprintf(fp,"mainp %s\n", cfg->mainp);
|
||||
else fputs("mainp (required input not set)\n",fp);
|
||||
|
||||
if (cfg->maout) fprintf(fp,"maout %s\n", cfg->maout);
|
||||
else fputs("maout NULL\n",fp);
|
||||
|
||||
if (cfg->macmd) fprintf(fp,"macmd %s\n", cfg->macmd);
|
||||
if (cfg->maarg) fprintf(fp,"maarg %s\n", cfg->maarg);
|
||||
|
||||
fputs("\n# MM slave system configuration:\n",fp);
|
||||
if (cfg->sldir) fprintf(fp,"sldir %s\n", cfg->sldir);
|
||||
else fputs("sldir (required input not set)\n",fp);
|
||||
|
||||
if (cfg->slinp) fprintf(fp,"slinp %s\n", cfg->slinp);
|
||||
else fputs("slinp (required input not set)\n",fp);
|
||||
|
||||
if (cfg->slout) fprintf(fp,"slout %s\n", cfg->slout);
|
||||
else fputs("slout NULL\n",fp);
|
||||
|
||||
if (cfg->slcmd) fprintf(fp,"slcmd %s\n", cfg->slcmd);
|
||||
if (cfg->slarg) fprintf(fp,"slarg %s\n", cfg->slarg);
|
||||
|
||||
if (file != NULL) fclose(fp);
|
||||
return QMMM_OK;
|
||||
}
|
||||
|
||||
/* free storage associated with qmmm_config_t struct */
|
||||
void free_qmmm_config(qmmm_config_t *cfg) {
|
||||
|
||||
if (cfg->qmdir != NULL) free(cfg->qmdir);
|
||||
if (cfg->madir != NULL) free(cfg->madir);
|
||||
if (cfg->sldir != NULL) free(cfg->sldir);
|
||||
|
||||
if (cfg->qminp != NULL) free(cfg->qminp);
|
||||
if (cfg->mainp != NULL) free(cfg->mainp);
|
||||
if (cfg->slinp != NULL) free(cfg->slinp);
|
||||
|
||||
if (cfg->qmout != NULL) free(cfg->qmout);
|
||||
if (cfg->maout != NULL) free(cfg->maout);
|
||||
if (cfg->slout != NULL) free(cfg->slout);
|
||||
|
||||
if (cfg->qmcmd != NULL) free(cfg->qmcmd);
|
||||
if (cfg->macmd != NULL) free(cfg->macmd);
|
||||
if (cfg->slcmd != NULL) free(cfg->slcmd);
|
||||
|
||||
if (cfg->qmarg != NULL) free(cfg->qmarg);
|
||||
if (cfg->maarg != NULL) free(cfg->maarg);
|
||||
if (cfg->slarg != NULL) free(cfg->slarg);
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* This file is distributed under the terms of the
|
||||
* GNU General Public License. See the file `License'
|
||||
* in the root directory of the present distribution,
|
||||
* or http://www.gnu.org/copyleft/gpl.txt .
|
||||
*
|
||||
* common definitions, APIs and global data for QM/MM interface
|
||||
*/
|
||||
|
||||
#ifndef QE_LIBQMMM_H
|
||||
#define QE_LIBQMMM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* transport method for data exchange between QM and MM codes */
|
||||
#define QMMM_COMM_NONE 0
|
||||
#define QMMM_COMM_MPI 1
|
||||
#define QMMM_COMM_SHM 2
|
||||
|
||||
/* type or "level" of QM/MM coupling */
|
||||
#define QMMM_MODE_OFF -1
|
||||
#define QMMM_MODE_NONE 0
|
||||
#define QMMM_MODE_MECH 1
|
||||
#define QMMM_MODE_ELEC 2
|
||||
|
||||
/* flag indicating the role of this process in a QM/MM calculation */
|
||||
#define QMMM_ROLE_QM 1
|
||||
#define QMMM_ROLE_MASTER 2
|
||||
#define QMMM_ROLE_SLAVE 3
|
||||
|
||||
#define QMMM_OK 0
|
||||
#define QMMM_ERROR -1
|
||||
|
||||
/* container struct for global QM/MM configuration information */
|
||||
typedef struct {
|
||||
int comm_mode, qmmm_mode; /* communication and coupling mode */
|
||||
char *qmdir, *madir, *sldir; /* directories to run codes in */
|
||||
char *qminp, *mainp, *slinp; /* input files for codes */
|
||||
char *qmout, *maout, *slout; /* stdout files for codes */
|
||||
char *qmcmd, *macmd, *slcmd; /* command to run codes (SHMEM only) */
|
||||
char *qmarg, *maarg, *slarg; /* extra flags to pass to code */
|
||||
int verbose; /* verbosity level */
|
||||
int role; /* role of this rank */
|
||||
int steps; /* number of MD steps */
|
||||
int nmm; /* tasks reserved for MD (master and slave) */
|
||||
char *restart; /* name of (MM) restart file */
|
||||
char *handle; /* handle for SHEMEM communication */
|
||||
int my_comm, qm_comm, mm_comm; /* MPI communicators, Fortran-style */
|
||||
} qmmm_config_t;
|
||||
|
||||
/* declare a global variable for the QM/MM setup.
|
||||
thus there can be only one QM/MM coupling currently */
|
||||
extern qmmm_config_t qmmmcfg;
|
||||
|
||||
/* read and parse global QM/MM configuration file and
|
||||
* store the result in a qmmm_config_t struct */
|
||||
int read_qmmm_config(const char *, qmmm_config_t *);
|
||||
|
||||
/* write out the global QM/MM configuration file in
|
||||
* the same format as the read function can parse */
|
||||
int write_qmmm_config(const char *, qmmm_config_t *);
|
||||
|
||||
/* perform consistency checks on a qmmm_config_t struct */
|
||||
const char *check_qmmm_config(qmmm_config_t *);
|
||||
|
||||
/* free storage associated with qmmm_config_t struct */
|
||||
void free_qmmm_config(qmmm_config_t *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* QE_LIBQMMM_H */
|
|
@ -0,0 +1,365 @@
|
|||
/* Copyright (C) 2013 Quantum ESPRESSO group
|
||||
* This file is distributed under the terms of the
|
||||
* GNU General Public License. See the file `License'
|
||||
* in the root directory of the present distribution,
|
||||
* or http://www.gnu.org/copyleft/gpl.txt . */
|
||||
|
||||
/* Toplevel wrapper code to launch QM/MM calculations via MPI */
|
||||
|
||||
#include <mpi.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libqecouple.h"
|
||||
#include "libqmmm.h"
|
||||
|
||||
#include "library.h"
|
||||
|
||||
static const char delim[] = " \t\n\r";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MPI_Comm intra_comm, qm_comm, mm_comm;
|
||||
int me, ncpu, nqm, key, retval;
|
||||
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm_size(MPI_COMM_WORLD,&ncpu);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD,&me);
|
||||
|
||||
/* we accept just the qm/mm file as the one argument */
|
||||
if ((argc < 2) || (argc > 3)) {
|
||||
if (me == 0) fprintf(stderr,"\n usage: %s <qmmm input file> "
|
||||
"[<number of mm procs>]\n\n",argv[0]);
|
||||
MPI_Finalize();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* parse the qm/mm file */
|
||||
if (read_qmmm_config(argv[1],&qmmmcfg)) {
|
||||
if (me == 0) fputs("\n Error parsing QM/MM config file\n\n",stderr);
|
||||
MPI_Finalize();
|
||||
return -2;
|
||||
}
|
||||
|
||||
key = 2;
|
||||
if (argc == 3) {
|
||||
key = atoi(argv[2]);
|
||||
}
|
||||
qmmmcfg.nmm = key;
|
||||
|
||||
/* sanity checks */
|
||||
qmmmcfg.comm_mode = QMMM_COMM_MPI;
|
||||
nqm = ncpu - qmmmcfg.nmm;
|
||||
retval = 0;
|
||||
|
||||
if (me == 0) {
|
||||
const char *msg;
|
||||
|
||||
msg = check_qmmm_config(&qmmmcfg);
|
||||
|
||||
if ((nqm < 1) || (qmmmcfg.nmm < 2)) {
|
||||
msg = "Need at least 2 MM and 1 QM processes";
|
||||
}
|
||||
if (msg != NULL) {
|
||||
retval = 1;
|
||||
fprintf(stderr,"\n%s\n\n",msg);
|
||||
}
|
||||
}
|
||||
MPI_Bcast(&retval,1,MPI_INT,0,MPI_COMM_WORLD);
|
||||
if (retval != 0) {
|
||||
MPI_Finalize();
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (me == 0) {
|
||||
write_qmmm_config(NULL,&qmmmcfg);
|
||||
|
||||
printf("\nRunning QM/MM calculation for %d steps on %d procs\n\n",
|
||||
qmmmcfg.steps, ncpu);
|
||||
printf("QM system: procs: % 4d | directory: %-16s | input: %-16s|\n",
|
||||
nqm,qmmmcfg.qmdir,qmmmcfg.qminp);
|
||||
printf("MM master: procs: % 4d | directory: %-16s | input: %-16s|\n",
|
||||
qmmmcfg.nmm-1,qmmmcfg.madir,qmmmcfg.mainp);
|
||||
printf("MM slave: procs: % 4d | directory: %-16s | input: %-16s|\n\n",
|
||||
1,qmmmcfg.sldir,qmmmcfg.slinp);
|
||||
}
|
||||
|
||||
/* set up MPI communication */
|
||||
|
||||
/* process partitioning: QM | MM master | MM slave */
|
||||
qmmmcfg.role = QMMM_ROLE_QM;
|
||||
if (me >= nqm) qmmmcfg.role = QMMM_ROLE_MASTER;
|
||||
if (me == (ncpu-1)) qmmmcfg.role = QMMM_ROLE_SLAVE;
|
||||
|
||||
MPI_Comm_split(MPI_COMM_WORLD, qmmmcfg.role, me, &intra_comm);
|
||||
qmmmcfg.my_comm = MPI_Comm_c2f(intra_comm);
|
||||
|
||||
/* qm to mm-master inter communicator */
|
||||
key = MPI_UNDEFINED;
|
||||
if ((me == 0) || (me == nqm)) key = 1;
|
||||
|
||||
MPI_Comm_split(MPI_COMM_WORLD, key, ncpu-me, &qm_comm);
|
||||
qmmmcfg.qm_comm = MPI_Comm_c2f(qm_comm);
|
||||
|
||||
/* mm-slave to mm-master inter communicator */
|
||||
key = MPI_UNDEFINED;
|
||||
if ((me == (ncpu-1)) || (me == nqm)) key = 1;
|
||||
|
||||
MPI_Comm_split(MPI_COMM_WORLD, key, me, &mm_comm);
|
||||
qmmmcfg.mm_comm = MPI_Comm_c2f(mm_comm);
|
||||
|
||||
if (qmmmcfg.role == QMMM_ROLE_QM) {
|
||||
FILE *fp;
|
||||
int nimage,npots,npool,ntg,nband,ndiag;
|
||||
|
||||
MPI_Comm_rank(intra_comm,&me);
|
||||
|
||||
if (chdir(qmmmcfg.qmdir)) {
|
||||
if (me == 0) fputs("failure to change into QM directory\n",stderr);
|
||||
MPI_Abort(MPI_COMM_WORLD, 10);
|
||||
}
|
||||
|
||||
/* check if input file is available and readable */
|
||||
fp = fopen(qmmmcfg.qminp,"r");
|
||||
if (fp == NULL) {
|
||||
if (me == 0) fprintf(stderr,"failure to open QM input for "
|
||||
"reading: %s\n", strerror(errno));
|
||||
MPI_Abort(MPI_COMM_WORLD, 20);
|
||||
} else fclose(fp);
|
||||
|
||||
/* redirect output to file, if requested */
|
||||
if (strcmp(qmmmcfg.qmout,"NULL") != 0) {
|
||||
fp = freopen(qmmmcfg.qmout,"w",stdout);
|
||||
if (fp == NULL) {
|
||||
if (me == 0) fprintf(stderr,"failure to open QM output for "
|
||||
"writing: %s\n", strerror(errno));
|
||||
MPI_Abort(MPI_COMM_WORLD, 30);
|
||||
}
|
||||
}
|
||||
|
||||
/* parse additional command line flags for pw.x */
|
||||
nimage=npots=npool=ntg=nband=ndiag=1;
|
||||
|
||||
if (qmmmcfg.qmarg != NULL) {
|
||||
char *ptr = strtok(qmmmcfg.qmarg,delim);
|
||||
do {
|
||||
/* -nimage is not supported */
|
||||
if (strncmp("-npot",ptr,5) == 0) {
|
||||
ptr=strtok(NULL,delim);
|
||||
npots=atoi(ptr);
|
||||
} else if ((strncmp("-nk",ptr,3) == 0)
|
||||
|| (strncmp("-npoo",ptr,5) == 0)) {
|
||||
ptr=strtok(NULL,delim);
|
||||
npool=atoi(ptr);
|
||||
} else if (strncmp("-nt",ptr,3) == 0) {
|
||||
ptr=strtok(NULL,delim);
|
||||
ntg=atoi(ptr);
|
||||
} else if (strncmp("-nb",ptr,3) == 0) {
|
||||
ptr=strtok(NULL,delim);
|
||||
nband=atoi(ptr);
|
||||
} else if ((strncmp("-nd",ptr,3) == 0)
|
||||
|| (strncmp("-no",ptr,3) == 0)
|
||||
|| (strcmp("-nproc_diag",ptr) == 0)
|
||||
|| (strcmp("-nproc_ortho",ptr) == 0)) {
|
||||
ptr=strtok(NULL,delim);
|
||||
ndiag=atoi(ptr);
|
||||
} else {
|
||||
if (me == 0) {
|
||||
fprintf(stderr,"QM: ignoring flag '%s", ptr);
|
||||
ptr=strtok(NULL,delim);
|
||||
fprintf(stderr," %s'\n",ptr);
|
||||
} else strtok(NULL,delim);
|
||||
}
|
||||
} while ((ptr=strtok(NULL,delim)));
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if (me == 0) fprintf(stderr,"QM: nimage: %d npots: %d npools: %d "
|
||||
"ntg: %d nband: %d ndiag: %d\n",
|
||||
nimage,npots,npool,ntg,nband,ndiag);
|
||||
|
||||
/* setup and call Q-E. */
|
||||
c2qmmm_mpi_config(qmmmcfg.qmmm_mode, qmmmcfg.qm_comm,
|
||||
qmmmcfg.verbose, qmmmcfg.steps);
|
||||
c2libpwscf(qmmmcfg.my_comm, nimage, npots, npool, ntg, nband, ndiag,
|
||||
&retval, qmmmcfg.qminp);
|
||||
|
||||
if (strcmp(qmmmcfg.qmout,"NULL") != 0)
|
||||
fclose(fp);
|
||||
|
||||
} else if (qmmmcfg.role == QMMM_ROLE_MASTER) {
|
||||
FILE *fp;
|
||||
char *cuda, *echo, *suffix;
|
||||
void *lmp;
|
||||
|
||||
MPI_Comm_rank(intra_comm,&me);
|
||||
|
||||
if (chdir(qmmmcfg.madir)) {
|
||||
if (me == 0)
|
||||
fputs("failure to change into MM master directory\n",stderr);
|
||||
MPI_Abort(MPI_COMM_WORLD, 10);
|
||||
}
|
||||
|
||||
/* check if input file is available and readable */
|
||||
fp = fopen(qmmmcfg.mainp,"r");
|
||||
if (fp == NULL) {
|
||||
if (me == 0) fprintf(stderr,"failure to open MM master input "
|
||||
"for reading: %s\n", strerror(errno));
|
||||
MPI_Abort(MPI_COMM_WORLD, 20);
|
||||
} else fclose(fp);
|
||||
|
||||
/* redirect output to file, if requested */
|
||||
if (strcmp(qmmmcfg.maout,"NULL") != 0) {
|
||||
fp = freopen(qmmmcfg.maout,"w",stdout);
|
||||
if (fp == NULL) {
|
||||
if (me == 0) fprintf(stderr,"failure to open MM master output "
|
||||
"for writing: %s\n", strerror(errno));
|
||||
MPI_Abort(MPI_COMM_WORLD, 30);
|
||||
}
|
||||
}
|
||||
|
||||
/* parse additional support command line flags for LAMMPS */
|
||||
|
||||
if (qmmmcfg.maarg != NULL) {
|
||||
char *ptr = strtok(qmmmcfg.maarg,delim);
|
||||
do {
|
||||
if ((strncmp("-c",ptr,2) == 0)
|
||||
|| (strncmp("-cuda",ptr,5) == 0)) {
|
||||
ptr=strtok(NULL,delim);
|
||||
cuda=strdup(ptr);
|
||||
} else if ((strncmp("-e",ptr,2) == 0)
|
||||
|| (strncmp("-echo",ptr,5) == 0)) {
|
||||
ptr=strtok(NULL,delim);
|
||||
echo=strdup(ptr);
|
||||
} else if ((strncmp("-sf",ptr,3) == 0)
|
||||
|| (strncmp("-suffix",ptr,7) == 0)) {
|
||||
ptr=strtok(NULL,delim);
|
||||
suffix=strdup(ptr);
|
||||
} else {
|
||||
if (me == 0)
|
||||
fprintf(stderr,"unsupported LAMMPS flag: %s\n",ptr);
|
||||
MPI_Abort(MPI_COMM_WORLD, 40);
|
||||
}
|
||||
} while ((ptr=strtok(NULL,delim)));
|
||||
}
|
||||
char *lmpargs[5];
|
||||
lmpargs[0] = strdup("MM Master");
|
||||
lmpargs[1] = strdup("-log");
|
||||
lmpargs[2] = strdup("none");
|
||||
lmpargs[3] = strdup("-echo");
|
||||
lmpargs[4] = strdup("screen");
|
||||
|
||||
lammps_open(5, lmpargs, intra_comm, &lmp);
|
||||
lammps_file(lmp,qmmmcfg.mainp);
|
||||
|
||||
char runcmd[1024];
|
||||
sprintf(runcmd,"run %d\n",qmmmcfg.steps);
|
||||
lammps_command(lmp,runcmd);
|
||||
if (qmmmcfg.restart != NULL) {
|
||||
sprintf(runcmd,"write_restart %s\n",qmmmcfg.restart);
|
||||
lammps_command(lmp,runcmd);
|
||||
}
|
||||
lammps_close(lmp);
|
||||
|
||||
fputs("MM: master done\n",stderr);
|
||||
if (strcmp(qmmmcfg.maout,"NULL") != 0)
|
||||
fclose(fp);
|
||||
|
||||
retval = 0;
|
||||
|
||||
} else if (qmmmcfg.role == QMMM_ROLE_SLAVE) {
|
||||
FILE *fp;
|
||||
char *cuda, *echo, *suffix;
|
||||
void *lmp;
|
||||
|
||||
MPI_Comm_rank(intra_comm,&me);
|
||||
|
||||
if (chdir(qmmmcfg.sldir)) {
|
||||
if (me == 0)
|
||||
fputs("failure to change into MM slave directory\n",stderr);
|
||||
MPI_Abort(MPI_COMM_WORLD, 10);
|
||||
}
|
||||
|
||||
/* check if input file is available and readable */
|
||||
fp = fopen(qmmmcfg.slinp,"r");
|
||||
if (fp == NULL) {
|
||||
if (me == 0) fprintf(stderr,"failure to open MM slave input "
|
||||
"for reading: %s\n", strerror(errno));
|
||||
MPI_Abort(MPI_COMM_WORLD, 20);
|
||||
} else fclose(fp);
|
||||
|
||||
/* redirect output to file, if requested */
|
||||
if (strcmp(qmmmcfg.slout,"NULL") != 0) {
|
||||
fp = freopen(qmmmcfg.slout,"w",stdout);
|
||||
if (fp == NULL) {
|
||||
if (me == 0) fprintf(stderr,"failure to open MM slave output "
|
||||
"for writing: %s\n", strerror(errno));
|
||||
MPI_Abort(MPI_COMM_WORLD, 30);
|
||||
}
|
||||
}
|
||||
|
||||
/* parse additional support command line flags for LAMMPS */
|
||||
|
||||
if (qmmmcfg.slarg != NULL) {
|
||||
char *ptr = strtok(qmmmcfg.maarg,delim);
|
||||
do {
|
||||
if ((strncmp("-c",ptr,2) == 0)
|
||||
|| (strncmp("-cuda",ptr,5) == 0)) {
|
||||
ptr=strtok(NULL,delim);
|
||||
cuda=strdup(ptr);
|
||||
} else if ((strncmp("-e",ptr,2) == 0)
|
||||
|| (strncmp("-echo",ptr,5) == 0)) {
|
||||
ptr=strtok(NULL,delim);
|
||||
echo=strdup(ptr);
|
||||
} else if ((strncmp("-sf",ptr,3) == 0)
|
||||
|| (strncmp("-suffix",ptr,7) == 0)) {
|
||||
ptr=strtok(NULL,delim);
|
||||
suffix=strdup(ptr);
|
||||
} else {
|
||||
if (me == 0)
|
||||
fprintf(stderr,"unsupported LAMMPS flag: %s\n",ptr);
|
||||
MPI_Abort(MPI_COMM_WORLD, 40);
|
||||
}
|
||||
} while ((ptr=strtok(NULL,delim)));
|
||||
}
|
||||
|
||||
char *lmpargs[5];
|
||||
lmpargs[0] = strdup("MM slave");
|
||||
lmpargs[1] = strdup("-log");
|
||||
lmpargs[2] = strdup("none");
|
||||
lmpargs[3] = strdup("-echo");
|
||||
lmpargs[4] = strdup("screen");
|
||||
|
||||
lammps_open(5, lmpargs, intra_comm, &lmp);
|
||||
lammps_file(lmp,qmmmcfg.slinp);
|
||||
|
||||
char runcmd[64];
|
||||
sprintf(runcmd,"run %d\n",qmmmcfg.steps);
|
||||
lammps_command(lmp,runcmd);
|
||||
lammps_close(lmp);
|
||||
|
||||
fputs("MM: slave done\n",stderr);
|
||||
if (strcmp(qmmmcfg.slout,"NULL") != 0)
|
||||
fclose(fp);
|
||||
retval = 0;
|
||||
|
||||
} else {
|
||||
fputs("\n how on earth did you end up here?\n\n",stderr);
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD,&me);
|
||||
|
||||
if (me == 0) fputs("\nQM/MM run complete.\n",stderr);
|
||||
MPI_Finalize();
|
||||
free_qmmm_config(&qmmmcfg);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
Loading…
Reference in New Issue