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,2017,2018 by the GROMACS development team.
7 * Copyright (c) 2019,2020, by the GROMACS development team, led by
8 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
9 * and including many others, as listed in the AUTHORS file in the
10 * top-level source directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
47 #include "gromacs/topology/idef.h"
48 #include "gromacs/utility/cstringutil.h"
49 #include "gromacs/utility/enumerationhelpers.h"
50 #include "gromacs/utility/fatalerror.h"
51 #include "gromacs/utility/smalloc.h"
53 /* Must correspond to the Directive enum in grompp_impl.h */
54 static gmx::EnumerationArray
<Directive
, const char*> directive_names
= {
55 { "defaults", "atomtypes", "bondtypes", "constrainttypes", "pairtypes", "angletypes",
56 "dihedraltypes", "nonbond_params", "implicit_genborn_params", "implicit_surface_params",
58 /* All the directives above can not appear after moleculetype */
59 "moleculetype", "atoms", "virtual_sites2", "virtual_sites3", "virtual_sites4",
60 "virtual_sitesn", "bonds", "exclusions", "pairs", "pairs_nb", "angles", "dihedrals",
61 "constraints", "settles", "polarization", "water_polarization", "thole_polarization",
62 "system", "molecules", "position_restraints", "angle_restraints", "angle_restraints_z",
63 "distance_restraints", "orientation_restraints", "dihedral_restraints", "cmap",
64 "intermolecular_interactions", "maxdirs", "invalid", "none" }
67 int ifunc_index(Directive d
, int type
)
71 case Directive::d_bondtypes
:
72 case Directive::d_bonds
:
75 case 1: return F_BONDS
;
76 case 2: return F_G96BONDS
;
77 case 3: return F_MORSE
;
78 case 4: return F_CUBICBONDS
;
79 case 5: return F_CONNBONDS
;
80 case 6: return F_HARMONIC
;
81 case 7: return F_FENEBONDS
;
82 case 8: return F_TABBONDS
;
83 case 9: return F_TABBONDSNC
;
84 case 10: return F_RESTRBONDS
;
85 default: gmx_fatal(FARGS
, "Invalid bond type %d", type
);
87 case Directive::d_angles
:
88 case Directive::d_angletypes
:
91 case 1: return F_ANGLES
;
92 case 2: return F_G96ANGLES
;
93 case 3: return F_CROSS_BOND_BONDS
;
94 case 4: return F_CROSS_BOND_ANGLES
;
95 case 5: return F_UREY_BRADLEY
;
96 case 6: return F_QUARTIC_ANGLES
;
97 case 8: return F_TABANGLES
;
98 case 9: return F_LINEAR_ANGLES
;
99 case 10: return F_RESTRANGLES
;
100 default: gmx_fatal(FARGS
, "Invalid angle type %d", type
);
102 case Directive::d_pairs
:
103 case Directive::d_pairtypes
:
104 if (type
== 1 || (d
== Directive::d_pairtypes
&& type
== 2))
114 gmx_fatal(FARGS
, "Invalid pairs type %d", type
);
116 case Directive::d_pairs_nb
: return F_LJC_PAIRS_NB
;
117 case Directive::d_dihedrals
:
118 case Directive::d_dihedraltypes
:
121 case 1: return F_PDIHS
;
122 case 2: return F_IDIHS
;
123 case 3: return F_RBDIHS
;
124 case 4: return F_PIDIHS
;
125 case 5: return F_FOURDIHS
;
126 case 8: return F_TABDIHS
;
128 return F_PDIHS
; /* proper dihedrals where we allow multiple terms over single bond */
129 case 10: return F_RESTRDIHS
;
130 case 11: return F_CBTDIHS
;
131 default: gmx_fatal(FARGS
, "Invalid dihedral type %d", type
);
133 case Directive::d_cmaptypes
:
134 case Directive::d_cmap
: return F_CMAP
;
136 case Directive::d_nonbond_params
:
145 case Directive::d_vsites2
:
148 case 1: return F_VSITE2
;
149 case 2: return F_VSITE2FD
;
150 default: gmx_fatal(FARGS
, "Invalid vsites2 type %d", type
);
152 case Directive::d_vsites3
:
155 case 1: return F_VSITE3
;
156 case 2: return F_VSITE3FD
;
157 case 3: return F_VSITE3FAD
;
158 case 4: return F_VSITE3OUT
;
159 default: gmx_fatal(FARGS
, "Invalid vsites3 type %d", type
);
161 case Directive::d_vsites4
:
164 case 1: return F_VSITE4FD
;
165 case 2: return F_VSITE4FDN
;
166 default: gmx_fatal(FARGS
, "Invalid vsites4 type %d", type
);
168 case Directive::d_vsitesn
: return F_VSITEN
;
169 case Directive::d_constraints
:
170 case Directive::d_constrainttypes
:
173 case 1: return F_CONSTR
;
174 case 2: return F_CONSTRNC
;
175 default: gmx_fatal(FARGS
, "Invalid constraints type %d", type
);
177 case Directive::d_settles
: return F_SETTLE
;
178 case Directive::d_position_restraints
:
181 case 1: return F_POSRES
;
182 case 2: return F_FBPOSRES
;
183 default: gmx_fatal(FARGS
, "Invalid position restraint type %d", type
);
185 case Directive::d_polarization
:
188 case 1: return F_POLARIZATION
;
189 case 2: return F_ANHARM_POL
;
190 default: gmx_fatal(FARGS
, "Invalid polarization type %d", type
);
192 case Directive::d_thole_polarization
: return F_THOLE_POL
;
193 case Directive::d_water_polarization
: return F_WATER_POL
;
194 case Directive::d_angle_restraints
: return F_ANGRES
;
195 case Directive::d_angle_restraints_z
: return F_ANGRESZ
;
196 case Directive::d_distance_restraints
: return F_DISRES
;
197 case Directive::d_orientation_restraints
: return F_ORIRES
;
198 case Directive::d_dihedral_restraints
: return F_DIHRES
;
200 gmx_fatal(FARGS
, "invalid directive %s in ifunc_index (%s:%d)", dir2str(d
), __FILE__
, __LINE__
);
204 const char* dir2str(Directive d
)
206 int index
= static_cast<int>(d
);
207 return directive_names
[index
];
210 Directive
str2dir(char* dstr
)
212 char buf
[STRLEN
], *ptr
;
214 /* Hack to be able to read old topologies */
215 if (gmx_strncasecmp_min(dstr
, "dummies", 7) == 0)
217 sprintf(buf
, "virtual_sites%s", dstr
+ 7);
225 for (auto d
: gmx::EnumerationWrapper
<Directive
>())
227 if (gmx_strcasecmp_min(ptr
, dir2str(static_cast<Directive
>(d
))) == 0)
229 return static_cast<Directive
>(d
);
233 return Directive::d_invalid
;
236 static gmx::EnumerationArray
<Directive
, Directive
*> necessary
= { { nullptr } };
238 static void set_nec(Directive
** n
, ...)
239 /* Must always have at least one extra argument */
248 d
= static_cast<Directive
>(va_arg(ap
, int));
251 } while (d
!= Directive::d_none
);
255 void DS_Init(DirStack
** DS
)
257 if (necessary
[0] == nullptr)
259 set_nec(&(necessary
[Directive::d_defaults
]), Directive::d_none
);
260 set_nec(&(necessary
[Directive::d_atomtypes
]), Directive::d_defaults
, Directive::d_none
);
261 set_nec(&(necessary
[Directive::d_bondtypes
]), Directive::d_atomtypes
, Directive::d_none
);
262 set_nec(&(necessary
[Directive::d_constrainttypes
]), Directive::d_atomtypes
, Directive::d_none
);
263 set_nec(&(necessary
[Directive::d_pairtypes
]), Directive::d_atomtypes
, Directive::d_none
);
264 set_nec(&(necessary
[Directive::d_angletypes
]), Directive::d_atomtypes
, Directive::d_none
);
265 set_nec(&(necessary
[Directive::d_dihedraltypes
]), Directive::d_atomtypes
, Directive::d_none
);
266 set_nec(&(necessary
[Directive::d_nonbond_params
]), Directive::d_atomtypes
, Directive::d_none
);
267 // Note that the content of the next two directives are
268 // ignored, but if grompp reads them in old force field files,
269 // it still needs to understand that they are in a valid place
270 // in the .top structure. It doesn't have to require them to
271 // be in the same place that was valid in old versions (ie. child
272 // directive of [atomtypes]) but any relevant case will
274 set_nec(&(necessary
[Directive::d_implicit_genborn_params
]), Directive::d_atomtypes
,
276 set_nec(&(necessary
[Directive::d_implicit_surface_params
]), Directive::d_atomtypes
,
278 set_nec(&(necessary
[Directive::d_cmaptypes
]), Directive::d_atomtypes
, Directive::d_none
);
279 set_nec(&(necessary
[Directive::d_moleculetype
]), Directive::d_atomtypes
, Directive::d_none
);
280 set_nec(&(necessary
[Directive::d_atoms
]), Directive::d_moleculetype
, Directive::d_none
);
281 set_nec(&(necessary
[Directive::d_vsites2
]), Directive::d_atoms
, Directive::d_none
);
282 set_nec(&(necessary
[Directive::d_vsites3
]), Directive::d_atoms
, Directive::d_none
);
283 set_nec(&(necessary
[Directive::d_vsites4
]), Directive::d_atoms
, Directive::d_none
);
284 set_nec(&(necessary
[Directive::d_vsitesn
]), Directive::d_atoms
, Directive::d_none
);
285 set_nec(&(necessary
[Directive::d_bonds
]), Directive::d_atoms
, Directive::d_none
);
286 set_nec(&(necessary
[Directive::d_exclusions
]), Directive::d_bonds
, Directive::d_constraints
,
287 Directive::d_settles
, Directive::d_none
);
288 set_nec(&(necessary
[Directive::d_pairs
]), Directive::d_atoms
, Directive::d_none
);
289 set_nec(&(necessary
[Directive::d_pairs_nb
]), Directive::d_atoms
, Directive::d_none
);
290 set_nec(&(necessary
[Directive::d_angles
]), Directive::d_atoms
, Directive::d_none
);
291 set_nec(&(necessary
[Directive::d_polarization
]), Directive::d_atoms
, Directive::d_none
);
292 set_nec(&(necessary
[Directive::d_water_polarization
]), Directive::d_atoms
, Directive::d_none
);
293 set_nec(&(necessary
[Directive::d_thole_polarization
]), Directive::d_atoms
, Directive::d_none
);
294 set_nec(&(necessary
[Directive::d_dihedrals
]), Directive::d_atoms
, Directive::d_none
);
295 set_nec(&(necessary
[Directive::d_constraints
]), Directive::d_atoms
, Directive::d_none
);
296 set_nec(&(necessary
[Directive::d_settles
]), Directive::d_atoms
, Directive::d_none
);
297 set_nec(&(necessary
[Directive::d_system
]), Directive::d_moleculetype
, Directive::d_none
);
298 set_nec(&(necessary
[Directive::d_molecules
]), Directive::d_system
, Directive::d_none
);
299 set_nec(&(necessary
[Directive::d_position_restraints
]), Directive::d_atoms
, Directive::d_none
);
300 set_nec(&(necessary
[Directive::d_angle_restraints
]), Directive::d_atoms
, Directive::d_none
);
301 set_nec(&(necessary
[Directive::d_angle_restraints_z
]), Directive::d_atoms
, Directive::d_none
);
302 set_nec(&(necessary
[Directive::d_distance_restraints
]), Directive::d_atoms
, Directive::d_none
);
303 set_nec(&(necessary
[Directive::d_orientation_restraints
]), Directive::d_atoms
, Directive::d_none
);
304 set_nec(&(necessary
[Directive::d_dihedral_restraints
]), Directive::d_atoms
, Directive::d_none
);
305 set_nec(&(necessary
[Directive::d_cmap
]), Directive::d_atoms
, Directive::d_none
);
306 set_nec(&(necessary
[Directive::d_intermolecular_interactions
]), Directive::d_molecules
,
312 void DS_Done(DirStack
** DS
)
316 while (*DS
!= nullptr)
324 void DS_Push(DirStack
** DS
, Directive d
)
334 int DS_Search(DirStack
* DS
, Directive d
)
339 while ((D
!= nullptr) && (D
->d
!= d
))
344 return static_cast<int>(D
!= nullptr);
347 int DS_Check_Order(DirStack
* DS
, Directive d
)
352 /* Check if parameter definitions appear after a moleculetype directive */
353 if (d
< Directive::d_moleculetype
&& DS_Search(DS
, Directive::d_moleculetype
))
358 /* Check if all the necessary directives have appeared before directive d */
359 if (necessary
[d
][0] == Directive::d_none
)
367 d0
= necessary
[d
][i
++];
368 if (DS_Search(DS
, d0
))
372 } while (d0
!= Directive::d_none
);