clang-tidy modernize
[gromacs.git] / src / gromacs / mdlib / qmmm.cpp
blob5729274be1687ea9a4662a01559f6e24b20c77fd
1 /*
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.
37 #include "gmxpre.h"
39 #include "qmmm.h"
41 #include "config.h"
43 #include <cmath>
44 #include <cstdio>
45 #include <cstdlib>
46 #include <cstring>
48 #include <algorithm>
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
75 #if GMX_QMMM_GAMESS
76 /* GAMESS interface */
78 void
79 init_gamess(const t_commrec *cr, t_QMrec *qm, t_MMrec *mm);
81 real
82 call_gamess(const t_forcerec *fr,
83 t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]);
85 #elif GMX_QMMM_MOPAC
86 /* MOPAC interface */
88 void
89 init_mopac(t_QMrec *qm);
91 real
92 call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]);
94 real
95 call_mopac_SH(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]);
97 #elif GMX_QMMM_GAUSSIAN
98 /* GAUSSIAN interface */
100 void
101 init_gaussian(t_QMrec *qm);
103 real
104 call_gaussian_SH(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]);
106 real
107 call_gaussian(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]);
109 #elif GMX_QMMM_ORCA
110 #include "gromacs/mdlib/qm_orca.h"
111 #endif
113 #if GMX_QMMM
114 /* this struct and these comparison functions are needed for creating
115 * a QMMM input for the QM routines from the QMMM neighbor list.
118 typedef struct {
119 int j;
120 int shift;
121 } t_j_particle;
123 static bool struct_comp(const t_j_particle &a, const t_j_particle &b)
125 return a.j < b.j;
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))
138 #if GMX_QMMM_MOPAC
139 if (qm->bSH)
141 return call_mopac_SH(qm, mm, f, fshift);
143 else
145 return call_mopac(qm, mm, f, fshift);
147 #else
148 gmx_fatal(FARGS, "Semi-empirical QM only supported with Mopac.");
149 #endif
151 else
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);
158 #else
159 gmx_fatal(FARGS, "Ab-initio Surface-hopping only supported with Gaussian.");
160 #endif
162 else
164 #if GMX_QMMM_GAMESS
165 return call_gamess(fr, qm, mm, f, fshift);
166 #elif GMX_QMMM_GAUSSIAN
167 return call_gaussian(fr, qm, mm, f, fshift);
168 #elif GMX_QMMM_ORCA
169 return call_orca(fr, qm, mm, f, fshift);
170 #else
171 gmx_fatal(FARGS, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
172 #endif
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)
183 #if GMX_QMMM_MOPAC
184 /* do a semi-empiprical calculation */
185 init_mopac(qm);
186 #else
187 gmx_fatal(FARGS, "Semi-empirical QM only supported with Mopac.");
188 #endif
190 else
192 /* do an ab-initio calculation */
193 #if GMX_QMMM_GAMESS
194 init_gamess(cr, qm, mm);
195 #elif GMX_QMMM_GAUSSIAN
196 init_gaussian(qm);
197 #elif GMX_QMMM_ORCA
198 init_orca(qm);
199 #else
200 gmx_fatal(FARGS, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
201 #endif
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)
234 t_QMrec *qm;
235 snew(qm, 1);
236 return qm;
237 } /* mk_QMrec */
239 static t_MMrec *mk_MMrec(void)
241 t_MMrec *mm;
242 snew(mm, 1);
243 return mm;
244 } /* mk_MMrec */
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
252 qm->nrQMatoms = nr;
253 snew(qm->xQM, nr);
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);
262 int molb = 0;
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
286 * (init_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]);
292 } /* init_QMrec */
294 static t_QMrec *copy_QMrec(t_QMrec *qm)
296 /* copies the contents of qm into a new t_QMrec struct */
297 t_QMrec
298 *qmcopy;
302 qmcopy = mk_QMrec();
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;
339 return(qmcopy);
341 } /*copy_QMrec */
343 t_QMMMrec *mk_QMMMrec(void)
346 t_QMMMrec *qr;
348 snew(qr, 1);
350 return qr;
352 } /* mk_QMMMrec */
354 void init_QMMMrec(const t_commrec *cr,
355 gmx_mtop_t *mtop,
356 t_inputrec *ir,
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;
368 t_QMMMrec *qr;
369 t_MMrec *mm;
370 t_iatom *iatoms;
371 gmx_mtop_atomloop_all_t aloop;
372 gmx_mtop_ilistloop_all_t iloop;
373 int a_offset;
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 */
386 if (PAR(cr))
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 */
392 qr = fr->qr;
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;
417 else
419 qr->nrQMlayers = 1;
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
428 * that.. 11-11-2003
430 snew(qr->qm, jmax);
431 for (j = 0; j < jmax; j++)
433 /* new layer */
434 aloop = gmx_mtop_atomloop_all_init(mtop);
435 const t_atom *atom;
436 while (gmx_mtop_atomloop_all_next(aloop, &i, &atom))
438 if (qm_nr >= qm_max)
440 qm_max += 1000;
441 srenew(qm_arr, qm_max);
443 if (ggrpnr(groups, egcQMMM, i) == j)
445 /* hack for tip4p */
446 qm_arr[qm_nr++] = i;
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
463 * qm_arr[]. */
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];
492 qm_nr--;
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.
514 int molb = 0;
515 for (k = 0; k < qm_nr; k++)
517 int indexInMolecule;
518 mtopGetMolblockIndex(mtop, qm_arr[k], &molb, nullptr, &indexInMolecule);
519 t_atom *atom = &mtop->moltype[mtop->molblock[molb].type].atoms.atom[indexInMolecule];
520 atom->q = 0.0;
521 atom->qB = 0.0;
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 */
529 mm = mk_MMrec();
530 mm->scalefactor = ir->scalefactor;
531 mm->nrMMatoms = (mtop->natoms)-(qr->qm[0]->nrQMatoms); /* rest of the atoms */
532 qr->mm = mm;
534 else /* ONIOM */
535 { /* MM rec creation */
536 mm = mk_MMrec();
537 mm->scalefactor = ir->scalefactor;
538 mm->nrMMatoms = 0;
539 qr->mm = mm;
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)
553 #if GMX_QMMM_MOPAC
554 /* semi-empiprical 1-layer ONIOM calculation requested (mopac93) */
555 init_mopac(qr->qm[0]);
556 #else
557 gmx_fatal(FARGS, "Semi-empirical QM only supported with Mopac.");
558 #endif
560 else
562 /* ab initio calculation requested (gamess/gaussian/ORCA) */
563 #if GMX_QMMM_GAMESS
564 init_gamess(cr, qr->qm[0], qr->mm);
565 #elif GMX_QMMM_GAUSSIAN
566 init_gaussian(qr->qm[0]);
567 #elif GMX_QMMM_ORCA
568 init_orca(qr->qm[0]);
569 #else
570 gmx_fatal(FARGS, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA.");
571 #endif
574 } /* init_QMMMrec */
576 void update_QMMMrec(const t_commrec *cr,
577 const t_forcerec *fr,
578 const rvec *x,
579 const t_mdatoms *md,
580 const matrix box)
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;
590 t_j_particle
591 *mm_j_particles = nullptr, *qm_i_particles = nullptr;
592 t_QMMMrec
593 *qr;
594 t_nblist
595 *QMMMlist;
596 rvec
598 ivec
599 crd;
600 t_QMrec
601 *qm;
602 t_MMrec
603 *mm;
604 t_pbc
605 pbc;
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 */
616 qr = fr->qr;
617 mm = qr->mm;
618 QMMMlist = fr->QMMMlist;
620 /* init_pbc(box); needs to be called first, see pbc.h */
621 ivec null_ivec;
622 clear_ivec(null_ivec);
623 set_pbc_dd(&pbc, fr->ePBC, DOMAINDECOMP(cr) ? cr->dd->nc : null_ivec,
624 FALSE, box);
625 /* only in standard (normal) QMMM we need the neighbouring MM
626 * particles to provide a electric field of point charges for the QM
627 * atoms.
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);
645 if (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];
652 if (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
660 * list too.
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];
673 j++)
675 if (mm_nr >= mm_max)
677 mm_max += 1000;
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;
683 mm_nr++;
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 */
693 if (mm_nr > 0)
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.
701 j = 0;
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];
709 mm_nr_new = 0;
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];
724 mm_nr = mm_nr_new;
725 /* store the data retrieved above into the QMMMrec
727 k = 0;
728 /* Keep the compiler happy,
729 * shift will always be set in the loop for i=0
731 shift = 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
743 * group anyway,
746 qm->shiftQM[i] = shift;
749 /* parallel excecution */
750 if (PAR(cr))
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);
769 mm_nr = 0;
771 mm_max = 0;
772 for (i = 0; i < md->nr; i++)
774 if (parallelMMarray[i])
776 if (mm_nr >= mm_max)
778 mm_max += 1000;
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 */
790 else
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
809 * scaled by a factor
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
818 * calculated above.
821 update_QMMM_coord(x, fr, qr->qm[0], qr->mm);
822 free(qm_i_particles);
823 free(mm_j_particles);
825 else /* ONIOM */ /* ????? */
827 mm->nrMMatoms = 0;
828 /* do for each layer */
829 for (j = 0; j < qr->nrQMlayers; j++)
831 qm = qr->qm[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]],
836 dx);
838 update_QMMM_coord(x, fr, qm, mm);
841 } /* update_QMMM_rec */
843 real calculate_QMMM(const t_commrec *cr,
844 rvec f[],
845 const t_forcerec *fr)
847 real
848 QMener = 0.0;
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
853 t_QMMMrec
854 *qr;
855 t_QMrec
856 *qm, *qm2;
857 t_MMrec
858 *mm = nullptr;
859 rvec
860 *forces = nullptr, *fshift = nullptr,
861 *forces2 = nullptr, *fshift2 = nullptr; /* needed for multilayer ONIOM */
863 i, j, k;
864 /* make a local copy the QMMMrec pointer
866 qr = fr->qr;
867 mm = qr->mm;
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)
874 qm = qr->qm[0];
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];
895 free(forces);
896 free(fshift);
898 else /* Multi-layer ONIOM */
900 for (i = 0; i < qr->nrQMlayers-1; i++) /* last layer is special */
902 qm = qr->qm[i];
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]);
943 free(qm2);
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];
959 free(forces);
960 free(fshift);
961 free(forces2);
962 free(fshift2);
964 return(QMener);
965 } /* calculate_QMMM */
966 #else
967 real calculate_QMMM(const t_commrec * /*unused*/,
968 rvec * /*unused*/,
969 const t_forcerec * /*unused*/)
971 gmx_incons("Compiled without QMMM");
973 t_QMMMrec *mk_QMMMrec()
975 return nullptr;
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");
992 #endif
994 /* end of QMMM core routines */