2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team.
6 * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
50 #include "gromacs/domdec/domdec_struct.h"
51 #include "gromacs/fileio/confio.h"
52 #include "gromacs/gmxlib/network.h"
53 #include "gromacs/gmxlib/nrnb.h"
54 #include "gromacs/math/functions.h"
55 #include "gromacs/math/units.h"
56 #include "gromacs/math/vec.h"
57 #include "gromacs/mdlib/ns.h"
58 #include "gromacs/mdtypes/commrec.h"
59 #include "gromacs/mdtypes/forcerec.h"
60 #include "gromacs/mdtypes/inputrec.h"
61 #include "gromacs/mdtypes/md_enums.h"
62 #include "gromacs/mdtypes/mdatom.h"
63 #include "gromacs/mdtypes/nblist.h"
64 #include "gromacs/pbcutil/ishift.h"
65 #include "gromacs/pbcutil/pbc.h"
66 #include "gromacs/topology/mtop_lookup.h"
67 #include "gromacs/topology/mtop_util.h"
68 #include "gromacs/topology/topology.h"
69 #include "gromacs/utility/fatalerror.h"
70 #include "gromacs/utility/smalloc.h"
72 /* declarations of the interfaces to the QM packages. The _SH indicate
73 * the QM interfaces can be used for Surface Hopping simulations
76 /* GAMESS interface */
79 init_gamess(const t_commrec
*cr
, t_QMrec
*qm
, t_MMrec
*mm
);
82 call_gamess(const t_forcerec
*fr
,
83 t_QMrec
*qm
, t_MMrec
*mm
, rvec f
[], rvec fshift
[]);
89 init_mopac(t_QMrec
*qm
);
92 call_mopac(t_QMrec
*qm
, t_MMrec
*mm
, rvec f
[], rvec fshift
[]);
95 call_mopac_SH(t_QMrec
*qm
, t_MMrec
*mm
, rvec f
[], rvec fshift
[]);
97 #elif GMX_QMMM_GAUSSIAN
98 /* GAUSSIAN interface */
101 init_gaussian(t_QMrec
*qm
);
104 call_gaussian_SH(const t_forcerec
*fr
, t_QMrec
*qm
, t_MMrec
*mm
, rvec f
[], rvec fshift
[]);
107 call_gaussian(const t_forcerec
*fr
, t_QMrec
*qm
, t_MMrec
*mm
, rvec f
[], rvec fshift
[]);
110 #include "gromacs/mdlib/qm_orca.h"
114 /* this struct and these comparison functions are needed for creating
115 * a QMMM input for the QM routines from the QMMM neighbor list.
123 static bool struct_comp(const t_j_particle
&a
, const t_j_particle
&b
)
128 static real
call_QMroutine(const t_commrec gmx_unused
*cr
, const t_forcerec gmx_unused
*fr
, t_QMrec gmx_unused
*qm
,
129 t_MMrec gmx_unused
*mm
, rvec gmx_unused f
[], rvec gmx_unused fshift
[])
131 /* makes a call to the requested QM routine (qm->QMmethod)
132 * Note that f is actually the gradient, i.e. -f
134 /* do a semi-empiprical calculation */
136 if (qm
->QMmethod
< eQMmethodRHF
&& !(mm
->nrMMatoms
))
141 return call_mopac_SH(qm
, mm
, f
, fshift
);
145 return call_mopac(qm
, mm
, f
, fshift
);
148 gmx_fatal(FARGS
, "Semi-empirical QM only supported with Mopac.");
153 /* do an ab-initio calculation */
154 if (qm
->bSH
&& qm
->QMmethod
== eQMmethodCASSCF
)
156 #if GMX_QMMM_GAUSSIAN
157 return call_gaussian_SH(fr
, qm
, mm
, f
, fshift
);
159 gmx_fatal(FARGS
, "Ab-initio Surface-hopping only supported with Gaussian.");
165 return call_gamess(fr
, qm
, mm
, f
, fshift
);
166 #elif GMX_QMMM_GAUSSIAN
167 return call_gaussian(fr
, qm
, mm
, f
, fshift
);
169 return call_orca(fr
, qm
, mm
, f
, fshift
);
171 gmx_fatal(FARGS
, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
177 static void init_QMroutine(const t_commrec gmx_unused
*cr
, t_QMrec gmx_unused
*qm
, t_MMrec gmx_unused
*mm
)
179 /* makes a call to the requested QM routine (qm->QMmethod)
181 if (qm
->QMmethod
< eQMmethodRHF
)
184 /* do a semi-empiprical calculation */
187 gmx_fatal(FARGS
, "Semi-empirical QM only supported with Mopac.");
192 /* do an ab-initio calculation */
194 init_gamess(cr
, qm
, mm
);
195 #elif GMX_QMMM_GAUSSIAN
200 gmx_fatal(FARGS
, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
203 } /* init_QMroutine */
205 static void update_QMMM_coord(const rvec
*x
, const t_forcerec
*fr
, t_QMrec
*qm
, t_MMrec
*mm
)
207 /* shifts the QM and MM particles into the central box and stores
208 * these shifted coordinates in the coordinate arrays of the
209 * QMMMrec. These coordinates are passed on the QM subroutines.
214 /* shift the QM atoms into the central box
216 for (i
= 0; i
< qm
->nrQMatoms
; i
++)
218 rvec_sub(x
[qm
->indexQM
[i
]], fr
->shift_vec
[qm
->shiftQM
[i
]], qm
->xQM
[i
]);
220 /* also shift the MM atoms into the central box, if any
222 for (i
= 0; i
< mm
->nrMMatoms
; i
++)
224 rvec_sub(x
[mm
->indexMM
[i
]], fr
->shift_vec
[mm
->shiftMM
[i
]], mm
->xMM
[i
]);
226 } /* update_QMMM_coord */
228 /* end of QMMM subroutines */
230 /* QMMM core routines */
232 static t_QMrec
*mk_QMrec(void)
239 static t_MMrec
*mk_MMrec(void)
246 static void init_QMrec(int grpnr
, t_QMrec
*qm
, int nr
, const int *atomarray
,
247 gmx_mtop_t
*mtop
, t_inputrec
*ir
)
249 /* fills the t_QMrec struct of QM group grpnr
254 snew(qm
->indexQM
, nr
);
255 snew(qm
->shiftQM
, nr
); /* the shifts */
256 for (int i
= 0; i
< nr
; i
++)
258 qm
->indexQM
[i
] = atomarray
[i
];
261 snew(qm
->atomicnumberQM
, nr
);
263 for (int i
= 0; i
< qm
->nrQMatoms
; i
++)
265 const t_atom
&atom
= mtopGetAtomParameters(mtop
, qm
->indexQM
[i
], &molb
);
266 qm
->nelectrons
+= mtop
->atomtypes
.atomnumber
[atom
.type
];
267 qm
->atomicnumberQM
[i
] = mtop
->atomtypes
.atomnumber
[atom
.type
];
270 qm
->QMcharge
= ir
->opts
.QMcharge
[grpnr
];
271 qm
->multiplicity
= ir
->opts
.QMmult
[grpnr
];
272 qm
->nelectrons
-= ir
->opts
.QMcharge
[grpnr
];
274 qm
->QMmethod
= ir
->opts
.QMmethod
[grpnr
];
275 qm
->QMbasis
= ir
->opts
.QMbasis
[grpnr
];
276 /* trajectory surface hopping setup (Gaussian only) */
277 qm
->bSH
= ir
->opts
.bSH
[grpnr
];
278 qm
->CASorbitals
= ir
->opts
.CASorbitals
[grpnr
];
279 qm
->CASelectrons
= ir
->opts
.CASelectrons
[grpnr
];
280 qm
->SAsteps
= ir
->opts
.SAsteps
[grpnr
];
281 qm
->SAon
= ir
->opts
.SAon
[grpnr
];
282 qm
->SAoff
= ir
->opts
.SAoff
[grpnr
];
283 /* hack to prevent gaussian from reinitializing all the time */
284 qm
->nQMcpus
= 0; /* number of CPU's to be used by g01, is set
285 * upon initializing gaussian
288 /* print the current layer to allow users to check their input */
289 fprintf(stderr
, "Layer %d\nnr of QM atoms %d\n", grpnr
, nr
);
290 fprintf(stderr
, "QMlevel: %s/%s\n\n",
291 eQMmethod_names
[qm
->QMmethod
], eQMbasis_names
[qm
->QMbasis
]);
294 static t_QMrec
*copy_QMrec(t_QMrec
*qm
)
296 /* copies the contents of qm into a new t_QMrec struct */
303 qmcopy
->nrQMatoms
= qm
->nrQMatoms
;
304 snew(qmcopy
->xQM
, qmcopy
->nrQMatoms
);
305 snew(qmcopy
->indexQM
, qmcopy
->nrQMatoms
);
306 snew(qmcopy
->atomicnumberQM
, qm
->nrQMatoms
);
307 snew(qmcopy
->shiftQM
, qmcopy
->nrQMatoms
); /* the shifts */
308 for (i
= 0; i
< qmcopy
->nrQMatoms
; i
++)
310 qmcopy
->shiftQM
[i
] = qm
->shiftQM
[i
];
311 qmcopy
->indexQM
[i
] = qm
->indexQM
[i
];
312 qmcopy
->atomicnumberQM
[i
] = qm
->atomicnumberQM
[i
];
314 qmcopy
->nelectrons
= qm
->nelectrons
;
315 qmcopy
->multiplicity
= qm
->multiplicity
;
316 qmcopy
->QMcharge
= qm
->QMcharge
;
317 qmcopy
->nelectrons
= qm
->nelectrons
;
318 qmcopy
->QMmethod
= qm
->QMmethod
;
319 qmcopy
->QMbasis
= qm
->QMbasis
;
320 /* trajectory surface hopping setup (Gaussian only) */
321 qmcopy
->bSH
= qm
->bSH
;
322 qmcopy
->CASorbitals
= qm
->CASorbitals
;
323 qmcopy
->CASelectrons
= qm
->CASelectrons
;
324 qmcopy
->SAsteps
= qm
->SAsteps
;
325 qmcopy
->SAon
= qm
->SAon
;
326 qmcopy
->SAoff
= qm
->SAoff
;
328 /* Gaussian init. variables */
329 qmcopy
->nQMcpus
= qm
->nQMcpus
;
330 for (i
= 0; i
< DIM
; i
++)
332 qmcopy
->SHbasis
[i
] = qm
->SHbasis
[i
];
334 qmcopy
->QMmem
= qm
->QMmem
;
335 qmcopy
->accuracy
= qm
->accuracy
;
336 qmcopy
->cpmcscf
= qm
->cpmcscf
;
337 qmcopy
->SAstep
= qm
->SAstep
;
343 t_QMMMrec
*mk_QMMMrec(void)
354 void init_QMMMrec(const t_commrec
*cr
,
357 const t_forcerec
*fr
)
359 /* we put the atomsnumbers of atoms that belong to the QMMM group in
360 * an array that will be copied later to QMMMrec->indexQM[..]. Also
361 * it will be used to create an QMMMrec->bQMMM index array that
362 * simply contains true/false for QM and MM (the other) atoms.
365 gmx_groups_t
*groups
;
366 int *qm_arr
= nullptr, vsite
, ai
, aj
;
367 int qm_max
= 0, qm_nr
= 0, i
, j
, jmax
, k
, l
, nrvsite2
= 0;
371 gmx_mtop_atomloop_all_t aloop
;
372 gmx_mtop_ilistloop_all_t iloop
;
374 const t_ilist
*ilist_mol
;
376 if (ir
->cutoff_scheme
!= ecutsGROUP
)
378 gmx_fatal(FARGS
, "QMMM is currently only supported with cutoff-scheme=group");
380 if (!EI_DYNAMICS(ir
->eI
))
382 gmx_fatal(FARGS
, "QMMM is only supported with dynamics");
385 /* issue a fatal if the user wants to run with more than one node */
388 gmx_fatal(FARGS
, "QM/MM does not work in parallel, use a single rank instead\n");
391 /* Make a local copy of the QMMMrec */
394 /* bQMMM[..] is an array containing TRUE/FALSE for atoms that are
395 * QM/not QM. We first set all elemenst at false. Afterwards we use
396 * the qm_arr (=MMrec->indexQM) to changes the elements
397 * corresponding to the QM atoms at TRUE. */
399 qr
->QMMMscheme
= ir
->QMMMscheme
;
401 /* we take the possibility into account that a user has
402 * defined more than one QM group:
404 /* an ugly work-around in case there is only one group In this case
405 * the whole system is treated as QM. Otherwise the second group is
406 * always the rest of the total system and is treated as MM.
409 /* small problem if there is only QM.... so no MM */
411 jmax
= ir
->opts
.ngQM
;
413 if (qr
->QMMMscheme
== eQMMMschemeoniom
)
415 qr
->nrQMlayers
= jmax
;
422 groups
= &mtop
->groups
;
424 /* there are jmax groups of QM atoms. In case of multiple QM groups
425 * I assume that the users wants to do ONIOM. However, maybe it
426 * should also be possible to define more than one QM subsystem with
427 * independent neighbourlists. I have to think about
431 for (j
= 0; j
< jmax
; j
++)
434 aloop
= gmx_mtop_atomloop_all_init(mtop
);
436 while (gmx_mtop_atomloop_all_next(aloop
, &i
, &atom
))
441 srenew(qm_arr
, qm_max
);
443 if (ggrpnr(groups
, egcQMMM
, i
) == j
)
449 if (qr
->QMMMscheme
== eQMMMschemeoniom
)
451 /* add the atoms to the bQMMM array
454 /* I assume that users specify the QM groups from small to
455 * big(ger) in the mdp file
457 qr
->qm
[j
] = mk_QMrec();
458 /* we need to throw out link atoms that in the previous layer
459 * existed to separate this QMlayer from the previous
460 * QMlayer. We use the iatoms array in the idef for that
461 * purpose. If all atoms defining the current Link Atom (Dummy2)
462 * are part of the current QM layer it needs to be removed from
465 iloop
= gmx_mtop_ilistloop_all_init(mtop
);
466 while (gmx_mtop_ilistloop_all_next(iloop
, &ilist_mol
, &a_offset
))
468 nrvsite2
= ilist_mol
[F_VSITE2
].nr
;
469 iatoms
= ilist_mol
[F_VSITE2
].iatoms
;
471 for (k
= 0; k
< nrvsite2
; k
+= 4)
473 vsite
= a_offset
+ iatoms
[k
+1]; /* the vsite */
474 ai
= a_offset
+ iatoms
[k
+2]; /* constructing atom */
475 aj
= a_offset
+ iatoms
[k
+3]; /* constructing atom */
476 if (ggrpnr(groups
, egcQMMM
, vsite
) == ggrpnr(groups
, egcQMMM
, ai
)
478 ggrpnr(groups
, egcQMMM
, vsite
) == ggrpnr(groups
, egcQMMM
, aj
))
480 /* this dummy link atom needs to be removed from the qm_arr
481 * before making the QMrec of this layer!
483 for (i
= 0; i
< qm_nr
; i
++)
485 if (qm_arr
[i
] == vsite
)
487 /* drop the element */
488 for (l
= i
; l
< qm_nr
; l
++)
490 qm_arr
[l
] = qm_arr
[l
+1];
499 /* store QM atoms in this layer in the QMrec and initialise layer
501 init_QMrec(j
, qr
->qm
[j
], qm_nr
, qm_arr
, mtop
, ir
);
504 if (qr
->QMMMscheme
!= eQMMMschemeoniom
)
507 /* standard QMMM, all layers are merged together so there is one QM
508 * subsystem and one MM subsystem.
509 * Also we set the charges to zero in mtop to prevent the innerloops
510 * from doubly counting the electostatic QM MM interaction
511 * TODO: Consider doing this in grompp instead.
515 for (k
= 0; k
< qm_nr
; k
++)
518 mtopGetMolblockIndex(mtop
, qm_arr
[k
], &molb
, nullptr, &indexInMolecule
);
519 t_atom
*atom
= &mtop
->moltype
[mtop
->molblock
[molb
].type
].atoms
.atom
[indexInMolecule
];
523 qr
->qm
[0] = mk_QMrec();
524 /* store QM atoms in the QMrec and initialise
526 init_QMrec(0, qr
->qm
[0], qm_nr
, qm_arr
, mtop
, ir
);
528 /* MM rec creation */
530 mm
->scalefactor
= ir
->scalefactor
;
531 mm
->nrMMatoms
= (mtop
->natoms
)-(qr
->qm
[0]->nrQMatoms
); /* rest of the atoms */
535 { /* MM rec creation */
537 mm
->scalefactor
= ir
->scalefactor
;
542 /* these variables get updated in the update QMMMrec */
544 if (qr
->nrQMlayers
== 1)
546 /* with only one layer there is only one initialisation
547 * needed. Multilayer is a bit more complicated as it requires
548 * re-initialisation at every step of the simulation. This is due
549 * to the use of COMMON blocks in the fortran QM subroutines.
551 if (qr
->qm
[0]->QMmethod
< eQMmethodRHF
)
554 /* semi-empiprical 1-layer ONIOM calculation requested (mopac93) */
555 init_mopac(qr
->qm
[0]);
557 gmx_fatal(FARGS
, "Semi-empirical QM only supported with Mopac.");
562 /* ab initio calculation requested (gamess/gaussian/ORCA) */
564 init_gamess(cr
, qr
->qm
[0], qr
->mm
);
565 #elif GMX_QMMM_GAUSSIAN
566 init_gaussian(qr
->qm
[0]);
568 init_orca(qr
->qm
[0]);
570 gmx_fatal(FARGS
, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
576 void update_QMMMrec(const t_commrec
*cr
,
577 const t_forcerec
*fr
,
582 /* updates the coordinates of both QM atoms and MM atoms and stores
583 * them in the QMMMrec.
585 * NOTE: is NOT yet working if there are no PBC. Also in ns.c, simple
586 * ns needs to be fixed!
589 mm_max
= 0, mm_nr
= 0, mm_nr_new
, i
, j
, is
, k
, shift
;
591 *mm_j_particles
= nullptr, *qm_i_particles
= nullptr;
607 *parallelMMarray
= nullptr;
609 /* every cpu has this array. On every processor we fill this array
610 * with 1's and 0's. 1's indicate the atoms is a QM atom on the
611 * current cpu in a later stage these arrays are all summed. indexes
612 * > 0 indicate the atom is a QM atom. Every node therefore knows
613 * whcih atoms are part of the QM subsystem.
615 /* copy some pointers */
618 QMMMlist
= fr
->QMMMlist
;
620 /* init_pbc(box); needs to be called first, see pbc.h */
622 clear_ivec(null_ivec
);
623 set_pbc_dd(&pbc
, fr
->ePBC
, DOMAINDECOMP(cr
) ? cr
->dd
->nc
: null_ivec
,
625 /* only in standard (normal) QMMM we need the neighbouring MM
626 * particles to provide a electric field of point charges for the QM
629 if (qr
->QMMMscheme
== eQMMMschemenormal
) /* also implies 1 QM-layer */
631 /* we NOW create/update a number of QMMMrec entries:
633 * 1) the shiftQM, containing the shifts of the QM atoms
635 * 2) the indexMM array, containing the index of the MM atoms
637 * 3) the shiftMM, containing the shifts of the MM atoms
639 * 4) the shifted coordinates of the MM atoms
641 * the shifts are used for computing virial of the QM/MM particles.
643 qm
= qr
->qm
[0]; /* in case of normal QMMM, there is only one group */
644 snew(qm_i_particles
, QMMMlist
->nri
);
647 qm_i_particles
[0].shift
= XYZ2IS(0, 0, 0);
648 for (i
= 0; i
< QMMMlist
->nri
; i
++)
650 qm_i_particles
[i
].j
= QMMMlist
->iinr
[i
];
654 qm_i_particles
[i
].shift
= pbc_dx_aiuc(&pbc
, x
[QMMMlist
->iinr
[0]],
655 x
[QMMMlist
->iinr
[i
]], dx
);
658 /* However, since nri >= nrQMatoms, we do a quicksort, and throw
659 * out double, triple, etc. entries later, as we do for the MM
663 /* compute the shift for the MM j-particles with respect to
664 * the QM i-particle and store them.
667 crd
[0] = IS2X(QMMMlist
->shift
[i
]) + IS2X(qm_i_particles
[i
].shift
);
668 crd
[1] = IS2Y(QMMMlist
->shift
[i
]) + IS2Y(qm_i_particles
[i
].shift
);
669 crd
[2] = IS2Z(QMMMlist
->shift
[i
]) + IS2Z(qm_i_particles
[i
].shift
);
670 is
= XYZ2IS(crd
[0], crd
[1], crd
[2]);
671 for (j
= QMMMlist
->jindex
[i
];
672 j
< QMMMlist
->jindex
[i
+1];
678 srenew(mm_j_particles
, mm_max
);
681 mm_j_particles
[mm_nr
].j
= QMMMlist
->jjnr
[j
];
682 mm_j_particles
[mm_nr
].shift
= is
;
687 /* quicksort QM and MM shift arrays and throw away multiple entries */
691 std::sort(qm_i_particles
, qm_i_particles
+QMMMlist
->nri
, struct_comp
);
692 /* The mm_j_particles argument to qsort is not allowed to be NULL */
695 std::sort(mm_j_particles
, mm_j_particles
+mm_nr
, struct_comp
);
697 /* remove multiples in the QM shift array, since in init_QMMM() we
698 * went through the atom numbers from 0 to md.nr, the order sorted
699 * here matches the one of QMindex already.
702 for (i
= 0; i
< QMMMlist
->nri
; i
++)
704 if (i
== 0 || qm_i_particles
[i
].j
!= qm_i_particles
[i
-1].j
)
706 qm_i_particles
[j
++] = qm_i_particles
[i
];
710 /* Remove double entries for the MM array.
711 * Also remove mm atoms that have no charges!
712 * actually this is already done in the ns.c
714 for (i
= 0; i
< mm_nr
; i
++)
716 if ((i
== 0 || mm_j_particles
[i
].j
!= mm_j_particles
[i
-1].j
)
717 && !md
->bQM
[mm_j_particles
[i
].j
]
718 && (md
->chargeA
[mm_j_particles
[i
].j
]
719 || (md
->chargeB
&& md
->chargeB
[mm_j_particles
[i
].j
])))
721 mm_j_particles
[mm_nr_new
++] = mm_j_particles
[i
];
725 /* store the data retrieved above into the QMMMrec
728 /* Keep the compiler happy,
729 * shift will always be set in the loop for i=0
732 for (i
= 0; i
< qm
->nrQMatoms
; i
++)
734 /* not all qm particles might have appeared as i
735 * particles. They might have been part of the same charge
736 * group for instance.
738 if (qm
->indexQM
[i
] == qm_i_particles
[k
].j
)
740 shift
= qm_i_particles
[k
++].shift
;
742 /* use previous shift, assuming they belong the same charge
746 qm
->shiftQM
[i
] = shift
;
749 /* parallel excecution */
752 snew(parallelMMarray
, 2*(md
->nr
));
753 /* only MM particles have a 1 at their atomnumber. The second part
754 * of the array contains the shifts. Thus:
755 * p[i]=1/0 depending on wether atomnumber i is a MM particle in the QM
756 * step or not. p[i+md->nr] is the shift of atomnumber i.
758 for (i
= 0; i
< 2*(md
->nr
); i
++)
760 parallelMMarray
[i
] = 0;
763 for (i
= 0; i
< mm_nr
; i
++)
765 parallelMMarray
[mm_j_particles
[i
].j
] = 1;
766 parallelMMarray
[mm_j_particles
[i
].j
+(md
->nr
)] = mm_j_particles
[i
].shift
;
768 gmx_sumi(md
->nr
, parallelMMarray
, cr
);
772 for (i
= 0; i
< md
->nr
; i
++)
774 if (parallelMMarray
[i
])
779 srenew(mm
->indexMM
, mm_max
);
780 srenew(mm
->shiftMM
, mm_max
);
782 mm
->indexMM
[mm_nr
] = i
;
783 mm
->shiftMM
[mm_nr
++] = parallelMMarray
[i
+md
->nr
]/parallelMMarray
[i
];
786 mm
->nrMMatoms
= mm_nr
;
787 free(parallelMMarray
);
789 /* serial execution */
792 mm
->nrMMatoms
= mm_nr
;
793 srenew(mm
->shiftMM
, mm_nr
);
794 srenew(mm
->indexMM
, mm_nr
);
795 for (i
= 0; i
< mm_nr
; i
++)
797 mm
->indexMM
[i
] = mm_j_particles
[i
].j
;
798 mm
->shiftMM
[i
] = mm_j_particles
[i
].shift
;
802 /* (re) allocate memory for the MM coordiate array. The QM
803 * coordinate array was already allocated in init_QMMM, and is
804 * only (re)filled in the update_QMMM_coordinates routine
806 srenew(mm
->xMM
, mm
->nrMMatoms
);
807 /* now we (re) fill the array that contains the MM charges with
808 * the forcefield charges. If requested, these charges will be
811 srenew(mm
->MMcharges
, mm
->nrMMatoms
);
812 for (i
= 0; i
< mm
->nrMMatoms
; i
++) /* no free energy yet */
814 mm
->MMcharges
[i
] = md
->chargeA
[mm
->indexMM
[i
]]*mm
->scalefactor
;
816 /* the next routine fills the coordinate fields in the QMMM rec of
817 * both the qunatum atoms and the MM atoms, using the shifts
821 update_QMMM_coord(x
, fr
, qr
->qm
[0], qr
->mm
);
822 free(qm_i_particles
);
823 free(mm_j_particles
);
825 else /* ONIOM */ /* ????? */
828 /* do for each layer */
829 for (j
= 0; j
< qr
->nrQMlayers
; j
++)
832 qm
->shiftQM
[0] = XYZ2IS(0, 0, 0);
833 for (i
= 1; i
< qm
->nrQMatoms
; i
++)
835 qm
->shiftQM
[i
] = pbc_dx_aiuc(&pbc
, x
[qm
->indexQM
[0]], x
[qm
->indexQM
[i
]],
838 update_QMMM_coord(x
, fr
, qm
, mm
);
841 } /* update_QMMM_rec */
843 real
calculate_QMMM(const t_commrec
*cr
,
845 const t_forcerec
*fr
)
849 /* a selection for the QM package depending on which is requested
850 * (Gaussian, GAMESS-UK, MOPAC or ORCA) needs to be implemented here. Now
851 * it works through defines.... Not so nice yet
860 *forces
= nullptr, *fshift
= nullptr,
861 *forces2
= nullptr, *fshift2
= nullptr; /* needed for multilayer ONIOM */
864 /* make a local copy the QMMMrec pointer
869 /* now different procedures are carried out for one layer ONION and
870 * normal QMMM on one hand and multilayer oniom on the other
872 if (qr
->QMMMscheme
== eQMMMschemenormal
|| qr
->nrQMlayers
== 1)
875 snew(forces
, (qm
->nrQMatoms
+mm
->nrMMatoms
));
876 snew(fshift
, (qm
->nrQMatoms
+mm
->nrMMatoms
));
877 QMener
= call_QMroutine(cr
, fr
, qm
, mm
, forces
, fshift
);
878 for (i
= 0; i
< qm
->nrQMatoms
; i
++)
880 for (j
= 0; j
< DIM
; j
++)
882 f
[qm
->indexQM
[i
]][j
] -= forces
[i
][j
];
883 fr
->fshift
[qm
->shiftQM
[i
]][j
] += fshift
[i
][j
];
886 for (i
= 0; i
< mm
->nrMMatoms
; i
++)
888 for (j
= 0; j
< DIM
; j
++)
890 f
[mm
->indexMM
[i
]][j
] -= forces
[qm
->nrQMatoms
+i
][j
];
891 fr
->fshift
[mm
->shiftMM
[i
]][j
] += fshift
[qm
->nrQMatoms
+i
][j
];
898 else /* Multi-layer ONIOM */
900 for (i
= 0; i
< qr
->nrQMlayers
-1; i
++) /* last layer is special */
903 qm2
= copy_QMrec(qr
->qm
[i
+1]);
905 qm2
->nrQMatoms
= qm
->nrQMatoms
;
907 for (j
= 0; j
< qm2
->nrQMatoms
; j
++)
909 for (k
= 0; k
< DIM
; k
++)
911 qm2
->xQM
[j
][k
] = qm
->xQM
[j
][k
];
913 qm2
->indexQM
[j
] = qm
->indexQM
[j
];
914 qm2
->atomicnumberQM
[j
] = qm
->atomicnumberQM
[j
];
915 qm2
->shiftQM
[j
] = qm
->shiftQM
[j
];
918 qm2
->QMcharge
= qm
->QMcharge
;
919 /* this layer at the higher level of theory */
920 srenew(forces
, qm
->nrQMatoms
);
921 srenew(fshift
, qm
->nrQMatoms
);
922 /* we need to re-initialize the QMroutine every step... */
923 init_QMroutine(cr
, qm
, mm
);
924 QMener
+= call_QMroutine(cr
, fr
, qm
, mm
, forces
, fshift
);
926 /* this layer at the lower level of theory */
927 srenew(forces2
, qm
->nrQMatoms
);
928 srenew(fshift2
, qm
->nrQMatoms
);
929 init_QMroutine(cr
, qm2
, mm
);
930 QMener
-= call_QMroutine(cr
, fr
, qm2
, mm
, forces2
, fshift2
);
931 /* E = E1high-E1low The next layer includes the current layer at
932 * the lower level of theory, which provides + E2low
933 * this is similar for gradients
935 for (i
= 0; i
< qm
->nrQMatoms
; i
++)
937 for (j
= 0; j
< DIM
; j
++)
939 f
[qm
->indexQM
[i
]][j
] -= (forces
[i
][j
]-forces2
[i
][j
]);
940 fr
->fshift
[qm
->shiftQM
[i
]][j
] += (fshift
[i
][j
]-fshift2
[i
][j
]);
945 /* now the last layer still needs to be done: */
946 qm
= qr
->qm
[qr
->nrQMlayers
-1]; /* C counts from 0 */
947 init_QMroutine(cr
, qm
, mm
);
948 srenew(forces
, qm
->nrQMatoms
);
949 srenew(fshift
, qm
->nrQMatoms
);
950 QMener
+= call_QMroutine(cr
, fr
, qm
, mm
, forces
, fshift
);
951 for (i
= 0; i
< qm
->nrQMatoms
; i
++)
953 for (j
= 0; j
< DIM
; j
++)
955 f
[qm
->indexQM
[i
]][j
] -= forces
[i
][j
];
956 fr
->fshift
[qm
->shiftQM
[i
]][j
] += fshift
[i
][j
];
965 } /* calculate_QMMM */
967 real
calculate_QMMM(const t_commrec
* /*unused*/,
969 const t_forcerec
* /*unused*/)
971 gmx_incons("Compiled without QMMM");
973 t_QMMMrec
*mk_QMMMrec()
977 void init_QMMMrec(const t_commrec
* /*unused*/,
978 gmx_mtop_t
* /*unused*/,
979 t_inputrec
* /*unused*/,
980 const t_forcerec
* /*unused*/)
982 gmx_incons("Compiled without QMMM");
984 void update_QMMMrec(const t_commrec
* /*unused*/,
985 const t_forcerec
* /*unused*/,
986 const rvec
* /*unused*/,
987 const t_mdatoms
* /*unused*/,
988 const matrix
/*unused*/)
990 gmx_incons("Compiled without QMMM");
994 /* end of QMMM core routines */