Fixed typo in CMakeLists for mdrun-gpu
[gromacs/qmmm-gamess-us.git] / src / mdlib / qmmm.c
blob109b3e61775cd4e381d0696d28d517061aa3244f
1 /*
2 *
3 * This source code is part of
4 *
5 * G R O M A C S
6 *
7 * GROningen MAchine for Chemical Simulations
8 *
9 * VERSION 3.2.0
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
32 * And Hey:
33 * GROwing Monsters And Cloning Shrimps
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
39 #include <math.h>
40 #include "sysstuff.h"
41 #include "typedefs.h"
42 #include "macros.h"
43 #include "smalloc.h"
44 #include "assert.h"
45 #include "physics.h"
46 #include "macros.h"
47 #include "vec.h"
48 #include "force.h"
49 #include "invblock.h"
50 #include "confio.h"
51 #include "names.h"
52 #include "network.h"
53 #include "pbc.h"
54 #include "ns.h"
55 #include "nrnb.h"
56 #include "bondf.h"
57 #include "mshift.h"
58 #include "txtdump.h"
59 #include "copyrite.h"
60 #include "qmmm.h"
61 #include <stdio.h>
62 #include <string.h>
63 #include "gmx_fatal.h"
64 #include "typedefs.h"
65 #include <stdlib.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 */
75 void
76 init_gamess(t_commrec *cr, t_QMrec *qm, t_MMrec *mm);
78 real
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
83 /* MOPAC interface */
85 void
86 init_mopac(t_commrec *cr, t_QMrec *qm, t_MMrec *mm);
88 real
89 call_mopac(t_commrec *cr,t_forcerec *fr, t_QMrec *qm,
90 t_MMrec *mm,rvec f[], rvec fshift[]);
92 real
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 */
99 void
100 init_gaussian(t_commrec *cr ,t_QMrec *qm, t_MMrec *mm);
102 real
103 call_gaussian_SH(t_commrec *cr,t_forcerec *fr,t_QMrec *qm,
104 t_MMrec *mm,rvec f[], rvec fshift[]);
106 real
107 call_gaussian(t_commrec *cr,t_forcerec *fr, t_QMrec *qm,
108 t_MMrec *mm,rvec f[], rvec fshift[]);
110 #endif
115 /* this struct and these comparison functions are needed for creating
116 * a QMMM input for the QM routines from the QMMM neighbor list.
119 typedef struct {
120 int j;
121 int shift;
122 } t_j_particle;
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);
128 } /* struct_comp */
130 static int int_comp(const void *a,const void *b){
132 return (*(int *)a) - (*(int *)b);
134 } /* int_comp */
136 static int QMlayer_comp(const void *a, const void *b){
138 return (int)(((t_QMrec *)a)->nrQMatoms)-(int)(((t_QMrec *)b)->nrQMatoms);
140 } /* QMlayer_comp */
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]),
146 QMlayer_comp);
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
156 real
157 QMener=0.0;
159 /* do a semi-empiprical calculation */
161 if (qm->QMmethod<eQMmethodRHF && !(mm->nrMMatoms))
163 #ifdef GMX_QMMM_MOPAC
164 if (qm->bSH)
165 QMener = call_mopac_SH(cr,fr,qm,mm,f,fshift);
166 else
167 QMener = call_mopac(cr,fr,qm,mm,f,fshift);
168 #else
169 gmx_fatal(FARGS,"Semi-empirical QM only supported with Mopac.");
170 #endif
172 else
174 /* do an ab-initio calculation */
175 if (qm->bSH)
177 #ifdef GMX_QMMM_GAUSSIAN
178 QMener = call_gaussian_SH(cr,fr,qm,mm,f,fshift);
179 #else
180 gmx_fatal(FARGS,"Ab-initio Surface-hopping only supported with Gaussian.");
181 #endif
183 else
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);
189 #else
190 gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess or Gaussian.");
191 #endif
194 return (QMener);
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);
205 #else
206 gmx_fatal(FARGS,"Semi-empirical QM only supported with Mopac.");
207 #endif
209 else
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);
216 #else
217 gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess or Gaussian.");
218 #endif
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
249 FILE
250 *out=NULL;
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++){
260 nrexcl = 0;
261 for(j=excls->index[qm->indexQM[i]];
262 j<excls->index[qm->indexQM[i]+1];
263 j++){
264 for(k=0;k<mm->nrMMatoms;k++){
265 if(mm->indexMM[k]==excls->a[j]){/* the excluded MM atom */
266 if(nrexcl >= max){
267 max += 1000;
268 srenew(excluded,max);
270 excluded[nrexcl++]=k;
271 continue;
275 /* write to file: */
276 fprintf(out,"%5d %5d\n",i+1,nrexcl);
277 for(j=0;j<nrexcl;j++){
278 fprintf(out,"%5d ",excluded[j]);
280 fprintf(out,"\n");
282 free(excluded);
283 fclose(out);
284 } /* punch_QMMM_excl */
287 /* end of QMMM subroutines */
289 /* QMMM core routines */
291 t_QMrec *mk_QMrec(void){
292 t_QMrec *qm;
293 snew(qm,1);
294 return qm;
295 } /* mk_QMrec */
297 t_MMrec *mk_MMrec(void){
298 t_MMrec *mm;
299 snew(mm,1);
300 return mm;
301 } /* mk_MMrec */
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
308 int i;
309 t_atom *atom;
312 qm->nrQMatoms = nr;
313 snew(qm->xQM,nr);
314 snew(qm->indexQM,nr);
315 snew(qm->shiftQM,nr); /* the shifts */
316 for(i=0;i<nr;i++){
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
342 * (init_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]);
349 /* frontier atoms */
350 snew(qm->frontatoms,nr);
351 /* Lennard-Jones coefficients */
352 snew(qm->c6,nr);
353 snew(qm->c12,nr);
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];
359 } /* init_QMrec */
361 t_QMrec *copy_QMrec(t_QMrec *qm)
363 /* copies the contents of qm into a new t_QMrec struct */
364 t_QMrec
365 *qmcopy;
369 qmcopy = mk_QMrec();
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;
397 for(i=0;i<DIM;i++)
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];
414 return(qmcopy);
416 } /*copy_QMrec */
418 t_QMMMrec *mk_QMMMrec(void)
421 t_QMMMrec *qr;
423 snew(qr,1);
425 return qr;
427 } /* mk_QMMMrec */
429 void init_QMMMrec(t_commrec *cr,
430 matrix box,
431 gmx_mtop_t *mtop,
432 t_inputrec *ir,
433 t_forcerec *fr)
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;
444 t_QMMMrec *qr;
445 t_MMrec *mm;
446 t_iatom *iatoms;
447 real c12au,c6au;
448 gmx_mtop_atomloop_all_t aloop;
449 t_atom *atom;
450 gmx_mtop_ilistloop_all_t iloop;
451 int a_offset;
452 t_ilist *ilist_mol;
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 */
459 qr = fr->qr;
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;
482 else
483 qr->nrQMlayers = 1;
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
491 * that.. 11-11-2003
493 snew(qr->qm,jmax);
494 for(j=0;j<jmax;j++){
495 /* new layer */
496 aloop = gmx_mtop_atomloop_all_init(mtop);
497 while (gmx_mtop_atomloop_all_next(aloop,&i,&atom)) {
498 if(qm_nr >= qm_max){
499 qm_max += 1000;
500 srenew(qm_arr,qm_max);
502 if (ggrpnr(groups,egcQMMM ,i) == j) {
503 /* hack for tip4p */
504 qm_arr[qm_nr++] = i;
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
520 * qm_arr[]. */
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];
543 qm_nr--;
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);
608 atom->q = 0.0;
609 atom->qB = 0.0;
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 */
657 mm = mk_MMrec();
658 mm->scalefactor = ir->scalefactor;
659 mm->nrMMatoms = (mtop->natoms)-(qr->qm[0]->nrQMatoms); /* rest of the atoms */
660 qr->mm = mm;
661 } else {/* ONIOM */
662 /* MM rec creation */
663 mm = mk_MMrec();
664 mm->scalefactor = ir->scalefactor;
665 mm->nrMMatoms = 0;
666 qr->mm = mm;
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);
682 #else
683 gmx_fatal(FARGS,"Semi-empirical QM only supported with Mopac.");
684 #endif
686 else
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);
693 #else
694 gmx_fatal(FARGS,"Ab-initio calculation only supported with Gamess or Gaussian.");
695 #endif
698 } /* init_QMMMrec */
700 void update_QMMMrec(t_commrec *cr,
701 t_forcerec *fr,
702 rvec x[],
703 t_mdatoms *md,
704 matrix box,
705 gmx_localtop_t *top)
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!
713 int
714 mm_max=0,mm_nr=0,mm_nr_new,i,j,is,k,shift;
715 t_j_particle
716 *mm_j_particles=NULL,*qm_i_particles=NULL;
717 t_QMMMrec
718 *qr;
719 t_nblist
720 QMMMlist;
721 rvec
722 dx,crd;
724 *MMatoms;
725 t_QMrec
726 *qm;
727 t_MMrec
728 *mm;
729 t_pbc
730 pbc;
731 int
732 *parallelMMarray=NULL;
733 real
734 c12au,c6au;
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 */
746 qr = fr->qr;
747 mm = qr->mm;
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
756 * atoms.
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);
773 if(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];
778 if(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
785 * list too.
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];
798 j++){
799 if(mm_nr >= mm_max){
800 mm_max += 1000;
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;
806 mm_nr++;
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]),
816 struct_comp);
817 qsort(mm_j_particles,mm_nr,
818 (size_t)sizeof(mm_j_particles[0]),
819 struct_comp);
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.
824 j=0;
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];
830 mm_nr_new = 0;
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
843 else{
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];
853 mm_nr = mm_nr_new;
854 /* store the data retrieved above into the QMMMrec
856 k=0;
857 /* Keep the compiler happy,
858 * shift will always be set in the loop for i=0
860 shift = 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
870 * group anyway,
873 qm->shiftQM[i] = shift;
876 /* parallel excecution */
877 if(PAR(cr)){
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);
893 mm_nr=0;
895 mm_max = 0;
896 for(i=0;i<md->nr;i++){
897 if(parallelMMarray[i]){
898 if(mm_nr >= mm_max){
899 mm_max += 1000;
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];
907 mm->nrMMatoms=mm_nr;
908 free(parallelMMarray);
910 /* serial execution */
911 else{
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
928 * scaled by a factor
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
951 * calculated above.
954 update_QMMM_coord(x,fr,qr->qm[0],qr->mm);
955 free(qm_i_particles);
956 free(mm_j_particles);
958 else { /* ONIOM */ /* ????? */
959 mm->nrMMatoms=0;
960 /* do for each layer */
961 for (j=0;j<qr->nrQMlayers;j++){
962 qm = qr->qm[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]],
966 dx);
968 update_QMMM_coord(x,fr,qm,mm);
971 } /* update_QMMM_rec */
974 real calculate_QMMM(t_commrec *cr,
975 rvec x[],rvec f[],
976 t_forcerec *fr,
977 t_mdatoms *md)
979 real
980 QMener=0.0;
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
985 t_QMMMrec
986 *qr;
987 t_QMrec
988 *qm,*qm2;
989 t_MMrec
990 *mm=NULL;
991 rvec
992 *forces=NULL,*fshift=NULL,
993 *forces2=NULL, *fshift2=NULL; /* needed for multilayer ONIOM */
995 i,j,k;
996 /* make a local copy the QMMMrec pointer
998 qr = fr->qr;
999 mm = qr->mm;
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){
1005 qm = qr->qm[0];
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++){
1010 for(j=0;j<DIM;j++){
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++){
1016 for(j=0;j<DIM;j++){
1017 f[mm->indexMM[i]][j] -= forces[qm->nrQMatoms+i][j];
1018 fr->fshift[mm->shiftMM[i]][j] += fshift[qm->nrQMatoms+i][j];
1022 free(forces);
1023 free(fshift);
1025 else{ /* Multi-layer ONIOM */
1026 for(i=0;i<qr->nrQMlayers-1;i++){ /* last layer is special */
1027 qm = qr->qm[i];
1028 qm2 = copy_QMrec(qr->qm[i+1]);
1030 qm2->nrQMatoms = qm->nrQMatoms;
1032 for(j=0;j<qm2->nrQMatoms;j++){
1033 for(k=0;k<DIM;k++)
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++){
1058 for(j=0;j<DIM;j++){
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]);
1063 free(qm2);
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++){
1072 for(j=0;j<DIM;j++){
1073 f[qm->indexQM[i]][j] -= forces[i][j];
1074 fr->fshift[qm->shiftQM[i]][j] += fshift[i][j];
1077 free(forces);
1078 free(fshift);
1079 free(forces2);
1080 free(fshift2);
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++){
1087 for(j=0;j<DIM;j++){
1088 x[qm->indexQM[i]][j] = qm->xQM[i][j];
1092 return(QMener);
1093 } /* calculate_QMMM */
1095 /* end of QMMM core routines */