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,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.
46 #include "gromacs/topology/idef.h"
47 #include "gromacs/utility/cstringutil.h"
48 #include "gromacs/utility/enumerationhelpers.h"
49 #include "gromacs/utility/fatalerror.h"
50 #include "gromacs/utility/smalloc.h"
52 /* Must correspond to the Directive enum in grompp_impl.h */
53 static gmx::EnumerationArray
<Directive
, const char *> directive_names
63 "implicit_genborn_params",
64 "implicit_surface_params",
66 /* All the directives above can not appear after moleculetype */
86 "position_restraints",
89 "distance_restraints",
90 "orientation_restraints",
91 "dihedral_restraints",
93 "intermolecular_interactions",
99 int ifunc_index(Directive d
, int type
)
103 case Directive::d_bondtypes
:
104 case Directive::d_bonds
:
128 gmx_fatal(FARGS
, "Invalid bond type %d", type
);
130 case Directive::d_angles
:
131 case Directive::d_angletypes
:
139 return F_CROSS_BOND_BONDS
;
141 return F_CROSS_BOND_ANGLES
;
143 return F_UREY_BRADLEY
;
145 return F_QUARTIC_ANGLES
;
149 return F_LINEAR_ANGLES
;
151 return F_RESTRANGLES
;
153 gmx_fatal(FARGS
, "Invalid angle type %d", type
);
155 case Directive::d_pairs
:
156 case Directive::d_pairtypes
:
157 if (type
== 1 || (d
== Directive::d_pairtypes
&& type
== 2))
167 gmx_fatal(FARGS
, "Invalid pairs type %d", type
);
169 case Directive::d_pairs_nb
:
170 return F_LJC_PAIRS_NB
;
171 case Directive::d_dihedrals
:
172 case Directive::d_dihedraltypes
:
188 return F_PDIHS
; /* proper dihedrals where we allow multiple terms over single bond */
194 gmx_fatal(FARGS
, "Invalid dihedral type %d", type
);
196 case Directive::d_cmaptypes
:
197 case Directive::d_cmap
:
200 case Directive::d_nonbond_params
:
209 case Directive::d_vsites2
:
217 gmx_fatal(FARGS
, "Invalid vsites2 type %d", type
);
219 case Directive::d_vsites3
:
231 gmx_fatal(FARGS
, "Invalid vsites3 type %d", type
);
233 case Directive::d_vsites4
:
241 gmx_fatal(FARGS
, "Invalid vsites4 type %d", type
);
243 case Directive::d_vsitesn
:
245 case Directive::d_constraints
:
246 case Directive::d_constrainttypes
:
254 gmx_fatal(FARGS
, "Invalid constraints type %d", type
);
256 case Directive::d_settles
:
258 case Directive::d_position_restraints
:
266 gmx_fatal(FARGS
, "Invalid position restraint type %d", type
);
268 case Directive::d_polarization
:
272 return F_POLARIZATION
;
276 gmx_fatal(FARGS
, "Invalid polarization type %d", type
);
278 case Directive::d_thole_polarization
:
280 case Directive::d_water_polarization
:
282 case Directive::d_angle_restraints
:
284 case Directive::d_angle_restraints_z
:
286 case Directive::d_distance_restraints
:
288 case Directive::d_orientation_restraints
:
290 case Directive::d_dihedral_restraints
:
293 gmx_fatal(FARGS
, "invalid directive %s in ifunc_index (%s:%d)",
294 dir2str(d
), __FILE__
, __LINE__
);
298 const char *dir2str (Directive d
)
300 int index
= static_cast<int>(d
);
301 return directive_names
[index
];
304 Directive
str2dir (char *dstr
)
306 char buf
[STRLEN
], *ptr
;
308 /* Hack to be able to read old topologies */
309 if (gmx_strncasecmp_min(dstr
, "dummies", 7) == 0)
311 sprintf(buf
, "virtual_sites%s", dstr
+7);
319 for (auto d
: gmx::EnumerationWrapper
<Directive
>())
321 if (gmx_strcasecmp_min(ptr
, dir2str(static_cast<Directive
>(d
))) == 0)
323 return static_cast<Directive
>(d
);
327 return Directive::d_invalid
;
330 static gmx::EnumerationArray
<Directive
, Directive
*> necessary
= {{ nullptr }};
332 static void set_nec(Directive
**n
, ...)
333 /* Must always have at least one extra argument */
342 d
= static_cast<Directive
>(va_arg(ap
, int));
346 while (d
!= Directive::d_none
);
350 void DS_Init(DirStack
**DS
)
352 if (necessary
[0] == nullptr)
354 set_nec(&(necessary
[Directive::d_defaults
]), Directive::d_none
);
355 set_nec(&(necessary
[Directive::d_atomtypes
]), Directive::d_defaults
, Directive::d_none
);
356 set_nec(&(necessary
[Directive::d_bondtypes
]), Directive::d_atomtypes
, Directive::d_none
);
357 set_nec(&(necessary
[Directive::d_constrainttypes
]), Directive::d_atomtypes
, Directive::d_none
);
358 set_nec(&(necessary
[Directive::d_pairtypes
]), Directive::d_atomtypes
, Directive::d_none
);
359 set_nec(&(necessary
[Directive::d_angletypes
]), Directive::d_atomtypes
, Directive::d_none
);
360 set_nec(&(necessary
[Directive::d_dihedraltypes
]), Directive::d_atomtypes
, Directive::d_none
);
361 set_nec(&(necessary
[Directive::d_nonbond_params
]), Directive::d_atomtypes
, Directive::d_none
);
362 // Note that the content of the next two directives are
363 // ignored, but if grompp reads them in old force field files,
364 // it still needs to understand that they are in a valid place
365 // in the .top structure. It doesn't have to require them to
366 // be in the same place that was valid in old versions (ie. child
367 // directive of [atomtypes]) but any relevant case will
369 set_nec(&(necessary
[Directive::d_implicit_genborn_params
]), Directive::d_atomtypes
, Directive::d_none
);
370 set_nec(&(necessary
[Directive::d_implicit_surface_params
]), Directive::d_atomtypes
, Directive::d_none
);
371 set_nec(&(necessary
[Directive::d_cmaptypes
]), Directive::d_atomtypes
, Directive::d_none
);
372 set_nec(&(necessary
[Directive::d_moleculetype
]), Directive::d_atomtypes
, Directive::d_none
);
373 set_nec(&(necessary
[Directive::d_atoms
]), Directive::d_moleculetype
, Directive::d_none
);
374 set_nec(&(necessary
[Directive::d_vsites2
]), Directive::d_atoms
, Directive::d_none
);
375 set_nec(&(necessary
[Directive::d_vsites3
]), Directive::d_atoms
, Directive::d_none
);
376 set_nec(&(necessary
[Directive::d_vsites4
]), Directive::d_atoms
, Directive::d_none
);
377 set_nec(&(necessary
[Directive::d_vsitesn
]), Directive::d_atoms
, Directive::d_none
);
378 set_nec(&(necessary
[Directive::d_bonds
]), Directive::d_atoms
, Directive::d_none
);
379 set_nec(&(necessary
[Directive::d_exclusions
]), Directive::d_bonds
, Directive::d_constraints
, Directive::d_settles
, Directive::d_none
);
380 set_nec(&(necessary
[Directive::d_pairs
]), Directive::d_atoms
, Directive::d_none
);
381 set_nec(&(necessary
[Directive::d_pairs_nb
]), Directive::d_atoms
, Directive::d_none
);
382 set_nec(&(necessary
[Directive::d_angles
]), Directive::d_atoms
, Directive::d_none
);
383 set_nec(&(necessary
[Directive::d_polarization
]), Directive::d_atoms
, Directive::d_none
);
384 set_nec(&(necessary
[Directive::d_water_polarization
]), Directive::d_atoms
, Directive::d_none
);
385 set_nec(&(necessary
[Directive::d_thole_polarization
]), Directive::d_atoms
, Directive::d_none
);
386 set_nec(&(necessary
[Directive::d_dihedrals
]), Directive::d_atoms
, Directive::d_none
);
387 set_nec(&(necessary
[Directive::d_constraints
]), Directive::d_atoms
, Directive::d_none
);
388 set_nec(&(necessary
[Directive::d_settles
]), Directive::d_atoms
, Directive::d_none
);
389 set_nec(&(necessary
[Directive::d_system
]), Directive::d_moleculetype
, Directive::d_none
);
390 set_nec(&(necessary
[Directive::d_molecules
]), Directive::d_system
, Directive::d_none
);
391 set_nec(&(necessary
[Directive::d_position_restraints
]), Directive::d_atoms
, Directive::d_none
);
392 set_nec(&(necessary
[Directive::d_angle_restraints
]), Directive::d_atoms
, Directive::d_none
);
393 set_nec(&(necessary
[Directive::d_angle_restraints_z
]), Directive::d_atoms
, Directive::d_none
);
394 set_nec(&(necessary
[Directive::d_distance_restraints
]), Directive::d_atoms
, Directive::d_none
);
395 set_nec(&(necessary
[Directive::d_orientation_restraints
]), Directive::d_atoms
, Directive::d_none
);
396 set_nec(&(necessary
[Directive::d_dihedral_restraints
]), Directive::d_atoms
, Directive::d_none
);
397 set_nec(&(necessary
[Directive::d_cmap
]), Directive::d_atoms
, Directive::d_none
);
398 set_nec(&(necessary
[Directive::d_intermolecular_interactions
]), Directive::d_molecules
, Directive::d_none
);
404 void DS_Done (DirStack
**DS
)
408 while (*DS
!= nullptr)
416 void DS_Push (DirStack
**DS
, Directive d
)
426 int DS_Search(DirStack
*DS
, Directive d
)
431 while ((D
!= nullptr) && (D
->d
!= d
))
436 return static_cast<int>(D
!= nullptr);
439 int DS_Check_Order(DirStack
*DS
, Directive d
)
444 /* Check if parameter definitions appear after a moleculetype directive */
445 if (d
< Directive::d_moleculetype
&& DS_Search(DS
, Directive::d_moleculetype
))
450 /* Check if all the necessary directives have appeared before directive d */
451 if (necessary
[d
][0] == Directive::d_none
)
459 d0
= necessary
[d
][i
++];
460 if (DS_Search(DS
, d0
))
465 while (d0
!= Directive::d_none
);