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,2019, 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.
52 #include <unordered_set>
53 #include <sys/types.h>
55 #include "gromacs/fileio/gmxfio.h"
56 #include "gromacs/fileio/warninp.h"
57 #include "gromacs/gmxpreprocess/gmxcpp.h"
58 #include "gromacs/gmxpreprocess/gpp_atomtype.h"
59 #include "gromacs/gmxpreprocess/gpp_bond_atomtype.h"
60 #include "gromacs/gmxpreprocess/gpp_nextnb.h"
61 #include "gromacs/gmxpreprocess/grompp_impl.h"
62 #include "gromacs/gmxpreprocess/readir.h"
63 #include "gromacs/gmxpreprocess/topdirs.h"
64 #include "gromacs/gmxpreprocess/toppush.h"
65 #include "gromacs/gmxpreprocess/topshake.h"
66 #include "gromacs/gmxpreprocess/toputil.h"
67 #include "gromacs/gmxpreprocess/vsite_parm.h"
68 #include "gromacs/math/units.h"
69 #include "gromacs/math/utilities.h"
70 #include "gromacs/mdtypes/inputrec.h"
71 #include "gromacs/mdtypes/md_enums.h"
72 #include "gromacs/pbcutil/pbc.h"
73 #include "gromacs/topology/block.h"
74 #include "gromacs/topology/exclusionblocks.h"
75 #include "gromacs/topology/ifunc.h"
76 #include "gromacs/topology/symtab.h"
77 #include "gromacs/topology/topology.h"
78 #include "gromacs/utility/cstringutil.h"
79 #include "gromacs/utility/fatalerror.h"
80 #include "gromacs/utility/futil.h"
81 #include "gromacs/utility/gmxassert.h"
82 #include "gromacs/utility/pleasecite.h"
83 #include "gromacs/utility/smalloc.h"
85 #define OPENDIR '[' /* starting sign for directive */
86 #define CLOSEDIR ']' /* ending sign for directive */
88 static void gen_pairs(const InteractionsOfType
&nbs
, InteractionsOfType
*pairs
, real fudge
, int comb
)
92 int nnn
= static_cast<int>(std::sqrt(static_cast<double>(ntp
)));
93 GMX_ASSERT(nnn
* nnn
== ntp
, "Number of pairs of generated non-bonded parameters should be a perfect square");
94 int nrfp
= NRFP(F_LJ
);
95 int nrfpA
= interaction_function
[F_LJ14
].nrfpA
;
96 int nrfpB
= interaction_function
[F_LJ14
].nrfpB
;
98 if ((nrfp
!= nrfpA
) || (nrfpA
!= nrfpB
))
100 gmx_incons("Number of force parameters in gen_pairs wrong");
103 fprintf(stderr
, "Generating 1-4 interactions: fudge = %g\n", fudge
);
104 pairs
->interactionTypes
.clear();
106 std::array
<int, 2> atomNumbers
;
107 std::array
<real
, MAXFORCEPARAM
> forceParam
= {NOTSET
};
108 for (const auto &type
: nbs
.interactionTypes
)
110 /* Copy type.atoms */
111 atomNumbers
= {i
/ nnn
, i
% nnn
};
112 /* Copy normal and FEP parameters and multiply by fudge factor */
113 gmx::ArrayRef
<const real
> existingParam
= type
.forceParam();
114 GMX_RELEASE_ASSERT(2*nrfp
<= MAXFORCEPARAM
, "Can't have more parameters than half of maximum p arameter number");
115 for (int j
= 0; j
< nrfp
; j
++)
117 /* If we are using sigma/epsilon values, only the epsilon values
118 * should be scaled, but not sigma.
119 * The sigma values have even indices 0,2, etc.
121 if ((comb
== eCOMB_ARITHMETIC
|| comb
== eCOMB_GEOM_SIG_EPS
) && (j
%2 == 0))
130 forceParam
[j
] = scaling
*existingParam
[j
];
131 forceParam
[nrfp
+j
] = scaling
*existingParam
[j
];
133 pairs
->interactionTypes
.emplace_back(InteractionOfType(atomNumbers
, forceParam
));
138 double check_mol(const gmx_mtop_t
*mtop
, warninp
*wi
)
145 /* Check mass and charge */
148 for (const gmx_molblock_t
&molb
: mtop
->molblock
)
150 const t_atoms
*atoms
= &mtop
->moltype
[molb
.type
].atoms
;
151 for (i
= 0; (i
< atoms
->nr
); i
++)
153 q
+= molb
.nmol
*atoms
->atom
[i
].q
;
154 m
= atoms
->atom
[i
].m
;
155 mB
= atoms
->atom
[i
].mB
;
156 pt
= atoms
->atom
[i
].ptype
;
157 /* If the particle is an atom or a nucleus it must have a mass,
158 * else, if it is a shell, a vsite or a bondshell it can have mass zero
160 if (((m
<= 0.0) || (mB
<= 0.0)) && ((pt
== eptAtom
) || (pt
== eptNucleus
)))
162 ri
= atoms
->atom
[i
].resind
;
163 sprintf(buf
, "atom %s (Res %s-%d) has mass %g (state A) / %g (state B)\n",
164 *(atoms
->atomname
[i
]),
165 *(atoms
->resinfo
[ri
].name
),
166 atoms
->resinfo
[ri
].nr
,
168 warning_error(wi
, buf
);
171 if (((m
!= 0) || (mB
!= 0)) && (pt
== eptVSite
))
173 ri
= atoms
->atom
[i
].resind
;
174 sprintf(buf
, "virtual site %s (Res %s-%d) has non-zero mass %g (state A) / %g (state B)\n"
175 " Check your topology.\n",
176 *(atoms
->atomname
[i
]),
177 *(atoms
->resinfo
[ri
].name
),
178 atoms
->resinfo
[ri
].nr
,
180 warning_error(wi
, buf
);
181 /* The following statements make LINCS break! */
182 /* atoms->atom[i].m=0; */
189 /*! \brief Returns the rounded charge of a molecule, when close to integer, otherwise returns the original charge.
191 * The results of this routine are only used for checking and for
192 * printing warning messages. Thus we can assume that charges of molecules
193 * should be integer. If the user wanted non-integer molecular charge,
194 * an undesired warning is printed and the user should use grompp -maxwarn 1.
196 * \param qMol The total, unrounded, charge of the molecule
197 * \param sumAbsQ The sum of absolute values of the charges, used for determining the tolerance for the rounding.
199 static double roundedMoleculeCharge(double qMol
, double sumAbsQ
)
201 /* We use a tolerance of 1e-6 for inaccuracies beyond the 6th decimal
202 * of the charges for ascii float truncation in the topology files.
203 * Although the summation here uses double precision, the charges
204 * are read and stored in single precision when real=float. This can
205 * lead to rounding errors of half the least significant bit.
206 * Note that, unfortunately, we can not assume addition of random
207 * rounding errors. It is not entirely unlikely that many charges
208 * have a near half-bit rounding error with the same sign.
210 double tolAbs
= 1e-6;
211 double tol
= std::max(tolAbs
, 0.5*GMX_REAL_EPS
*sumAbsQ
);
212 double qRound
= std::round(qMol
);
213 if (std::abs(qMol
- qRound
) <= tol
)
223 static void sum_q(const t_atoms
*atoms
, int numMols
,
224 double *qTotA
, double *qTotB
)
231 for (int i
= 0; i
< atoms
->nr
; i
++)
233 qmolA
+= atoms
->atom
[i
].q
;
234 qmolB
+= atoms
->atom
[i
].qB
;
235 sumAbsQA
+= std::abs(atoms
->atom
[i
].q
);
236 sumAbsQB
+= std::abs(atoms
->atom
[i
].qB
);
239 *qTotA
+= numMols
*roundedMoleculeCharge(qmolA
, sumAbsQA
);
240 *qTotB
+= numMols
*roundedMoleculeCharge(qmolB
, sumAbsQB
);
243 static void get_nbparm(char *nb_str
, char *comb_str
, int *nb
, int *comb
,
247 char warn_buf
[STRLEN
];
250 for (i
= 1; (i
< eNBF_NR
); i
++)
252 if (gmx_strcasecmp(nb_str
, enbf_names
[i
]) == 0)
259 *nb
= strtol(nb_str
, nullptr, 10);
261 if ((*nb
< 1) || (*nb
>= eNBF_NR
))
263 sprintf(warn_buf
, "Invalid nonbond function selector '%s' using %s",
264 nb_str
, enbf_names
[1]);
265 warning_error(wi
, warn_buf
);
269 for (i
= 1; (i
< eCOMB_NR
); i
++)
271 if (gmx_strcasecmp(comb_str
, ecomb_names
[i
]) == 0)
278 *comb
= strtol(comb_str
, nullptr, 10);
280 if ((*comb
< 1) || (*comb
>= eCOMB_NR
))
282 sprintf(warn_buf
, "Invalid combination rule selector '%s' using %s",
283 comb_str
, ecomb_names
[1]);
284 warning_error(wi
, warn_buf
);
289 static char ** cpp_opts(const char *define
, const char *include
,
294 const char *cppadds
[2];
295 char **cppopts
= nullptr;
296 const char *option
[2] = { "-D", "-I" };
297 const char *nopt
[2] = { "define", "include" };
301 char warn_buf
[STRLEN
];
304 cppadds
[1] = include
;
305 for (n
= 0; (n
< 2); n
++)
312 while ((*ptr
!= '\0') && isspace(*ptr
))
317 while ((*rptr
!= '\0') && !isspace(*rptr
))
325 strncpy(buf
, ptr
, len
);
326 if (strstr(ptr
, option
[n
]) != ptr
)
328 set_warning_line(wi
, "mdp file", -1);
329 sprintf(warn_buf
, "Malformed %s option %s", nopt
[n
], buf
);
330 warning(wi
, warn_buf
);
334 srenew(cppopts
, ++ncppopts
);
335 cppopts
[ncppopts
-1] = gmx_strdup(buf
);
343 srenew(cppopts
, ++ncppopts
);
344 cppopts
[ncppopts
-1] = nullptr;
350 static void make_atoms_sys(gmx::ArrayRef
<const gmx_molblock_t
> molblock
,
351 gmx::ArrayRef
<const MoleculeInformation
> molinfo
,
355 atoms
->atom
= nullptr;
357 for (const gmx_molblock_t
&molb
: molblock
)
359 const t_atoms
&mol_atoms
= molinfo
[molb
.type
].atoms
;
361 srenew(atoms
->atom
, atoms
->nr
+ molb
.nmol
*mol_atoms
.nr
);
363 for (int m
= 0; m
< molb
.nmol
; m
++)
365 for (int a
= 0; a
< mol_atoms
.nr
; a
++)
367 atoms
->atom
[atoms
->nr
++] = mol_atoms
.atom
[a
];
374 static char **read_topol(const char *infile
, const char *outfile
,
375 const char *define
, const char *include
,
377 PreprocessingAtomTypes
*atypes
,
378 std::vector
<MoleculeInformation
> *molinfo
,
379 std::unique_ptr
<MoleculeInformation
> *intermolecular_interactions
,
380 gmx::ArrayRef
<InteractionsOfType
> interactions
,
381 int *combination_rule
,
385 std::vector
<gmx_molblock_t
> *molblock
,
386 bool *ffParametrizedWithHBondConstraints
,
389 bool usingFullRangeElectrostatics
,
394 char *pline
= nullptr, **title
= nullptr;
395 char line
[STRLEN
], errbuf
[256], comb_str
[256], nb_str
[256];
397 char *dirstr
, *dummy2
;
398 int nrcopies
, nscan
, ncombs
, ncopy
;
399 double fLJ
, fQQ
, fPOW
;
400 MoleculeInformation
*mi0
= nullptr;
403 t_nbparam
**nbparam
, **pair
;
404 real fudgeLJ
= -1; /* Multiplication factor to generate 1-4 from LJ */
405 bool bReadDefaults
, bReadMolType
, bGenPairs
, bWarn_copy_A_B
;
406 double qt
= 0, qBt
= 0; /* total charge */
407 int dcatt
= -1, nmol_couple
;
408 /* File handling variables */
412 char *tmp_line
= nullptr;
413 char warn_buf
[STRLEN
];
414 const char *floating_point_arithmetic_tip
=
415 "Total charge should normally be an integer. See\n"
416 "http://www.gromacs.org/Documentation/Floating_Point_Arithmetic\n"
417 "for discussion on how close it should be to an integer.\n";
418 /* We need to open the output file before opening the input file,
419 * because cpp_open_file can change the current working directory.
423 out
= gmx_fio_fopen(outfile
, "w");
430 /* open input file */
431 auto cpp_opts_return
= cpp_opts(define
, include
, wi
);
432 status
= cpp_open_file(infile
, &handle
, cpp_opts_return
);
435 gmx_fatal(FARGS
, "%s", cpp_error(&handle
, status
));
438 /* some local variables */
439 DS_Init(&DS
); /* directive stack */
440 d
= Directive::d_invalid
; /* first thing should be a directive */
441 nbparam
= nullptr; /* The temporary non-bonded matrix */
442 pair
= nullptr; /* The temporary pair interaction matrix */
443 std::vector
< std::vector
< gmx::ExclusionBlock
>> exclusionBlocks
;
446 *reppow
= 12.0; /* Default value for repulsion power */
448 /* Init the number of CMAP torsion angles and grid spacing */
449 interactions
[F_CMAP
].cmakeGridSpacing
= 0;
450 interactions
[F_CMAP
].cmapAngles
= 0;
452 bWarn_copy_A_B
= bFEP
;
454 PreprocessingBondAtomType bondAtomType
;
455 /* parse the actual file */
456 bReadDefaults
= FALSE
;
458 bReadMolType
= FALSE
;
463 status
= cpp_read_line(&handle
, STRLEN
, line
);
464 done
= (status
== eCPP_EOF
);
467 if (status
!= eCPP_OK
)
469 gmx_fatal(FARGS
, "%s", cpp_error(&handle
, status
));
473 fprintf(out
, "%s\n", line
);
476 set_warning_line(wi
, cpp_cur_file(&handle
), cpp_cur_linenr(&handle
));
478 pline
= gmx_strdup(line
);
480 /* Strip trailing '\' from pline, if it exists */
482 if ((sl
> 0) && (pline
[sl
-1] == CONTINUE
))
487 /* build one long line from several fragments - necessary for CMAP */
488 while (continuing(line
))
490 status
= cpp_read_line(&handle
, STRLEN
, line
);
491 set_warning_line(wi
, cpp_cur_file(&handle
), cpp_cur_linenr(&handle
));
493 /* Since we depend on the '\' being present to continue to read, we copy line
494 * to a tmp string, strip the '\' from that string, and cat it to pline
496 tmp_line
= gmx_strdup(line
);
498 sl
= strlen(tmp_line
);
499 if ((sl
> 0) && (tmp_line
[sl
-1] == CONTINUE
))
501 tmp_line
[sl
-1] = ' ';
504 done
= (status
== eCPP_EOF
);
507 if (status
!= eCPP_OK
)
509 gmx_fatal(FARGS
, "%s", cpp_error(&handle
, status
));
513 fprintf(out
, "%s\n", line
);
517 srenew(pline
, strlen(pline
)+strlen(tmp_line
)+1);
518 strcat(pline
, tmp_line
);
522 /* skip trailing and leading spaces and comment text */
523 strip_comment (pline
);
526 /* if there is something left... */
527 if (static_cast<int>(strlen(pline
)) > 0)
529 if (pline
[0] == OPENDIR
)
531 /* A directive on this line: copy the directive
532 * without the brackets into dirstr, then
533 * skip spaces and tabs on either side of directive
535 dirstr
= gmx_strdup((pline
+1));
536 if ((dummy2
= strchr (dirstr
, CLOSEDIR
)) != nullptr)
542 if ((newd
= str2dir(dirstr
)) == Directive::d_invalid
)
544 sprintf(errbuf
, "Invalid directive %s", dirstr
);
545 warning_error(wi
, errbuf
);
549 /* Directive found */
550 if (DS_Check_Order (DS
, newd
))
557 /* we should print here which directives should have
558 been present, and which actually are */
559 gmx_fatal(FARGS
, "%s\nInvalid order for directive %s",
560 cpp_error(&handle
, eCPP_SYNTAX
), dir2str(newd
));
561 /* d = Directive::d_invalid; */
564 if (d
== Directive::d_intermolecular_interactions
)
566 if (*intermolecular_interactions
== nullptr)
568 /* We (mis)use the moleculetype processing
569 * to process the intermolecular interactions
570 * by making a "molecule" of the size of the system.
572 *intermolecular_interactions
= std::make_unique
<MoleculeInformation
>( );
573 mi0
= intermolecular_interactions
->get();
575 make_atoms_sys(*molblock
, *molinfo
,
582 else if (d
!= Directive::d_invalid
)
584 /* Not a directive, just a plain string
585 * use a gigantic switch to decode,
586 * if there is a valid directive!
590 case Directive::d_defaults
:
593 gmx_fatal(FARGS
, "%s\nFound a second defaults directive.\n",
594 cpp_error(&handle
, eCPP_SYNTAX
));
596 bReadDefaults
= TRUE
;
597 nscan
= sscanf(pline
, "%s%s%s%lf%lf%lf",
598 nb_str
, comb_str
, genpairs
, &fLJ
, &fQQ
, &fPOW
);
609 get_nbparm(nb_str
, comb_str
, &nb_funct
, combination_rule
, wi
);
612 bGenPairs
= (gmx::equalCaseInsensitive(genpairs
, "Y", 1));
613 if (nb_funct
!= eNBF_LJ
&& bGenPairs
)
615 gmx_fatal(FARGS
, "Generating pair parameters is only supported with LJ non-bonded interactions");
631 nb_funct
= ifunc_index(Directive::d_nonbond_params
, nb_funct
);
634 case Directive::d_atomtypes
:
635 push_at(symtab
, atypes
, &bondAtomType
, pline
, nb_funct
,
636 &nbparam
, bGenPairs
? &pair
: nullptr, wi
);
639 case Directive::d_bondtypes
:
640 push_bt(d
, interactions
, 2, nullptr, &bondAtomType
, pline
, wi
);
642 case Directive::d_constrainttypes
:
643 push_bt(d
, interactions
, 2, nullptr, &bondAtomType
, pline
, wi
);
645 case Directive::d_pairtypes
:
648 push_nbt(d
, pair
, atypes
, pline
, F_LJ14
, wi
);
652 push_bt(d
, interactions
, 2, atypes
, nullptr, pline
, wi
);
655 case Directive::d_angletypes
:
656 push_bt(d
, interactions
, 3, nullptr, &bondAtomType
, pline
, wi
);
658 case Directive::d_dihedraltypes
:
659 /* Special routine that can read both 2 and 4 atom dihedral definitions. */
660 push_dihedraltype(d
, interactions
, &bondAtomType
, pline
, wi
);
663 case Directive::d_nonbond_params
:
664 push_nbt(d
, nbparam
, atypes
, pline
, nb_funct
, wi
);
667 case Directive::d_implicit_genborn_params
:
668 // Skip this line, so old topologies with
669 // GB parameters can be read.
672 case Directive::d_implicit_surface_params
:
673 // Skip this line, so that any topologies
674 // with surface parameters can be read
675 // (even though these were never formally
679 case Directive::d_cmaptypes
:
680 push_cmaptype(d
, interactions
, 5, atypes
, &bondAtomType
, pline
, wi
);
683 case Directive::d_moleculetype
:
688 if (opts
->couple_moltype
!= nullptr &&
689 (opts
->couple_lam0
== ecouplamNONE
||
690 opts
->couple_lam0
== ecouplamQ
||
691 opts
->couple_lam1
== ecouplamNONE
||
692 opts
->couple_lam1
== ecouplamQ
))
694 dcatt
= add_atomtype_decoupled(symtab
, atypes
,
695 &nbparam
, bGenPairs
? &pair
: nullptr);
697 ntype
= atypes
->size();
698 ncombs
= (ntype
*(ntype
+1))/2;
699 generate_nbparams(*combination_rule
, nb_funct
, &(interactions
[nb_funct
]), atypes
, wi
);
700 ncopy
= copy_nbparams(nbparam
, nb_funct
, &(interactions
[nb_funct
]),
702 fprintf(stderr
, "Generated %d of the %d non-bonded parameter combinations\n", ncombs
-ncopy
, ncombs
);
703 free_nbparam(nbparam
, ntype
);
706 gen_pairs((interactions
[nb_funct
]), &(interactions
[F_LJ14
]), fudgeLJ
, *combination_rule
);
707 ncopy
= copy_nbparams(pair
, nb_funct
, &(interactions
[F_LJ14
]),
709 fprintf(stderr
, "Generated %d of the %d 1-4 parameter combinations\n", ncombs
-ncopy
, ncombs
);
710 free_nbparam(pair
, ntype
);
712 /* Copy GBSA parameters to atomtype array? */
717 push_molt(symtab
, molinfo
, pline
, wi
);
718 exclusionBlocks
.emplace_back();
719 mi0
= &molinfo
->back();
720 mi0
->atoms
.haveMass
= TRUE
;
721 mi0
->atoms
.haveCharge
= TRUE
;
722 mi0
->atoms
.haveType
= TRUE
;
723 mi0
->atoms
.haveBState
= TRUE
;
724 mi0
->atoms
.havePdbInfo
= FALSE
;
727 case Directive::d_atoms
:
728 push_atom(symtab
, &(mi0
->atoms
), atypes
, pline
, wi
);
731 case Directive::d_pairs
:
732 GMX_RELEASE_ASSERT(mi0
, "Need to have a valid MoleculeInformation object to work on");
733 push_bond(d
, interactions
, mi0
->interactions
, &(mi0
->atoms
), atypes
, pline
, FALSE
,
734 bGenPairs
, *fudgeQQ
, bZero
, &bWarn_copy_A_B
, wi
);
736 case Directive::d_pairs_nb
:
737 GMX_RELEASE_ASSERT(mi0
, "Need to have a valid MoleculeInformation object to work on");
738 push_bond(d
, interactions
, mi0
->interactions
, &(mi0
->atoms
), atypes
, pline
, FALSE
,
739 FALSE
, 1.0, bZero
, &bWarn_copy_A_B
, wi
);
742 case Directive::d_vsites2
:
743 case Directive::d_vsites3
:
744 case Directive::d_vsites4
:
745 case Directive::d_bonds
:
746 case Directive::d_angles
:
747 case Directive::d_constraints
:
748 case Directive::d_settles
:
749 case Directive::d_position_restraints
:
750 case Directive::d_angle_restraints
:
751 case Directive::d_angle_restraints_z
:
752 case Directive::d_distance_restraints
:
753 case Directive::d_orientation_restraints
:
754 case Directive::d_dihedral_restraints
:
755 case Directive::d_dihedrals
:
756 case Directive::d_polarization
:
757 case Directive::d_water_polarization
:
758 case Directive::d_thole_polarization
:
759 GMX_RELEASE_ASSERT(mi0
, "Need to have a valid MoleculeInformation object to work on");
760 push_bond(d
, interactions
, mi0
->interactions
, &(mi0
->atoms
), atypes
, pline
, TRUE
,
761 bGenPairs
, *fudgeQQ
, bZero
, &bWarn_copy_A_B
, wi
);
763 case Directive::d_cmap
:
764 GMX_RELEASE_ASSERT(mi0
, "Need to have a valid MoleculeInformation object to work on");
765 push_cmap(d
, interactions
, mi0
->interactions
, &(mi0
->atoms
), atypes
, pline
, wi
);
768 case Directive::d_vsitesn
:
769 GMX_RELEASE_ASSERT(mi0
, "Need to have a valid MoleculeInformation object to work on");
770 push_vsitesn(d
, mi0
->interactions
, &(mi0
->atoms
), pline
, wi
);
772 case Directive::d_exclusions
:
773 GMX_ASSERT(!exclusionBlocks
.empty(), "exclusionBlocks must always be allocated so exclusions can be processed");
774 if (exclusionBlocks
.back().empty())
776 GMX_RELEASE_ASSERT(mi0
, "Need to have a valid MoleculeInformation object to work on");
777 exclusionBlocks
.back().resize(mi0
->atoms
.nr
);
779 push_excl(pline
, exclusionBlocks
.back(), wi
);
781 case Directive::d_system
:
783 title
= put_symtab(symtab
, pline
);
785 case Directive::d_molecules
:
790 push_mol(*molinfo
, pline
, &whichmol
, &nrcopies
, wi
);
791 mi0
= &((*molinfo
)[whichmol
]);
792 molblock
->resize(molblock
->size() + 1);
793 molblock
->back().type
= whichmol
;
794 molblock
->back().nmol
= nrcopies
;
796 bCouple
= (opts
->couple_moltype
!= nullptr &&
797 (gmx_strcasecmp("system", opts
->couple_moltype
) == 0 ||
798 strcmp(*(mi0
->name
), opts
->couple_moltype
) == 0));
801 nmol_couple
+= nrcopies
;
804 if (mi0
->atoms
.nr
== 0)
806 gmx_fatal(FARGS
, "Molecule type '%s' contains no atoms",
810 "Excluding %d bonded neighbours molecule type '%s'\n",
811 mi0
->nrexcl
, *mi0
->name
);
812 sum_q(&mi0
->atoms
, nrcopies
, &qt
, &qBt
);
813 if (!mi0
->bProcessed
)
816 generate_excl(mi0
->nrexcl
,
821 gmx::mergeExclusions(&(mi0
->excls
), exclusionBlocks
[whichmol
]);
822 make_shake(mi0
->interactions
, &mi0
->atoms
, opts
->nshake
);
828 convert_moltype_couple(mi0
, dcatt
, *fudgeQQ
,
829 opts
->couple_lam0
, opts
->couple_lam1
,
831 nb_funct
, &(interactions
[nb_funct
]), wi
);
833 stupid_fill_block(&mi0
->mols
, mi0
->atoms
.nr
, TRUE
);
834 mi0
->bProcessed
= TRUE
;
839 fprintf (stderr
, "case: %d\n", static_cast<int>(d
));
840 gmx_incons("unknown directive");
850 // Check that all strings defined with -D were used when processing topology
851 std::string unusedDefineWarning
= checkAndWarnForUnusedDefines(*handle
);
852 if (!unusedDefineWarning
.empty())
854 warning(wi
, unusedDefineWarning
);
857 sfree(cpp_opts_return
);
864 /* List of GROMACS define names for force fields that have been
865 * parametrized using constraints involving hydrogens only.
867 * We should avoid hardcoded names, but this is hopefully only
868 * needed temparorily for discouraging use of constraints=all-bonds.
870 const std::array
<std::string
, 3> ffDefines
= {
875 *ffParametrizedWithHBondConstraints
= false;
876 for (const std::string
&ffDefine
: ffDefines
)
878 if (cpp_find_define(&handle
, ffDefine
))
880 *ffParametrizedWithHBondConstraints
= true;
884 if (cpp_find_define(&handle
, "_FF_GROMOS96") != nullptr)
887 "The GROMOS force fields have been parametrized with a physically incorrect "
888 "multiple-time-stepping scheme for a twin-range cut-off. When used with "
889 "a single-range cut-off (or a correct Trotter multiple-time-stepping scheme), "
890 "physical properties, such as the density, might differ from the intended values. "
891 "Check if molecules in your system are affected by such issues before proceeding. "
892 "Further information may be available at https://redmine.gromacs.org/issues/2884.");
897 if (opts
->couple_moltype
)
899 if (nmol_couple
== 0)
901 gmx_fatal(FARGS
, "Did not find any molecules of type '%s' for coupling",
902 opts
->couple_moltype
);
904 fprintf(stderr
, "Coupling %d copies of molecule type '%s'\n",
905 nmol_couple
, opts
->couple_moltype
);
908 /* this is not very clean, but fixes core dump on empty system name */
911 title
= put_symtab(symtab
, "");
916 sprintf(warn_buf
, "System has non-zero total charge: %.6f\n%s\n", qt
, floating_point_arithmetic_tip
);
917 warning_note(wi
, warn_buf
);
919 if (fabs(qBt
) > 1e-4 && !gmx_within_tol(qBt
, qt
, 1e-6))
921 sprintf(warn_buf
, "State B has non-zero total charge: %.6f\n%s\n", qBt
, floating_point_arithmetic_tip
);
922 warning_note(wi
, warn_buf
);
924 if (usingFullRangeElectrostatics
&& (fabs(qt
) > 1e-4 || fabs(qBt
) > 1e-4))
926 warning(wi
, "You are using Ewald electrostatics in a system with net charge. This can lead to severe artifacts, such as ions moving into regions with low dielectric, due to the uniform background charge. We suggest to neutralize your system with counter ions, possibly in combination with a physiological salt concentration.");
927 please_cite(stdout
, "Hub2014a");
932 if (*intermolecular_interactions
!= nullptr)
934 sfree(intermolecular_interactions
->get()->atoms
.atom
);
940 char **do_top(bool bVerbose
,
942 const char *topppfile
,
946 gmx::ArrayRef
<InteractionsOfType
> interactions
,
947 int *combination_rule
,
948 double *repulsion_power
,
950 PreprocessingAtomTypes
*atypes
,
951 std::vector
<MoleculeInformation
> *molinfo
,
952 std::unique_ptr
<MoleculeInformation
> *intermolecular_interactions
,
953 const t_inputrec
*ir
,
954 std::vector
<gmx_molblock_t
> *molblock
,
955 bool *ffParametrizedWithHBondConstraints
,
958 /* Tmpfile might contain a long path */
973 printf("processing topology...\n");
975 title
= read_topol(topfile
, tmpfile
, opts
->define
, opts
->include
,
977 molinfo
, intermolecular_interactions
,
978 interactions
, combination_rule
, repulsion_power
,
979 opts
, fudgeQQ
, molblock
,
980 ffParametrizedWithHBondConstraints
,
981 ir
->efep
!= efepNO
, bZero
,
982 EEL_FULL(ir
->coulombtype
), wi
);
984 if ((*combination_rule
!= eCOMB_GEOMETRIC
) &&
985 (ir
->vdwtype
== evdwUSER
))
987 warning(wi
, "Using sigma/epsilon based combination rules with"
988 " user supplied potential function may produce unwanted"
996 * Generate exclusion lists for QM/MM.
998 * This routine updates the exclusion lists for QM atoms in order to include all other QM
999 * atoms of this molecule. Moreover, this routine replaces bonds between QM atoms with
1000 * CONNBOND and, when MiMiC is not used, removes bonded interactions between QM and link atoms.
1001 * Finally, in case if MiMiC QM/MM is used - charges of QM atoms are set to 0
1003 * @param molt molecule type with QM atoms
1004 * @param grpnr group informatio
1005 * @param ir input record
1006 * @param qmmmMode QM/MM mode switch: original/MiMiC
1008 static void generate_qmexcl_moltype(gmx_moltype_t
*molt
, const unsigned char *grpnr
,
1009 t_inputrec
*ir
, GmxQmmmMode qmmmMode
)
1011 /* This routine expects molt->ilist to be of size F_NRE and ordered. */
1013 /* generates the exclusions between the individual QM atoms, as
1014 * these interactions should be handled by the QM subroutines and
1015 * not by the gromacs routines
1017 int qm_max
= 0, qm_nr
= 0, link_nr
= 0, link_max
= 0;
1018 int *qm_arr
= nullptr, *link_arr
= nullptr;
1019 bool *bQMMM
, *blink
;
1021 /* First we search and select the QM atoms in an qm_arr array that
1022 * we use to create the exclusions.
1024 * we take the possibility into account that a user has defined more
1025 * than one QM group:
1027 * for that we also need to do this an ugly work-about just in case
1028 * the QM group contains the entire system...
1031 /* we first search for all the QM atoms and put them in an array
1033 for (int j
= 0; j
< ir
->opts
.ngQM
; j
++)
1035 for (int i
= 0; i
< molt
->atoms
.nr
; i
++)
1037 if (qm_nr
>= qm_max
)
1040 srenew(qm_arr
, qm_max
);
1042 if ((grpnr
? grpnr
[i
] : 0) == j
)
1044 qm_arr
[qm_nr
++] = i
;
1045 molt
->atoms
.atom
[i
].q
= 0.0;
1046 molt
->atoms
.atom
[i
].qB
= 0.0;
1050 /* bQMMM[..] is an array containin TRUE/FALSE for atoms that are
1051 * QM/not QM. We first set all elements to false. Afterwards we use
1052 * the qm_arr to change the elements corresponding to the QM atoms
1055 snew(bQMMM
, molt
->atoms
.nr
);
1056 for (int i
= 0; i
< molt
->atoms
.nr
; i
++)
1060 for (int i
= 0; i
< qm_nr
; i
++)
1062 bQMMM
[qm_arr
[i
]] = TRUE
;
1065 /* We remove all bonded interactions (i.e. bonds,
1066 * angles, dihedrals, 1-4's), involving the QM atoms. The way they
1067 * are removed is as follows: if the interaction invloves 2 atoms,
1068 * it is removed if both atoms are QMatoms. If it involves 3 atoms,
1069 * it is removed if at least two of the atoms are QM atoms, if the
1070 * interaction involves 4 atoms, it is removed if there are at least
1071 * 2 QM atoms. Since this routine is called once before any forces
1072 * are computed, the top->idef.il[N].iatom[] array (see idef.h) can
1073 * be rewritten at this poitn without any problem. 25-9-2002 */
1075 /* first check whether we already have CONNBONDS.
1076 * Note that if we don't, we don't add a param entry and set ftype=0,
1077 * which is ok, since CONNBONDS does not use parameters.
1079 int ftype_connbond
= 0;
1080 int ind_connbond
= 0;
1081 if (molt
->ilist
[F_CONNBONDS
].size() != 0)
1083 fprintf(stderr
, "nr. of CONNBONDS present already: %d\n",
1084 molt
->ilist
[F_CONNBONDS
].size()/3);
1085 ftype_connbond
= molt
->ilist
[F_CONNBONDS
].iatoms
[0];
1086 ind_connbond
= molt
->ilist
[F_CONNBONDS
].size();
1088 /* now we delete all bonded interactions, except the ones describing
1089 * a chemical bond. These are converted to CONNBONDS
1091 for (int ftype
= 0; ftype
< F_NRE
; ftype
++)
1093 if (!(interaction_function
[ftype
].flags
& IF_BOND
) ||
1094 ftype
== F_CONNBONDS
)
1098 int nratoms
= interaction_function
[ftype
].nratoms
;
1100 while (j
< molt
->ilist
[ftype
].size())
1106 /* Remove an interaction between two atoms when both are
1107 * in the QM region. Note that we don't have to worry about
1108 * link atoms here, as they won't have 2-atom interactions.
1110 int a1
= molt
->ilist
[ftype
].iatoms
[1 + j
+ 0];
1111 int a2
= molt
->ilist
[ftype
].iatoms
[1 + j
+ 1];
1112 bexcl
= (bQMMM
[a1
] && bQMMM
[a2
]);
1113 /* A chemical bond between two QM atoms will be copied to
1114 * the F_CONNBONDS list, for reasons mentioned above.
1116 if (bexcl
&& IS_CHEMBOND(ftype
))
1118 InteractionList
&ilist
= molt
->ilist
[F_CONNBONDS
];
1119 ilist
.iatoms
.resize(ind_connbond
+ 3);
1120 ilist
.iatoms
[ind_connbond
++] = ftype_connbond
;
1121 ilist
.iatoms
[ind_connbond
++] = a1
;
1122 ilist
.iatoms
[ind_connbond
++] = a2
;
1127 /* MM interactions have to be excluded if they are included
1128 * in the QM already. Because we use a link atom (H atom)
1129 * when the QM/MM boundary runs through a chemical bond, this
1130 * means that as long as one atom is MM, we still exclude,
1131 * as the interaction is included in the QM via:
1132 * QMatom1-QMatom2-QMatom-3-Linkatom.
1135 for (int jj
= j
+ 1; jj
< j
+ 1 + nratoms
; jj
++)
1137 if (bQMMM
[molt
->ilist
[ftype
].iatoms
[jj
]])
1143 /* MiMiC treats link atoms as quantum atoms - therefore
1144 * we do not need do additional exclusions here */
1145 if (qmmmMode
== GmxQmmmMode::GMX_QMMM_MIMIC
)
1147 bexcl
= numQmAtoms
== nratoms
;
1151 bexcl
= (numQmAtoms
>= nratoms
- 1);
1154 if (bexcl
&& ftype
== F_SETTLE
)
1156 gmx_fatal(FARGS
, "Can not apply QM to molecules with SETTLE, replace the moleculetype using QM and SETTLE by one without SETTLE");
1161 /* since the interaction involves QM atoms, these should be
1162 * removed from the MM ilist
1164 InteractionList
&ilist
= molt
->ilist
[ftype
];
1165 for (int k
= j
; k
< ilist
.size() - (nratoms
+ 1); k
++)
1167 ilist
.iatoms
[k
] = ilist
.iatoms
[k
+ (nratoms
+ 1)];
1169 ilist
.iatoms
.resize(ilist
.size() - (nratoms
+ 1));
1173 j
+= nratoms
+1; /* the +1 is for the functype */
1177 /* Now, we search for atoms bonded to a QM atom because we also want
1178 * to exclude their nonbonded interactions with the QM atoms. The
1179 * reason for this is that this interaction is accounted for in the
1180 * linkatoms interaction with the QMatoms and would be counted
1183 if (qmmmMode
!= GmxQmmmMode::GMX_QMMM_MIMIC
)
1185 for (int i
= 0; i
< F_NRE
; i
++)
1190 while (j
< molt
->ilist
[i
].size())
1192 int a1
= molt
->ilist
[i
].iatoms
[j
+ 1];
1193 int a2
= molt
->ilist
[i
].iatoms
[j
+ 2];
1194 if ((bQMMM
[a1
] && !bQMMM
[a2
]) || (!bQMMM
[a1
] && bQMMM
[a2
]))
1196 if (link_nr
>= link_max
)
1199 srenew(link_arr
, link_max
);
1203 link_arr
[link_nr
++] = a2
;
1207 link_arr
[link_nr
++] = a1
;
1215 snew(blink
, molt
->atoms
.nr
);
1216 for (int i
= 0; i
< molt
->atoms
.nr
; i
++)
1221 if (qmmmMode
!= GmxQmmmMode::GMX_QMMM_MIMIC
)
1223 for (int i
= 0; i
< link_nr
; i
++)
1225 blink
[link_arr
[i
]] = TRUE
;
1228 /* creating the exclusion block for the QM atoms. Each QM atom has
1229 * as excluded elements all the other QMatoms (and itself).
1232 qmexcl
.nr
= molt
->atoms
.nr
;
1233 qmexcl
.nra
= qm_nr
*(qm_nr
+link_nr
)+link_nr
*qm_nr
;
1234 snew(qmexcl
.index
, qmexcl
.nr
+1);
1235 snew(qmexcl
.a
, qmexcl
.nra
);
1237 for (int i
= 0; i
< qmexcl
.nr
; i
++)
1239 qmexcl
.index
[i
] = j
;
1242 for (int k
= 0; k
< qm_nr
; k
++)
1244 qmexcl
.a
[k
+j
] = qm_arr
[k
];
1246 for (int k
= 0; k
< link_nr
; k
++)
1248 qmexcl
.a
[qm_nr
+k
+j
] = link_arr
[k
];
1250 j
+= (qm_nr
+link_nr
);
1254 for (int k
= 0; k
< qm_nr
; k
++)
1256 qmexcl
.a
[k
+j
] = qm_arr
[k
];
1261 qmexcl
.index
[qmexcl
.nr
] = j
;
1263 /* and merging with the exclusions already present in sys.
1266 std::vector
<gmx::ExclusionBlock
> qmexcl2(molt
->atoms
.nr
);
1267 gmx::blockaToExclusionBlocks(&qmexcl
, qmexcl2
);
1268 gmx::mergeExclusions(&(molt
->excls
), qmexcl2
);
1270 /* Finally, we also need to get rid of the pair interactions of the
1271 * classical atom bonded to the boundary QM atoms with the QMatoms,
1272 * as this interaction is already accounted for by the QM, so also
1273 * here we run the risk of double counting! We proceed in a similar
1274 * way as we did above for the other bonded interactions: */
1275 for (int i
= F_LJ14
; i
< F_COUL14
; i
++)
1277 int nratoms
= interaction_function
[i
].nratoms
;
1279 while (j
< molt
->ilist
[i
].size())
1281 int a1
= molt
->ilist
[i
].iatoms
[j
+1];
1282 int a2
= molt
->ilist
[i
].iatoms
[j
+2];
1283 bool bexcl
= ((bQMMM
[a1
] && bQMMM
[a2
]) ||
1284 (blink
[a1
] && bQMMM
[a2
]) ||
1285 (bQMMM
[a1
] && blink
[a2
]));
1288 /* since the interaction involves QM atoms, these should be
1289 * removed from the MM ilist
1291 InteractionList
&ilist
= molt
->ilist
[i
];
1292 for (int k
= j
; k
< ilist
.size() - (nratoms
+ 1); k
++)
1294 ilist
.iatoms
[k
] = ilist
.iatoms
[k
+ (nratoms
+ 1)];
1296 ilist
.iatoms
.resize(ilist
.size() - (nratoms
+ 1));
1300 j
+= nratoms
+1; /* the +1 is for the functype */
1309 } /* generate_qmexcl */
1311 void generate_qmexcl(gmx_mtop_t
*sys
, t_inputrec
*ir
, warninp
*wi
, GmxQmmmMode qmmmMode
)
1313 /* This routine expects molt->molt[m].ilist to be of size F_NRE and ordered.
1316 unsigned char *grpnr
;
1317 int mol
, nat_mol
, nr_mol_with_qm_atoms
= 0;
1318 gmx_molblock_t
*molb
;
1320 int index_offset
= 0;
1323 grpnr
= sys
->groups
.groupNumbers
[SimulationAtomGroupType::QuantumMechanics
].data();
1325 for (size_t mb
= 0; mb
< sys
->molblock
.size(); mb
++)
1327 molb
= &sys
->molblock
[mb
];
1328 nat_mol
= sys
->moltype
[molb
->type
].atoms
.nr
;
1329 for (mol
= 0; mol
< molb
->nmol
; mol
++)
1332 for (int i
= 0; i
< nat_mol
; i
++)
1334 if ((grpnr
? grpnr
[i
] : 0) < (ir
->opts
.ngQM
))
1343 nr_mol_with_qm_atoms
++;
1346 /* We need to split this molblock */
1349 /* Split the molblock at this molecule */
1350 auto pos
= sys
->molblock
.begin() + mb
+ 1;
1351 sys
->molblock
.insert(pos
, sys
->molblock
[mb
]);
1352 sys
->molblock
[mb
].nmol
= mol
;
1353 sys
->molblock
[mb
+1].nmol
-= mol
;
1355 molb
= &sys
->molblock
[mb
];
1359 /* Split the molblock after this molecule */
1360 auto pos
= sys
->molblock
.begin() + mb
+ 1;
1361 sys
->molblock
.insert(pos
, sys
->molblock
[mb
]);
1362 molb
= &sys
->molblock
[mb
];
1363 sys
->molblock
[mb
].nmol
= 1;
1364 sys
->molblock
[mb
+1].nmol
-= 1;
1367 /* Create a copy of a moltype for a molecule
1368 * containing QM atoms and append it in the end of the list
1370 std::vector
<gmx_moltype_t
> temp(sys
->moltype
.size());
1371 for (size_t i
= 0; i
< sys
->moltype
.size(); ++i
)
1373 copy_moltype(&sys
->moltype
[i
], &temp
[i
]);
1375 sys
->moltype
.resize(sys
->moltype
.size() + 1);
1376 for (size_t i
= 0; i
< temp
.size(); ++i
)
1378 copy_moltype(&temp
[i
], &sys
->moltype
[i
]);
1380 copy_moltype(&sys
->moltype
[molb
->type
], &sys
->moltype
.back());
1381 /* Copy the exclusions to a new array, since this is the only
1382 * thing that needs to be modified for QMMM.
1384 copy_blocka(&sys
->moltype
[molb
->type
].excls
,
1385 &sys
->moltype
.back().excls
);
1386 /* Set the molecule type for the QMMM molblock */
1387 molb
->type
= sys
->moltype
.size() - 1;
1389 generate_qmexcl_moltype(&sys
->moltype
[molb
->type
], grpnr
, ir
, qmmmMode
);
1395 index_offset
+= nat_mol
;
1398 if (qmmmMode
== GmxQmmmMode::GMX_QMMM_ORIGINAL
&&
1399 nr_mol_with_qm_atoms
> 1)
1401 /* generate a warning is there are QM atoms in different
1402 * topologies. In this case it is not possible at this stage to
1403 * mutualy exclude the non-bonded interactions via the
1404 * exclusions (AFAIK). Instead, the user is advised to use the
1405 * energy group exclusions in the mdp file
1408 "\nThe QM subsystem is divided over multiple topologies. "
1409 "The mutual non-bonded interactions cannot be excluded. "
1410 "There are two ways to achieve this:\n\n"
1411 "1) merge the topologies, such that the atoms of the QM "
1412 "subsystem are all present in one single topology file. "
1413 "In this case this warning will dissappear\n\n"
1414 "2) exclude the non-bonded interactions explicitly via the "
1415 "energygrp-excl option in the mdp file. if this is the case "
1416 "this warning may be ignored"