3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * GROwing Monsters And Cloning Shrimps
63 #include "gmx_fatal.h"
66 #include "mtop_util.h"
69 /* declarations of the interfaces to the QM packages. The _SH indicate
70 * the QM interfaces can be used for Surface Hopping simulations
72 #ifdef GMX_QMMM_GAMESS
73 /* GAMESS interface */
76 init_gamess(t_commrec
*cr
, t_QMrec
*qm
, t_MMrec
*mm
);
79 call_gamess(t_commrec
*cr
,t_forcerec
*fr
,
80 t_QMrec
*qm
, t_MMrec
*mm
,rvec f
[], rvec fshift
[]);
82 #elif defined GMX_QMMM_MOPAC
86 init_mopac(t_commrec
*cr
, t_QMrec
*qm
, t_MMrec
*mm
);
89 call_mopac(t_commrec
*cr
,t_forcerec
*fr
, t_QMrec
*qm
,
90 t_MMrec
*mm
,rvec f
[], rvec fshift
[]);
93 call_mopac_SH(t_commrec
*cr
,t_forcerec
*fr
,t_QMrec
*qm
,
94 t_MMrec
*mm
,rvec f
[], rvec fshift
[]);
96 #elif defined GMX_QMMM_GAUSSIAN
97 /* GAUSSIAN interface */
100 init_gaussian(t_commrec
*cr
,t_QMrec
*qm
, t_MMrec
*mm
);
103 call_gaussian_SH(t_commrec
*cr
,t_forcerec
*fr
,t_QMrec
*qm
,
104 t_MMrec
*mm
,rvec f
[], rvec fshift
[]);
107 call_gaussian(t_commrec
*cr
,t_forcerec
*fr
, t_QMrec
*qm
,
108 t_MMrec
*mm
,rvec f
[], rvec fshift
[]);
115 /* this struct and these comparison functions are needed for creating
116 * a QMMM input for the QM routines from the QMMM neighbor list.
124 static int struct_comp(const void *a
, const void *b
){
126 return (int)(((t_j_particle
*)a
)->j
)-(int)(((t_j_particle
*)b
)->j
);
130 static int int_comp(const void *a
,const void *b
){
132 return (*(int *)a
) - (*(int *)b
);
136 static int QMlayer_comp(const void *a
, const void *b
){
138 return (int)(((t_QMrec
*)a
)->nrQMatoms
)-(int)(((t_QMrec
*)b
)->nrQMatoms
);
142 void sort_QMlayers(t_QMMMrec
*qr
){
143 /* sorts QM layers from small to big */
144 qsort(qr
->qm
,qr
->nrQMlayers
,
145 (size_t)sizeof(qr
->qm
[0]),
147 } /* sort_QMlayers */
150 real
call_QMroutine(t_commrec
*cr
, t_forcerec
*fr
, t_QMrec
*qm
,
151 t_MMrec
*mm
, rvec f
[], rvec fshift
[])
153 /* makes a call to the requested QM routine (qm->QMmethod)
154 * Note that f is actually the gradient, i.e. -f
159 /* do a semi-empiprical calculation */
161 if (qm
->QMmethod
<eQMmethodRHF
&& !(mm
->nrMMatoms
))
163 #ifdef GMX_QMMM_MOPAC
165 QMener
= call_mopac_SH(cr
,fr
,qm
,mm
,f
,fshift
);
167 QMener
= call_mopac(cr
,fr
,qm
,mm
,f
,fshift
);
169 gmx_fatal(FARGS
,"Semi-empirical QM only supported with Mopac.");
174 /* do an ab-initio calculation */
177 #ifdef GMX_QMMM_GAUSSIAN
178 QMener
= call_gaussian_SH(cr
,fr
,qm
,mm
,f
,fshift
);
180 gmx_fatal(FARGS
,"Ab-initio Surface-hopping only supported with Gaussian.");
185 #ifdef GMX_QMMM_GAMESS
186 QMener
= call_gamess(cr
,fr
,qm
,mm
,f
,fshift
);
187 #elif defined GMX_QMMM_GAUSSIAN
188 QMener
= call_gaussian(cr
,fr
,qm
,mm
,f
,fshift
);
190 gmx_fatal(FARGS
,"Ab-initio calculation only supported with Gamess or Gaussian.");
197 void init_QMroutine(t_commrec
*cr
, t_QMrec
*qm
, t_MMrec
*mm
)
199 /* makes a call to the requested QM routine (qm->QMmethod)
201 if (qm
->QMmethod
<eQMmethodRHF
){
202 #ifdef GMX_QMMM_MOPAC
203 /* do a semi-empiprical calculation */
204 init_mopac(cr
,qm
,mm
);
206 gmx_fatal(FARGS
,"Semi-empirical QM only supported with Mopac.");
211 /* do an ab-initio calculation */
212 #ifdef GMX_QMMM_GAMESS
213 init_gamess(cr
,qm
,mm
);
214 #elif defined GMX_QMMM_GAUSSIAN
215 init_gaussian(cr
,qm
,mm
);
217 gmx_fatal(FARGS
,"Ab-initio calculation only supported with Gamess or Gaussian.");
220 } /* init_QMroutine */
222 void update_QMMM_coord(rvec x
[],t_forcerec
*fr
, t_QMrec
*qm
, t_MMrec
*mm
)
224 /* shifts the QM and MM particles into the central box and stores
225 * these shifted coordinates in the coordinate arrays of the
226 * QMMMrec. These coordinates are passed on the QM subroutines.
231 /* shift the QM atoms into the central box
233 for(i
=0;i
<qm
->nrQMatoms
;i
++){
234 rvec_sub(x
[qm
->indexQM
[i
]],fr
->shift_vec
[qm
->shiftQM
[i
]],qm
->xQM
[i
]);
236 /* also shift the MM atoms into the central box, if any
238 for(i
=0;i
<mm
->nrMMatoms
;i
++){
239 rvec_sub(x
[mm
->indexMM
[i
]],fr
->shift_vec
[mm
->shiftMM
[i
]],mm
->xMM
[i
]);
241 } /* update_QMMM_coord */
243 static void punch_QMMM_excl(t_QMrec
*qm
,t_MMrec
*mm
,t_blocka
*excls
)
245 /* punch a file containing the bonded interactions of each QM
246 * atom with MM atoms. These need to be excluded in the QM routines
247 * Only needed in case of QM/MM optimizations
252 i
,j
,k
,nrexcl
=0,*excluded
=NULL
,max
=0;
255 out
= fopen("QMMMexcl.dat","w");
257 /* this can be done more efficiently I think
259 for(i
=0;i
<qm
->nrQMatoms
;i
++){
261 for(j
=excls
->index
[qm
->indexQM
[i
]];
262 j
<excls
->index
[qm
->indexQM
[i
]+1];
264 for(k
=0;k
<mm
->nrMMatoms
;k
++){
265 if(mm
->indexMM
[k
]==excls
->a
[j
]){/* the excluded MM atom */
268 srenew(excluded
,max
);
270 excluded
[nrexcl
++]=k
;
276 fprintf(out
,"%5d %5d\n",i
+1,nrexcl
);
277 for(j
=0;j
<nrexcl
;j
++){
278 fprintf(out
,"%5d ",excluded
[j
]);
284 } /* punch_QMMM_excl */
287 /* end of QMMM subroutines */
289 /* QMMM core routines */
291 t_QMrec
*mk_QMrec(void){
297 t_MMrec
*mk_MMrec(void){
303 static void init_QMrec(int grpnr
, t_QMrec
*qm
,int nr
, int *atomarray
,
304 gmx_mtop_t
*mtop
, t_inputrec
*ir
)
306 /* fills the t_QMrec struct of QM group grpnr
314 snew(qm
->indexQM
,nr
);
315 snew(qm
->shiftQM
,nr
); /* the shifts */
317 qm
->indexQM
[i
]=atomarray
[i
];
320 snew(qm
->atomicnumberQM
,nr
);
321 for (i
=0;i
<qm
->nrQMatoms
;i
++){
322 gmx_mtop_atomnr_to_atom(mtop
,qm
->indexQM
[i
],&atom
);
323 qm
->nelectrons
+= mtop
->atomtypes
.atomnumber
[atom
->type
];
324 qm
->atomicnumberQM
[i
] = mtop
->atomtypes
.atomnumber
[atom
->type
];
326 qm
->QMcharge
= ir
->opts
.QMcharge
[grpnr
];
327 qm
->multiplicity
= ir
->opts
.QMmult
[grpnr
];
328 qm
->nelectrons
-= ir
->opts
.QMcharge
[grpnr
];
330 qm
->QMmethod
= ir
->opts
.QMmethod
[grpnr
];
331 qm
->QMbasis
= ir
->opts
.QMbasis
[grpnr
];
332 /* trajectory surface hopping setup (Gaussian only) */
333 qm
->bSH
= ir
->opts
.bSH
[grpnr
];
334 qm
->CASorbitals
= ir
->opts
.CASorbitals
[grpnr
];
335 qm
->CASelectrons
= ir
->opts
.CASelectrons
[grpnr
];
336 qm
->SAsteps
= ir
->opts
.SAsteps
[grpnr
];
337 qm
->SAon
= ir
->opts
.SAon
[grpnr
];
338 qm
->SAoff
= ir
->opts
.SAoff
[grpnr
];
339 /* hack to prevent gaussian from reinitializing all the time */
340 qm
->nQMcpus
= 0; /* number of CPU's to be used by g01, is set
341 * upon initializing gaussian
344 /* print the current layer to allow users to check their input */
345 fprintf(stderr
,"Layer %d\nnr of QM atoms %d\n",grpnr
,nr
);
346 fprintf(stderr
,"QMlevel: %s/%s\n\n",
347 eQMmethod_names
[qm
->QMmethod
],eQMbasis_names
[qm
->QMbasis
]);
350 snew(qm
->frontatoms
,nr
);
351 /* Lennard-Jones coefficients */
354 /* do we optimize the QM seperately using the algorithms of the QM program??
356 qm
->bTS
= ir
->opts
.bTS
[grpnr
];
357 qm
->bOPT
= ir
->opts
.bOPT
[grpnr
];
361 t_QMrec
*copy_QMrec(t_QMrec
*qm
)
363 /* copies the contents of qm into a new t_QMrec struct */
370 qmcopy
->nrQMatoms
= qm
->nrQMatoms
;
371 snew(qmcopy
->xQM
,qmcopy
->nrQMatoms
);
372 snew(qmcopy
->indexQM
,qmcopy
->nrQMatoms
);
373 snew(qmcopy
->atomicnumberQM
,qm
->nrQMatoms
);
374 snew(qmcopy
->shiftQM
,qmcopy
->nrQMatoms
); /* the shifts */
375 for (i
=0;i
<qmcopy
->nrQMatoms
;i
++){
376 qmcopy
->shiftQM
[i
] = qm
->shiftQM
[i
];
377 qmcopy
->indexQM
[i
] = qm
->indexQM
[i
];
378 qmcopy
->atomicnumberQM
[i
] = qm
->atomicnumberQM
[i
];
380 qmcopy
->nelectrons
= qm
->nelectrons
;
381 qmcopy
->multiplicity
= qm
->multiplicity
;
382 qmcopy
->QMcharge
= qm
->QMcharge
;
383 qmcopy
->nelectrons
= qm
->nelectrons
;
384 qmcopy
->QMmethod
= qm
->QMmethod
;
385 qmcopy
->QMbasis
= qm
->QMbasis
;
386 /* trajectory surface hopping setup (Gaussian only) */
387 qmcopy
->bSH
= qm
->bSH
;
388 qmcopy
->CASorbitals
= qm
->CASorbitals
;
389 qmcopy
->CASelectrons
= qm
->CASelectrons
;
390 qmcopy
->SAsteps
= qm
->SAsteps
;
391 qmcopy
->SAon
= qm
->SAon
;
392 qmcopy
->SAoff
= qm
->SAoff
;
393 qmcopy
->bOPT
= qm
->bOPT
;
395 /* Gaussian init. variables */
396 qmcopy
->nQMcpus
= qm
->nQMcpus
;
398 qmcopy
->SHbasis
[i
] = qm
->SHbasis
[i
];
399 qmcopy
->QMmem
= qm
->QMmem
;
400 qmcopy
->accuracy
= qm
->accuracy
;
401 qmcopy
->cpmcscf
= qm
->cpmcscf
;
402 qmcopy
->SAstep
= qm
->SAstep
;
403 snew(qmcopy
->frontatoms
,qm
->nrQMatoms
);
404 snew(qmcopy
->c12
,qmcopy
->nrQMatoms
);
405 snew(qmcopy
->c6
,qmcopy
->nrQMatoms
);
406 if(qmcopy
->bTS
||qmcopy
->bOPT
){
407 for(i
=1;i
<qmcopy
->nrQMatoms
;i
++){
408 qmcopy
->frontatoms
[i
] = qm
->frontatoms
[i
];
409 qmcopy
->c12
[i
] = qm
->c12
[i
];
410 qmcopy
->c6
[i
] = qm
->c6
[i
];
418 t_QMMMrec
*mk_QMMMrec(void)
429 void init_QMMMrec(t_commrec
*cr
,
435 /* we put the atomsnumbers of atoms that belong to the QMMM group in
436 * an array that will be copied later to QMMMrec->indexQM[..]. Also
437 * it will be used to create an QMMMrec->bQMMM index array that
438 * simply contains true/false for QM and MM (the other) atoms.
441 gmx_groups_t
*groups
;
442 atom_id
*qm_arr
=NULL
,vsite
,ai
,aj
;
443 int qm_max
=0,qm_nr
=0,i
,j
,jmax
,k
,l
,nrvsite2
=0;
448 gmx_mtop_atomloop_all_t aloop
;
450 gmx_mtop_ilistloop_all_t iloop
;
454 c6au
= (HARTREE2KJ
*AVOGADRO
*pow(BOHR2NM
,6));
455 c12au
= (HARTREE2KJ
*AVOGADRO
*pow(BOHR2NM
,12));
456 fprintf(stderr
,"there we go!\n");
458 /* Make a local copy of the QMMMrec */
461 /* bQMMM[..] is an array containing TRUE/FALSE for atoms that are
462 * QM/not QM. We first set all elemenst at false. Afterwards we use
463 * the qm_arr (=MMrec->indexQM) to changes the elements
464 * corresponding to the QM atoms at TRUE. */
466 qr
->QMMMscheme
= ir
->QMMMscheme
;
468 /* we take the possibility into account that a user has
469 * defined more than one QM group:
471 /* an ugly work-around in case there is only one group In this case
472 * the whole system is treated as QM. Otherwise the second group is
473 * always the rest of the total system and is treated as MM.
476 /* small problem if there is only QM.... so no MM */
478 jmax
= ir
->opts
.ngQM
;
480 if(qr
->QMMMscheme
==eQMMMschemeoniom
)
481 qr
->nrQMlayers
= jmax
;
485 groups
= &mtop
->groups
;
487 /* there are jmax groups of QM atoms. In case of multiple QM groups
488 * I assume that the users wants to do ONIOM. However, maybe it
489 * should also be possible to define more than one QM subsystem with
490 * independent neighbourlists. I have to think about
496 aloop
= gmx_mtop_atomloop_all_init(mtop
);
497 while (gmx_mtop_atomloop_all_next(aloop
,&i
,&atom
)) {
500 srenew(qm_arr
,qm_max
);
502 if (ggrpnr(groups
,egcQMMM
,i
) == j
) {
507 if(qr
->QMMMscheme
==eQMMMschemeoniom
){
508 /* add the atoms to the bQMMM array
511 /* I assume that users specify the QM groups from small to
512 * big(ger) in the mdp file
514 qr
->qm
[j
] = mk_QMrec();
515 /* we need to throw out link atoms that in the previous layer
516 * existed to separate this QMlayer from the previous
517 * QMlayer. We use the iatoms array in the idef for that
518 * purpose. If all atoms defining the current Link Atom (Dummy2)
519 * are part of the current QM layer it needs to be removed from
522 iloop
= gmx_mtop_ilistloop_all_init(mtop
);
523 while (gmx_mtop_ilistloop_all_next(iloop
,&ilist_mol
,&a_offset
)) {
524 nrvsite2
= ilist_mol
[F_VSITE2
].nr
;
525 iatoms
= ilist_mol
[F_VSITE2
].iatoms
;
527 for(k
=0; k
<nrvsite2
; k
+=4) {
528 vsite
= a_offset
+ iatoms
[k
+1]; /* the vsite */
529 ai
= a_offset
+ iatoms
[k
+2]; /* constructing atom */
530 aj
= a_offset
+ iatoms
[k
+3]; /* constructing atom */
531 if (ggrpnr(groups
, egcQMMM
, vsite
) == ggrpnr(groups
, egcQMMM
, ai
)
533 ggrpnr(groups
, egcQMMM
, vsite
) == ggrpnr(groups
, egcQMMM
, aj
)) {
534 /* this dummy link atom needs to be removed from the qm_arr
535 * before making the QMrec of this layer!
537 for(i
=0;i
<qm_nr
;i
++){
538 if(qm_arr
[i
]==vsite
){
539 /* drop the element */
540 for(l
=i
;l
<qm_nr
;l
++){
541 qm_arr
[l
]=qm_arr
[l
+1];
550 /* store QM atoms in this layer in the QMrec and initialise layer
552 init_QMrec(j
,qr
->qm
[j
],qm_nr
,qm_arr
,mtop
,ir
);
554 /* we now store the LJ C6 and C12 parameters in QM rec in case
555 * we need to do an optimization
557 if(qr
->qm
[j
]->bOPT
|| qr
->qm
[j
]->bTS
){
558 for(i
=0;i
<qm_nr
;i
++){
559 qr
->qm
[j
]->c6
[i
] = C6(fr
->nbfp
,mtop
->ffparams
.atnr
,
560 atom
->type
,atom
->type
)/c6au
;
561 qr
->qm
[j
]->c12
[i
] = C12(fr
->nbfp
,mtop
->ffparams
.atnr
,
562 atom
->type
,atom
->type
)/c12au
;
565 /* now we check for frontier QM atoms. These occur in pairs that
566 * construct the vsite
568 iloop
= gmx_mtop_ilistloop_all_init(mtop
);
569 while (gmx_mtop_ilistloop_all_next(iloop
,&ilist_mol
,&a_offset
)) {
570 nrvsite2
= ilist_mol
[F_VSITE2
].nr
;
571 iatoms
= ilist_mol
[F_VSITE2
].iatoms
;
573 for(k
=0; k
<nrvsite2
; k
+=4){
574 vsite
= a_offset
+ iatoms
[k
+1]; /* the vsite */
575 ai
= a_offset
+ iatoms
[k
+2]; /* constructing atom */
576 aj
= a_offset
+ iatoms
[k
+3]; /* constructing atom */
577 if(ggrpnr(groups
,egcQMMM
,ai
) < (groups
->grps
[egcQMMM
].nr
-1) &&
578 (ggrpnr(groups
,egcQMMM
,aj
) >= (groups
->grps
[egcQMMM
].nr
-1))){
579 /* mark ai as frontier atom */
580 for(i
=0;i
<qm_nr
;i
++){
581 if( (qm_arr
[i
]==ai
) || (qm_arr
[i
]==vsite
) ){
582 qr
->qm
[j
]->frontatoms
[i
]=TRUE
;
586 else if(ggrpnr(groups
,egcQMMM
,aj
) < (groups
->grps
[egcQMMM
].nr
-1) &&
587 (ggrpnr(groups
,egcQMMM
,ai
) >= (groups
->grps
[egcQMMM
].nr
-1))){
588 /* mark aj as frontier atom */
589 for(i
=0;i
<qm_nr
;i
++){
590 if( (qm_arr
[i
]==aj
) || (qm_arr
[i
]==vsite
)){
591 qr
->qm
[j
]->frontatoms
[i
]=TRUE
;
599 if(qr
->QMMMscheme
!=eQMMMschemeoniom
){
601 /* standard QMMM, all layers are merged together so there is one QM
602 * subsystem and one MM subsystem.
603 * Also we set the charges to zero in the md->charge arrays to prevent
604 * the innerloops from doubly counting the electostatic QM MM interaction
606 for (k
=0;k
<qm_nr
;k
++){
607 gmx_mtop_atomnr_to_atom(mtop
,qm_arr
[k
],&atom
);
611 qr
->qm
[0] = mk_QMrec();
612 /* store QM atoms in the QMrec and initialise
614 init_QMrec(0,qr
->qm
[0],qm_nr
,qm_arr
,mtop
,ir
);
615 if(qr
->qm
[0]->bOPT
|| qr
->qm
[0]->bTS
){
616 for(i
=0;i
<qm_nr
;i
++){
617 gmx_mtop_atomnr_to_atom(mtop
,qm_arr
[i
],&atom
);
618 qr
->qm
[0]->c6
[i
] = C6(fr
->nbfp
,mtop
->ffparams
.atnr
,
619 atom
->type
,atom
->type
)/c6au
;
620 qr
->qm
[0]->c12
[i
] = C12(fr
->nbfp
,mtop
->ffparams
.atnr
,
621 atom
->type
,atom
->type
)/c12au
;
628 /* find frontier atoms and mark them true in the frontieratoms array.
630 for(i
=0;i
<qm_nr
;i
++) {
631 gmx_mtop_atomnr_to_ilist(mtop
,qm_arr
[i
],&ilist_mol
,&a_offset
);
632 nrvsite2
= ilist_mol
[F_VSITE2
].nr
;
633 iatoms
= ilist_mol
[F_VSITE2
].iatoms
;
635 for(k
=0;k
<nrvsite2
;k
+=4){
636 vsite
= a_offset
+ iatoms
[k
+1]; /* the vsite */
637 ai
= a_offset
+ iatoms
[k
+2]; /* constructing atom */
638 aj
= a_offset
+ iatoms
[k
+3]; /* constructing atom */
639 if(ggrpnr(groups
,egcQMMM
,ai
) < (groups
->grps
[egcQMMM
].nr
-1) &&
640 (ggrpnr(groups
,egcQMMM
,aj
) >= (groups
->grps
[egcQMMM
].nr
-1))){
641 /* mark ai as frontier atom */
642 if ( (qm_arr
[i
]==ai
) || (qm_arr
[i
]==vsite
) ){
643 qr
->qm
[0]->frontatoms
[i
]=TRUE
;
646 else if (ggrpnr(groups
,egcQMMM
,aj
) < (groups
->grps
[egcQMMM
].nr
-1) &&
647 (ggrpnr(groups
,egcQMMM
,ai
) >=(groups
->grps
[egcQMMM
].nr
-1))) {
648 /* mark aj as frontier atom */
649 if ( (qm_arr
[i
]==aj
) || (qm_arr
[i
]==vsite
) ){
650 qr
->qm
[0]->frontatoms
[i
]=TRUE
;
656 /* MM rec creation */
658 mm
->scalefactor
= ir
->scalefactor
;
659 mm
->nrMMatoms
= (mtop
->natoms
)-(qr
->qm
[0]->nrQMatoms
); /* rest of the atoms */
662 /* MM rec creation */
664 mm
->scalefactor
= ir
->scalefactor
;
669 /* these variables get updated in the update QMMMrec */
671 if(qr
->nrQMlayers
==1){
672 /* with only one layer there is only one initialisation
673 * needed. Multilayer is a bit more complicated as it requires
674 * re-initialisation at every step of the simulation. This is due
675 * to the use of COMMON blocks in the fortran QM subroutines.
677 if (qr
->qm
[0]->QMmethod
<eQMmethodRHF
)
679 #ifdef GMX_QMMM_MOPAC
680 /* semi-empiprical 1-layer ONIOM calculation requested (mopac93) */
681 init_mopac(cr
,qr
->qm
[0],qr
->mm
);
683 gmx_fatal(FARGS
,"Semi-empirical QM only supported with Mopac.");
688 /* ab initio calculation requested (gamess/gaussian) */
689 #ifdef GMX_QMMM_GAMESS
690 init_gamess(cr
,qr
->qm
[0],qr
->mm
);
691 #elif defined GMX_QMMM_GAUSSIAN
692 init_gaussian(cr
,qr
->qm
[0],qr
->mm
);
694 gmx_fatal(FARGS
,"Ab-initio calculation only supported with Gamess or Gaussian.");
700 void update_QMMMrec(t_commrec
*cr
,
707 /* updates the coordinates of both QM atoms and MM atoms and stores
708 * them in the QMMMrec.
710 * NOTE: is NOT yet working if there are no PBC. Also in ns.c, simple
711 * ns needs to be fixed!
714 mm_max
=0,mm_nr
=0,mm_nr_new
,i
,j
,is
,k
,shift
;
716 *mm_j_particles
=NULL
,*qm_i_particles
=NULL
;
732 *parallelMMarray
=NULL
;
736 c6au
= (HARTREE2KJ
*AVOGADRO
*pow(BOHR2NM
,6));
737 c12au
= (HARTREE2KJ
*AVOGADRO
*pow(BOHR2NM
,12));
739 /* every cpu has this array. On every processor we fill this array
740 * with 1's and 0's. 1's indicate the atoms is a QM atom on the
741 * current cpu in a later stage these arrays are all summed. indexes
742 * > 0 indicate the atom is a QM atom. Every node therefore knows
743 * whcih atoms are part of the QM subsystem.
745 /* copy some pointers */
748 QMMMlist
= fr
->QMMMlist
;
752 /* init_pbc(box); needs to be called first, see pbc.h */
753 set_pbc_dd(&pbc
,fr
->ePBC
,DOMAINDECOMP(cr
) ? cr
->dd
: NULL
,FALSE
,box
);
754 /* only in standard (normal) QMMM we need the neighbouring MM
755 * particles to provide a electric field of point charges for the QM
758 if(qr
->QMMMscheme
==eQMMMschemenormal
){ /* also implies 1 QM-layer */
759 /* we NOW create/update a number of QMMMrec entries:
761 * 1) the shiftQM, containing the shifts of the QM atoms
763 * 2) the indexMM array, containing the index of the MM atoms
765 * 3) the shiftMM, containing the shifts of the MM atoms
767 * 4) the shifted coordinates of the MM atoms
769 * the shifts are used for computing virial of the QM/MM particles.
771 qm
= qr
->qm
[0]; /* in case of normal QMMM, there is only one group */
772 snew(qm_i_particles
,QMMMlist
.nri
);
774 qm_i_particles
[0].shift
= XYZ2IS(0,0,0);
775 for(i
=0;i
<QMMMlist
.nri
;i
++){
776 qm_i_particles
[i
].j
= QMMMlist
.iinr
[i
];
779 qm_i_particles
[i
].shift
= pbc_dx_aiuc(&pbc
,x
[QMMMlist
.iinr
[0]],
780 x
[QMMMlist
.iinr
[i
]],dx
);
783 /* However, since nri >= nrQMatoms, we do a quicksort, and throw
784 * out double, triple, etc. entries later, as we do for the MM
788 /* compute the shift for the MM j-particles with respect to
789 * the QM i-particle and store them.
792 crd
[0] = IS2X(QMMMlist
.shift
[i
]) + IS2X(qm_i_particles
[i
].shift
);
793 crd
[1] = IS2Y(QMMMlist
.shift
[i
]) + IS2Y(qm_i_particles
[i
].shift
);
794 crd
[2] = IS2Z(QMMMlist
.shift
[i
]) + IS2Z(qm_i_particles
[i
].shift
);
795 is
= XYZ2IS(crd
[0],crd
[1],crd
[2]);
796 for(j
=QMMMlist
.jindex
[i
];
797 j
<QMMMlist
.jindex
[i
+1];
801 srenew(mm_j_particles
,mm_max
);
804 mm_j_particles
[mm_nr
].j
= QMMMlist
.jjnr
[j
];
805 mm_j_particles
[mm_nr
].shift
= is
;
810 /* quicksort QM and MM shift arrays and throw away multiple entries */
814 qsort(qm_i_particles
,QMMMlist
.nri
,
815 (size_t)sizeof(qm_i_particles
[0]),
817 qsort(mm_j_particles
,mm_nr
,
818 (size_t)sizeof(mm_j_particles
[0]),
820 /* remove multiples in the QM shift array, since in init_QMMM() we
821 * went through the atom numbers from 0 to md.nr, the order sorted
822 * here matches the one of QMindex already.
825 for(i
=0;i
<QMMMlist
.nri
;i
++){
826 if (i
==0 || qm_i_particles
[i
].j
!=qm_i_particles
[i
-1].j
){
827 qm_i_particles
[j
++] = qm_i_particles
[i
];
831 if(qm
->bTS
||qm
->bOPT
){
832 /* only remove double entries for the MM array */
833 for(i
=0;i
<mm_nr
;i
++){
834 if((i
==0 || mm_j_particles
[i
].j
!=mm_j_particles
[i
-1].j
)
835 && !md
->bQM
[mm_j_particles
[i
].j
]){
836 mm_j_particles
[mm_nr_new
++] = mm_j_particles
[i
];
840 /* we also remove mm atoms that have no charges!
841 * actually this is already done in the ns.c
844 for(i
=0;i
<mm_nr
;i
++){
845 if((i
==0 || mm_j_particles
[i
].j
!=mm_j_particles
[i
-1].j
)
846 && !md
->bQM
[mm_j_particles
[i
].j
]
847 && (md
->chargeA
[mm_j_particles
[i
].j
]
848 || (md
->chargeB
&& md
->chargeB
[mm_j_particles
[i
].j
]))) {
849 mm_j_particles
[mm_nr_new
++] = mm_j_particles
[i
];
854 /* store the data retrieved above into the QMMMrec
857 /* Keep the compiler happy,
858 * shift will always be set in the loop for i=0
861 for(i
=0;i
<qm
->nrQMatoms
;i
++){
862 /* not all qm particles might have appeared as i
863 * particles. They might have been part of the same charge
864 * group for instance.
866 if (qm
->indexQM
[i
] == qm_i_particles
[k
].j
) {
867 shift
= qm_i_particles
[k
++].shift
;
869 /* use previous shift, assuming they belong the same charge
873 qm
->shiftQM
[i
] = shift
;
876 /* parallel excecution */
878 snew(parallelMMarray
,2*(md
->nr
));
879 /* only MM particles have a 1 at their atomnumber. The second part
880 * of the array contains the shifts. Thus:
881 * p[i]=1/0 depending on wether atomnumber i is a MM particle in the QM
882 * step or not. p[i+md->nr] is the shift of atomnumber i.
884 for(i
=0;i
<2*(md
->nr
);i
++){
885 parallelMMarray
[i
]=0;
888 for(i
=0;i
<mm_nr
;i
++){
889 parallelMMarray
[mm_j_particles
[i
].j
]=1;
890 parallelMMarray
[mm_j_particles
[i
].j
+(md
->nr
)]=mm_j_particles
[i
].shift
;
892 gmx_sumi(md
->nr
,parallelMMarray
,cr
);
896 for(i
=0;i
<md
->nr
;i
++){
897 if(parallelMMarray
[i
]){
900 srenew(mm
->indexMM
,mm_max
);
901 srenew(mm
->shiftMM
,mm_max
);
903 mm
->indexMM
[mm_nr
] = i
;
904 mm
->shiftMM
[mm_nr
++]= parallelMMarray
[i
+md
->nr
]/parallelMMarray
[i
];
908 free(parallelMMarray
);
910 /* serial execution */
912 mm
->nrMMatoms
= mm_nr
;
913 srenew(mm
->shiftMM
,mm_nr
);
914 srenew(mm
->indexMM
,mm_nr
);
915 for(i
=0;i
<mm_nr
;i
++){
916 mm
->indexMM
[i
]=mm_j_particles
[i
].j
;
917 mm
->shiftMM
[i
]=mm_j_particles
[i
].shift
;
921 /* (re) allocate memory for the MM coordiate array. The QM
922 * coordinate array was already allocated in init_QMMM, and is
923 * only (re)filled in the update_QMMM_coordinates routine
925 srenew(mm
->xMM
,mm
->nrMMatoms
);
926 /* now we (re) fill the array that contains the MM charges with
927 * the forcefield charges. If requested, these charges will be
930 srenew(mm
->MMcharges
,mm
->nrMMatoms
);
931 for(i
=0;i
<mm
->nrMMatoms
;i
++){/* no free energy yet */
932 mm
->MMcharges
[i
]=md
->chargeA
[mm
->indexMM
[i
]]*mm
->scalefactor
;
934 if(qm
->bTS
||qm
->bOPT
){
935 /* store (copy) the c6 and c12 parameters into the MMrec struct
937 srenew(mm
->c6
,mm
->nrMMatoms
);
938 srenew(mm
->c12
,mm
->nrMMatoms
);
939 for (i
=0;i
<mm
->nrMMatoms
;i
++){
940 mm
->c6
[i
] = C6(fr
->nbfp
,top
->idef
.atnr
,
941 md
->typeA
[mm
->indexMM
[i
]],
942 md
->typeA
[mm
->indexMM
[i
]])/c6au
;
943 mm
->c12
[i
] =C12(fr
->nbfp
,top
->idef
.atnr
,
944 md
->typeA
[mm
->indexMM
[i
]],
945 md
->typeA
[mm
->indexMM
[i
]])/c12au
;
947 punch_QMMM_excl(qr
->qm
[0],mm
,&(top
->excls
));
949 /* the next routine fills the coordinate fields in the QMMM rec of
950 * both the qunatum atoms and the MM atoms, using the shifts
954 update_QMMM_coord(x
,fr
,qr
->qm
[0],qr
->mm
);
955 free(qm_i_particles
);
956 free(mm_j_particles
);
958 else { /* ONIOM */ /* ????? */
960 /* do for each layer */
961 for (j
=0;j
<qr
->nrQMlayers
;j
++){
963 qm
->shiftQM
[0]=XYZ2IS(0,0,0);
964 for(i
=1;i
<qm
->nrQMatoms
;i
++){
965 qm
->shiftQM
[i
] = pbc_dx_aiuc(&pbc
,x
[qm
->indexQM
[0]],x
[qm
->indexQM
[i
]],
968 update_QMMM_coord(x
,fr
,qm
,mm
);
971 } /* update_QMMM_rec */
974 real
calculate_QMMM(t_commrec
*cr
,
981 /* a selection for the QM package depending on which is requested
982 * (Gaussian, GAMESS-UK or MOPAC) needs to be implemented here. Now
983 * it works through defines.... Not so nice yet
992 *forces
=NULL
,*fshift
=NULL
,
993 *forces2
=NULL
, *fshift2
=NULL
; /* needed for multilayer ONIOM */
996 /* make a local copy the QMMMrec pointer
1001 /* now different procedures are carried out for one layer ONION and
1002 * normal QMMM on one hand and multilayer oniom on the other
1004 if(qr
->QMMMscheme
==eQMMMschemenormal
|| qr
->nrQMlayers
==1){
1006 snew(forces
,(qm
->nrQMatoms
+mm
->nrMMatoms
));
1007 snew(fshift
,(qm
->nrQMatoms
+mm
->nrMMatoms
));
1008 QMener
= call_QMroutine(cr
,fr
,qm
,mm
,forces
,fshift
);
1009 for(i
=0;i
<qm
->nrQMatoms
;i
++){
1011 f
[qm
->indexQM
[i
]][j
] -= forces
[i
][j
];
1012 fr
->fshift
[qm
->shiftQM
[i
]][j
] += fshift
[i
][j
];
1015 for(i
=0;i
<mm
->nrMMatoms
;i
++){
1017 f
[mm
->indexMM
[i
]][j
] -= forces
[qm
->nrQMatoms
+i
][j
];
1018 fr
->fshift
[mm
->shiftMM
[i
]][j
] += fshift
[qm
->nrQMatoms
+i
][j
];
1025 else{ /* Multi-layer ONIOM */
1026 for(i
=0;i
<qr
->nrQMlayers
-1;i
++){ /* last layer is special */
1028 qm2
= copy_QMrec(qr
->qm
[i
+1]);
1030 qm2
->nrQMatoms
= qm
->nrQMatoms
;
1032 for(j
=0;j
<qm2
->nrQMatoms
;j
++){
1034 qm2
->xQM
[j
][k
] = qm
->xQM
[j
][k
];
1035 qm2
->indexQM
[j
] = qm
->indexQM
[j
];
1036 qm2
->atomicnumberQM
[j
] = qm
->atomicnumberQM
[j
];
1037 qm2
->shiftQM
[j
] = qm
->shiftQM
[j
];
1040 qm2
->QMcharge
= qm
->QMcharge
;
1041 /* this layer at the higher level of theory */
1042 srenew(forces
,qm
->nrQMatoms
);
1043 srenew(fshift
,qm
->nrQMatoms
);
1044 /* we need to re-initialize the QMroutine every step... */
1045 init_QMroutine(cr
,qm
,mm
);
1046 QMener
+= call_QMroutine(cr
,fr
,qm
,mm
,forces
,fshift
);
1048 /* this layer at the lower level of theory */
1049 srenew(forces2
,qm
->nrQMatoms
);
1050 srenew(fshift2
,qm
->nrQMatoms
);
1051 init_QMroutine(cr
,qm2
,mm
);
1052 QMener
-= call_QMroutine(cr
,fr
,qm2
,mm
,forces2
,fshift2
);
1053 /* E = E1high-E1low The next layer includes the current layer at
1054 * the lower level of theory, which provides + E2low
1055 * this is similar for gradients
1057 for(i
=0;i
<qm
->nrQMatoms
;i
++){
1059 f
[qm
->indexQM
[i
]][j
] -= (forces
[i
][j
]-forces2
[i
][j
]);
1060 fr
->fshift
[qm
->shiftQM
[i
]][j
] += (fshift
[i
][j
]-fshift2
[i
][j
]);
1065 /* now the last layer still needs to be done: */
1066 qm
= qr
->qm
[qr
->nrQMlayers
-1]; /* C counts from 0 */
1067 init_QMroutine(cr
,qm
,mm
);
1068 srenew(forces
,qm
->nrQMatoms
);
1069 srenew(fshift
,qm
->nrQMatoms
);
1070 QMener
+= call_QMroutine(cr
,fr
,qm
,mm
,forces
,fshift
);
1071 for(i
=0;i
<qm
->nrQMatoms
;i
++){
1073 f
[qm
->indexQM
[i
]][j
] -= forces
[i
][j
];
1074 fr
->fshift
[qm
->shiftQM
[i
]][j
] += fshift
[i
][j
];
1082 if(qm
->bTS
||qm
->bOPT
){
1083 /* qm[0] still contains the largest ONIOM QM subsystem
1084 * we take the optimized coordiates and put the in x[]
1086 for(i
=0;i
<qm
->nrQMatoms
;i
++){
1088 x
[qm
->indexQM
[i
]][j
] = qm
->xQM
[i
][j
];
1093 } /* calculate_QMMM */
1095 /* end of QMMM core routines */