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:
211 case Directive::d_vsites3:
223 gmx_fatal(FARGS, "Invalid vsites3 type %d", type);
225 case Directive::d_vsites4:
233 gmx_fatal(FARGS, "Invalid vsites4 type %d", type);
235 case Directive::d_vsitesn:
237 case Directive::d_constraints:
238 case Directive::d_constrainttypes:
246 gmx_fatal(FARGS, "Invalid constraints type %d", type);
248 case Directive::d_settles:
250 case Directive::d_position_restraints:
258 gmx_fatal(FARGS, "Invalid position restraint type %d", type);
260 case Directive::d_polarization:
264 return F_POLARIZATION;
268 gmx_fatal(FARGS, "Invalid polarization type %d", type);
270 case Directive::d_thole_polarization:
272 case Directive::d_water_polarization:
274 case Directive::d_angle_restraints:
276 case Directive::d_angle_restraints_z:
278 case Directive::d_distance_restraints:
280 case Directive::d_orientation_restraints:
282 case Directive::d_dihedral_restraints:
285 gmx_fatal(FARGS, "invalid directive %s in ifunc_index (%s:%d)",
286 dir2str(d), __FILE__, __LINE__);
290 const char *dir2str (Directive d)
292 int index = static_cast<int>(d);
293 return directive_names[index];
296 Directive str2dir (char *dstr)
298 char buf[STRLEN], *ptr;
300 /* Hack to be able to read old topologies */
301 if (gmx_strncasecmp_min(dstr, "dummies", 7) == 0)
303 sprintf(buf, "virtual_sites%s", dstr+7);
311 for (auto d : gmx::EnumerationWrapper<Directive>())
313 if (gmx_strcasecmp_min(ptr, dir2str(static_cast<Directive>(d))) == 0)
315 return static_cast<Directive>(d);
319 return Directive::d_invalid;
322 static gmx::EnumerationArray<Directive, Directive *> necessary = {{ nullptr }};
324 static void set_nec(Directive **n, ...)
325 /* Must always have at least one extra argument */
334 d = static_cast<Directive>(va_arg(ap, int));
338 while (d != Directive::d_none);
342 void DS_Init(DirStack **DS)
344 if (necessary[0] == nullptr)
346 set_nec(&(necessary[Directive::d_defaults]), Directive::d_none);
347 set_nec(&(necessary[Directive::d_atomtypes]), Directive::d_defaults, Directive::d_none);
348 set_nec(&(necessary[Directive::d_bondtypes]), Directive::d_atomtypes, Directive::d_none);
349 set_nec(&(necessary[Directive::d_constrainttypes]), Directive::d_atomtypes, Directive::d_none);
350 set_nec(&(necessary[Directive::d_pairtypes]), Directive::d_atomtypes, Directive::d_none);
351 set_nec(&(necessary[Directive::d_angletypes]), Directive::d_atomtypes, Directive::d_none);
352 set_nec(&(necessary[Directive::d_dihedraltypes]), Directive::d_atomtypes, Directive::d_none);
353 set_nec(&(necessary[Directive::d_nonbond_params]), Directive::d_atomtypes, Directive::d_none);
354 // Note that the content of the next two directives are
355 // ignored, but if grompp reads them in old force field files,
356 // it still needs to understand that they are in a valid place
357 // in the .top structure. It doesn't have to require them to
358 // be in the same place that was valid in old versions (ie. child
359 // directive of [atomtypes]) but any relevant case will
361 set_nec(&(necessary[Directive::d_implicit_genborn_params]), Directive::d_atomtypes, Directive::d_none);
362 set_nec(&(necessary[Directive::d_implicit_surface_params]), Directive::d_atomtypes, Directive::d_none);
363 set_nec(&(necessary[Directive::d_cmaptypes]), Directive::d_atomtypes, Directive::d_none);
364 set_nec(&(necessary[Directive::d_moleculetype]), Directive::d_atomtypes, Directive::d_none);
365 set_nec(&(necessary[Directive::d_atoms]), Directive::d_moleculetype, Directive::d_none);
366 set_nec(&(necessary[Directive::d_vsites2]), Directive::d_atoms, Directive::d_none);
367 set_nec(&(necessary[Directive::d_vsites3]), Directive::d_atoms, Directive::d_none);
368 set_nec(&(necessary[Directive::d_vsites4]), Directive::d_atoms, Directive::d_none);
369 set_nec(&(necessary[Directive::d_vsitesn]), Directive::d_atoms, Directive::d_none);
370 set_nec(&(necessary[Directive::d_bonds]), Directive::d_atoms, Directive::d_none);
371 set_nec(&(necessary[Directive::d_exclusions]), Directive::d_bonds, Directive::d_constraints, Directive::d_settles, Directive::d_none);
372 set_nec(&(necessary[Directive::d_pairs]), Directive::d_atoms, Directive::d_none);
373 set_nec(&(necessary[Directive::d_pairs_nb]), Directive::d_atoms, Directive::d_none);
374 set_nec(&(necessary[Directive::d_angles]), Directive::d_atoms, Directive::d_none);
375 set_nec(&(necessary[Directive::d_polarization]), Directive::d_atoms, Directive::d_none);
376 set_nec(&(necessary[Directive::d_water_polarization]), Directive::d_atoms, Directive::d_none);
377 set_nec(&(necessary[Directive::d_thole_polarization]), Directive::d_atoms, Directive::d_none);
378 set_nec(&(necessary[Directive::d_dihedrals]), Directive::d_atoms, Directive::d_none);
379 set_nec(&(necessary[Directive::d_constraints]), Directive::d_atoms, Directive::d_none);
380 set_nec(&(necessary[Directive::d_settles]), Directive::d_atoms, Directive::d_none);
381 set_nec(&(necessary[Directive::d_system]), Directive::d_moleculetype, Directive::d_none);
382 set_nec(&(necessary[Directive::d_molecules]), Directive::d_system, Directive::d_none);
383 set_nec(&(necessary[Directive::d_position_restraints]), Directive::d_atoms, Directive::d_none);
384 set_nec(&(necessary[Directive::d_angle_restraints]), Directive::d_atoms, Directive::d_none);
385 set_nec(&(necessary[Directive::d_angle_restraints_z]), Directive::d_atoms, Directive::d_none);
386 set_nec(&(necessary[Directive::d_distance_restraints]), Directive::d_atoms, Directive::d_none);
387 set_nec(&(necessary[Directive::d_orientation_restraints]), Directive::d_atoms, Directive::d_none);
388 set_nec(&(necessary[Directive::d_dihedral_restraints]), Directive::d_atoms, Directive::d_none);
389 set_nec(&(necessary[Directive::d_cmap]), Directive::d_atoms, Directive::d_none);
390 set_nec(&(necessary[Directive::d_intermolecular_interactions]), Directive::d_molecules, Directive::d_none);
396 void DS_Done (DirStack **DS)
400 while (*DS != nullptr)
408 void DS_Push (DirStack **DS, Directive d)
418 int DS_Search(DirStack *DS, Directive d)
423 while ((D != nullptr) && (D->d != d))
428 return static_cast<int>(D != nullptr);
431 int DS_Check_Order(DirStack *DS, Directive d)
436 /* Check if parameter definitions appear after a moleculetype directive */
437 if (d < Directive::d_moleculetype && DS_Search(DS, Directive::d_moleculetype))
442 /* Check if all the necessary directives have appeared before directive d */
443 if (necessary[d][0] == Directive::d_none)
451 d0 = necessary[d][i++];
452 if (DS_Search(DS, d0))
457 while (d0 != Directive::d_none);