Remove unnecessary config.h includes
[alexxy/gromacs.git] / src / gromacs / gmxpreprocess / gen_vsite.c
index 55fcff5e458d71dbb7435c6875dc64621a795450..9743f690a6d7a7a271d2df1c703aa92a2f0154ea 100644 (file)
@@ -1,72 +1,76 @@
 /*
- * 
- *                This source code is part of
- * 
- *                 G   R   O   M   A   C   S
- * 
- *          GROningen MAchine for Chemical Simulations
- * 
- *                        VERSION 3.2.0
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * This file is part of the GROMACS molecular simulation package.
+ *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
  * of the License, or (at your option) any later version.
- * 
- * If you want to redistribute modifications, please consider that
- * scientific software is very special. Version control is crucial -
- * bugs must be traceable. We will be happy to consider code for
- * inclusion in the official distribution, but derived work must not
- * be called official GROMACS. Details are found in the README & COPYING
- * files - if they are missing, get the official version at www.gromacs.org.
- * 
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
  * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- * 
- * For more info, check our website at http://www.gromacs.org
- * 
- * And Hey:
- * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
+ * the research papers on the package. Check out http://www.gromacs.org.
  */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "gmxpre.h"
 
-#include "string2.h"
-#include <stdio.h>
 #include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
+
 #include "gen_vsite.h"
-#include "smalloc.h"
 #include "resall.h"
 #include "add_par.h"
-#include "vec.h"
+#include "gromacs/math/vec.h"
 #include "toputil.h"
-#include "physics.h"
-#include "index.h"
-#include "names.h"
-#include "futil.h"
+#include "gromacs/math/units.h"
+#include "gromacs/legacyheaders/names.h"
+#include "gromacs/utility/futil.h"
 #include "gpp_atomtype.h"
 #include "fflibutil.h"
-#include "macros.h"
+
+#include "gromacs/topology/residuetypes.h"
+#include "gromacs/topology/symtab.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/smalloc.h"
 
 #define MAXNAME 32
-#define OPENDIR        '['     /* starting sign for directive          */
-#define CLOSEDIR       ']'     /* ending sign for directive            */
+#define OPENDIR     '[' /* starting sign for directive         */
+#define CLOSEDIR    ']' /* ending sign for directive           */
 
 typedef struct {
-  char   atomtype[MAXNAME];      /* Type for the XH3/XH2 atom */
-  gmx_bool   isplanar;               /* If true, the atomtype above and the three connected
-                                 * ones are in a planar geometry. The two next entries
-                                 * are undefined in that case 
-                                 */
-  int    nhydrogens;             /* number of connected hydrogens */
-  char   nextheavytype[MAXNAME]; /* Type for the heavy atom bonded to XH2/XH3 */
-  char   dummymass[MAXNAME];     /* The type of MNH* or MCH3* dummy mass to use */
+    char       atomtype[MAXNAME];  /* Type for the XH3/XH2 atom */
+    gmx_bool   isplanar;           /* If true, the atomtype above and the three connected
+                                    * ones are in a planar geometry. The two next entries
+                                    * are undefined in that case
+                                    */
+    int    nhydrogens;             /* number of connected hydrogens */
+    char   nextheavytype[MAXNAME]; /* Type for the heavy atom bonded to XH2/XH3 */
+    char   dummymass[MAXNAME];     /* The type of MNH* or MCH3* dummy mass to use */
 } t_vsiteconf;
 
 
@@ -76,1836 +80,2164 @@ typedef struct {
  * 5-rings (i.e. the sum of angles is !=540, but impropers keep it planar)
  */
 typedef struct {
-  char resname[MAXNAME];
-  int nbonds;
-  int nangles;
-  struct vsitetop_bond {
-    char   atom1[MAXNAME];
-    char   atom2[MAXNAME];
-    float  value;
-  } *bond; /* list of bonds */
-  struct vsitetop_angle {
-    char   atom1[MAXNAME];
-    char   atom2[MAXNAME];
-    char   atom3[MAXNAME];
-    float  value;
-  } *angle; /* list of angles */
+    char resname[MAXNAME];
+    int  nbonds;
+    int  nangles;
+    struct vsitetop_bond {
+        char   atom1[MAXNAME];
+        char   atom2[MAXNAME];
+        float  value;
+    } *bond; /* list of bonds */
+    struct vsitetop_angle {
+        char   atom1[MAXNAME];
+        char   atom2[MAXNAME];
+        char   atom3[MAXNAME];
+        float  value;
+    } *angle; /* list of angles */
 } t_vsitetop;
 
 
-enum { DDB_CH3, DDB_NH3, DDB_NH2, DDB_PHE, DDB_TYR, 
-       DDB_TRP, DDB_HISA, DDB_HISB, DDB_HISH , DDB_DIR_NR };
+enum {
+    DDB_CH3, DDB_NH3, DDB_NH2, DDB_PHE, DDB_TYR,
+    DDB_TRP, DDB_HISA, DDB_HISB, DDB_HISH, DDB_DIR_NR
+};
 
 typedef char t_dirname[STRLEN];
 
 static const t_dirname ddb_dirnames[DDB_DIR_NR] = {
-  "CH3",
-  "NH3",
-  "NH2",
-  "PHE",
-  "TYR",
-  "TRP",
-  "HISA",
-  "HISB",
-  "HISH"
+    "CH3",
+    "NH3",
+    "NH2",
+    "PHE",
+    "TYR",
+    "TRP",
+    "HISA",
+    "HISB",
+    "HISH"
 };
 
-static int ddb_name2dir(char *name) 
+static int ddb_name2dir(char *name)
 {
-  /* Translate a directive name to the number of the directive.
-   * HID/HIE/HIP names are translated to the ones we use in Gromacs.
-   */
+    /* Translate a directive name to the number of the directive.
+     * HID/HIE/HIP names are translated to the ones we use in Gromacs.
+     */
+
+    int i, index;
 
-  int i,index;
+    index = -1;
 
-  index=-1;
+    for (i = 0; i < DDB_DIR_NR && index < 0; i++)
+    {
+        if (!gmx_strcasecmp(name, ddb_dirnames[i]))
+        {
+            index = i;
+        }
+    }
 
-  for(i=0;i<DDB_DIR_NR && index<0;i++)
-    if(!gmx_strcasecmp(name,ddb_dirnames[i]))
-      index=i;
-  
-  return index;
+    return index;
 }
 
 
 static void read_vsite_database(const char *ddbname,
-                               t_vsiteconf **pvsiteconflist, int *nvsiteconf,
-                               t_vsitetop **pvsitetoplist, int *nvsitetop)
+                                t_vsiteconf **pvsiteconflist, int *nvsiteconf,
+                                t_vsitetop **pvsitetoplist, int *nvsitetop)
 {
-  /* This routine is a quick hack to fix the problem with hardcoded atomtypes
-   * and aromatic vsite parameters by reading them from a ff???.vsd file.
-   *
-   * The file can contain sections [ NH3 ], [ CH3 ], [ NH2 ], and ring residue names.
-   * For the NH3 and CH3 section each line has three fields. The first is the atomtype 
-   * (nb: not bonded type) of the N/C atom to be replaced, the second field is
-   * the type of the next heavy atom it is bonded to, and the third field the type
-   * of dummy mass that will be used for this group. 
-   * 
-   * If the NH2 group planar (sp2 N) a different vsite construct is used, so in this
-   * case the second field should just be the word planar.
-   */
-
-  FILE *ddb;
-  char dirstr[STRLEN];
-  char pline[STRLEN];
-  int i,j,n,k,nvsite,ntop,curdir,prevdir;
-  t_vsiteconf *vsiteconflist;
-  t_vsitetop *vsitetoplist;
-  char *ch;
-  char s1[MAXNAME],s2[MAXNAME],s3[MAXNAME],s4[MAXNAME];
-
-  ddb = libopen(ddbname);
-
-  nvsite        = *nvsiteconf;
-  vsiteconflist = *pvsiteconflist;
-  ntop          = *nvsitetop;
-  vsitetoplist  = *pvsitetoplist;
-
-  curdir=-1;
-  
-  snew(vsiteconflist,1);
-  snew(vsitetoplist,1);
-
-  while(fgets2(pline,STRLEN-2,ddb) != NULL) {
-    strip_comment(pline);
-    trim(pline);
-    if(strlen(pline)>0) {
-      if(pline[0] == OPENDIR ) {
-       strncpy(dirstr,pline+1,STRLEN-2);
-       if ((ch = strchr (dirstr,CLOSEDIR)) != NULL)
-         (*ch) = 0;
-       trim (dirstr);
-
-       if(!gmx_strcasecmp(dirstr,"HID") ||
-          !gmx_strcasecmp(dirstr,"HISD"))
-         sprintf(dirstr,"HISA");
-       else if(!gmx_strcasecmp(dirstr,"HIE") ||
-               !gmx_strcasecmp(dirstr,"HISE"))
-         sprintf(dirstr,"HISB");
-       else if(!gmx_strcasecmp(dirstr,"HIP"))
-         sprintf(dirstr,"HISH");
-
-       curdir=ddb_name2dir(dirstr);
-       if (curdir < 0) {
-         gmx_fatal(FARGS,"Invalid directive %s in vsite database %s",
-                   dirstr,ddbname);
-       }
-      } else {
-       switch(curdir) {
-       case -1:
-         gmx_fatal(FARGS,"First entry in vsite database must be a directive.\n");
-         break;
-       case DDB_CH3:
-       case DDB_NH3:
-       case DDB_NH2:
-         n = sscanf(pline,"%s%s%s",s1,s2,s3);
-         if(n<3 && !gmx_strcasecmp(s2,"planar")) {
-           srenew(vsiteconflist,nvsite+1);
-           strncpy(vsiteconflist[nvsite].atomtype,s1,MAXNAME-1);
-           vsiteconflist[nvsite].isplanar=TRUE;
-           vsiteconflist[nvsite].nextheavytype[0]=0;
-           vsiteconflist[nvsite].dummymass[0]=0;
-           vsiteconflist[nvsite].nhydrogens=2;
-           nvsite++;
-         } else if(n==3) {
-           srenew(vsiteconflist,(nvsite+1));
-           strncpy(vsiteconflist[nvsite].atomtype,s1,MAXNAME-1);
-           vsiteconflist[nvsite].isplanar=FALSE;
-           strncpy(vsiteconflist[nvsite].nextheavytype,s2,MAXNAME-1);
-           strncpy(vsiteconflist[nvsite].dummymass,s3,MAXNAME-1);
-           if(curdir==DDB_NH2)
-             vsiteconflist[nvsite].nhydrogens=2;
-           else
-             vsiteconflist[nvsite].nhydrogens=3;
-           nvsite++;
-         } else {
-           gmx_fatal(FARGS,"Not enough directives in vsite database line: %s\n",pline);
-         }
-         break;
-       case DDB_PHE:
-       case DDB_TYR:
-       case DDB_TRP:
-       case DDB_HISA:
-       case DDB_HISB:
-       case DDB_HISH:
-         i=0;
-         while((i<ntop) && gmx_strcasecmp(dirstr,vsitetoplist[i].resname))
-           i++;
-         /* Allocate a new topology entry if this is a new residue */
-         if(i==ntop) {
-           srenew(vsitetoplist,ntop+1);            
-           ntop++; /* i still points to current vsite topology entry */
-           strncpy(vsitetoplist[i].resname,dirstr,MAXNAME-1);
-           vsitetoplist[i].nbonds=vsitetoplist[i].nangles=0;
-           snew(vsitetoplist[i].bond,1);
-           snew(vsitetoplist[i].angle,1);
-         }
-         n = sscanf(pline,"%s%s%s%s",s1,s2,s3,s4);
-         if(n==3) {
-           /* bond */
-           k=vsitetoplist[i].nbonds++;
-           srenew(vsitetoplist[i].bond,k+1);
-           strncpy(vsitetoplist[i].bond[k].atom1,s1,MAXNAME-1);
-           strncpy(vsitetoplist[i].bond[k].atom2,s2,MAXNAME-1);
-           vsitetoplist[i].bond[k].value=strtod(s3,NULL);
-         } else if (n==4) {
-           /* angle */
-           k=vsitetoplist[i].nangles++;
-           srenew(vsitetoplist[i].angle,k+1);
-           strncpy(vsitetoplist[i].angle[k].atom1,s1,MAXNAME-1);
-           strncpy(vsitetoplist[i].angle[k].atom2,s2,MAXNAME-1);
-           strncpy(vsitetoplist[i].angle[k].atom3,s3,MAXNAME-1);
-           vsitetoplist[i].angle[k].value=strtod(s4,NULL);
-         } else {
-           gmx_fatal(FARGS,"Need 3 or 4 values to specify bond/angle values in %s: %s\n",ddbname,pline);
-         }
-         break;
-       default:
-         gmx_fatal(FARGS,"Didnt find a case for directive %s in read_vsite_database\n",dirstr);
-       }
-      }
-    }
-  }
-
-  *pvsiteconflist=vsiteconflist;
-  *pvsitetoplist=vsitetoplist;
-  *nvsiteconf=nvsite;
-  *nvsitetop=ntop;
-  
-  ffclose(ddb);
+    /* This routine is a quick hack to fix the problem with hardcoded atomtypes
+     * and aromatic vsite parameters by reading them from a ff???.vsd file.
+     *
+     * The file can contain sections [ NH3 ], [ CH3 ], [ NH2 ], and ring residue names.
+     * For the NH3 and CH3 section each line has three fields. The first is the atomtype
+     * (nb: not bonded type) of the N/C atom to be replaced, the second field is
+     * the type of the next heavy atom it is bonded to, and the third field the type
+     * of dummy mass that will be used for this group.
+     *
+     * If the NH2 group planar (sp2 N) a different vsite construct is used, so in this
+     * case the second field should just be the word planar.
+     */
+
+    FILE        *ddb;
+    char         dirstr[STRLEN];
+    char         pline[STRLEN];
+    int          i, j, n, k, nvsite, ntop, curdir, prevdir;
+    t_vsiteconf *vsiteconflist;
+    t_vsitetop  *vsitetoplist;
+    char        *ch;
+    char         s1[MAXNAME], s2[MAXNAME], s3[MAXNAME], s4[MAXNAME];
+
+    ddb = libopen(ddbname);
+
+    nvsite        = *nvsiteconf;
+    vsiteconflist = *pvsiteconflist;
+    ntop          = *nvsitetop;
+    vsitetoplist  = *pvsitetoplist;
+
+    curdir = -1;
+
+    snew(vsiteconflist, 1);
+    snew(vsitetoplist, 1);
+
+    while (fgets2(pline, STRLEN-2, ddb) != NULL)
+    {
+        strip_comment(pline);
+        trim(pline);
+        if (strlen(pline) > 0)
+        {
+            if (pline[0] == OPENDIR)
+            {
+                strncpy(dirstr, pline+1, STRLEN-2);
+                if ((ch = strchr (dirstr, CLOSEDIR)) != NULL)
+                {
+                    (*ch) = 0;
+                }
+                trim (dirstr);
+
+                if (!gmx_strcasecmp(dirstr, "HID") ||
+                    !gmx_strcasecmp(dirstr, "HISD"))
+                {
+                    sprintf(dirstr, "HISA");
+                }
+                else if (!gmx_strcasecmp(dirstr, "HIE") ||
+                         !gmx_strcasecmp(dirstr, "HISE"))
+                {
+                    sprintf(dirstr, "HISB");
+                }
+                else if (!gmx_strcasecmp(dirstr, "HIP"))
+                {
+                    sprintf(dirstr, "HISH");
+                }
+
+                curdir = ddb_name2dir(dirstr);
+                if (curdir < 0)
+                {
+                    gmx_fatal(FARGS, "Invalid directive %s in vsite database %s",
+                              dirstr, ddbname);
+                }
+            }
+            else
+            {
+                switch (curdir)
+                {
+                    case -1:
+                        gmx_fatal(FARGS, "First entry in vsite database must be a directive.\n");
+                        break;
+                    case DDB_CH3:
+                    case DDB_NH3:
+                    case DDB_NH2:
+                        n = sscanf(pline, "%s%s%s", s1, s2, s3);
+                        if (n < 3 && !gmx_strcasecmp(s2, "planar"))
+                        {
+                            srenew(vsiteconflist, nvsite+1);
+                            strncpy(vsiteconflist[nvsite].atomtype, s1, MAXNAME-1);
+                            vsiteconflist[nvsite].isplanar         = TRUE;
+                            vsiteconflist[nvsite].nextheavytype[0] = 0;
+                            vsiteconflist[nvsite].dummymass[0]     = 0;
+                            vsiteconflist[nvsite].nhydrogens       = 2;
+                            nvsite++;
+                        }
+                        else if (n == 3)
+                        {
+                            srenew(vsiteconflist, (nvsite+1));
+                            strncpy(vsiteconflist[nvsite].atomtype, s1, MAXNAME-1);
+                            vsiteconflist[nvsite].isplanar = FALSE;
+                            strncpy(vsiteconflist[nvsite].nextheavytype, s2, MAXNAME-1);
+                            strncpy(vsiteconflist[nvsite].dummymass, s3, MAXNAME-1);
+                            if (curdir == DDB_NH2)
+                            {
+                                vsiteconflist[nvsite].nhydrogens = 2;
+                            }
+                            else
+                            {
+                                vsiteconflist[nvsite].nhydrogens = 3;
+                            }
+                            nvsite++;
+                        }
+                        else
+                        {
+                            gmx_fatal(FARGS, "Not enough directives in vsite database line: %s\n", pline);
+                        }
+                        break;
+                    case DDB_PHE:
+                    case DDB_TYR:
+                    case DDB_TRP:
+                    case DDB_HISA:
+                    case DDB_HISB:
+                    case DDB_HISH:
+                        i = 0;
+                        while ((i < ntop) && gmx_strcasecmp(dirstr, vsitetoplist[i].resname))
+                        {
+                            i++;
+                        }
+                        /* Allocate a new topology entry if this is a new residue */
+                        if (i == ntop)
+                        {
+                            srenew(vsitetoplist, ntop+1);
+                            ntop++; /* i still points to current vsite topology entry */
+                            strncpy(vsitetoplist[i].resname, dirstr, MAXNAME-1);
+                            vsitetoplist[i].nbonds = vsitetoplist[i].nangles = 0;
+                            snew(vsitetoplist[i].bond, 1);
+                            snew(vsitetoplist[i].angle, 1);
+                        }
+                        n = sscanf(pline, "%s%s%s%s", s1, s2, s3, s4);
+                        if (n == 3)
+                        {
+                            /* bond */
+                            k = vsitetoplist[i].nbonds++;
+                            srenew(vsitetoplist[i].bond, k+1);
+                            strncpy(vsitetoplist[i].bond[k].atom1, s1, MAXNAME-1);
+                            strncpy(vsitetoplist[i].bond[k].atom2, s2, MAXNAME-1);
+                            vsitetoplist[i].bond[k].value = strtod(s3, NULL);
+                        }
+                        else if (n == 4)
+                        {
+                            /* angle */
+                            k = vsitetoplist[i].nangles++;
+                            srenew(vsitetoplist[i].angle, k+1);
+                            strncpy(vsitetoplist[i].angle[k].atom1, s1, MAXNAME-1);
+                            strncpy(vsitetoplist[i].angle[k].atom2, s2, MAXNAME-1);
+                            strncpy(vsitetoplist[i].angle[k].atom3, s3, MAXNAME-1);
+                            vsitetoplist[i].angle[k].value = strtod(s4, NULL);
+                        }
+                        else
+                        {
+                            gmx_fatal(FARGS, "Need 3 or 4 values to specify bond/angle values in %s: %s\n", ddbname, pline);
+                        }
+                        break;
+                    default:
+                        gmx_fatal(FARGS, "Didnt find a case for directive %s in read_vsite_database\n", dirstr);
+                }
+            }
+        }
+    }
+
+    *pvsiteconflist = vsiteconflist;
+    *pvsitetoplist  = vsitetoplist;
+    *nvsiteconf     = nvsite;
+    *nvsitetop      = ntop;
+
+    gmx_ffclose(ddb);
 }
 
-static int nitrogen_is_planar(t_vsiteconf vsiteconflist[],int nvsiteconf,char atomtype[])
+static int nitrogen_is_planar(t_vsiteconf vsiteconflist[], int nvsiteconf, char atomtype[])
 {
-  /* Return 1 if atomtype exists in database list and is planar, 0 if not,
-   * and -1 if not found.
-   */
-  int i,res;
-  gmx_bool found=FALSE;
-  for(i=0;i<nvsiteconf && !found;i++) {
-    found=(!gmx_strcasecmp(vsiteconflist[i].atomtype,atomtype) && (vsiteconflist[i].nhydrogens==2));
-  }
-  if(found)
-    res=(vsiteconflist[i-1].isplanar==TRUE);
-  else
-    res=-1;
-
-  return res;
+    /* Return 1 if atomtype exists in database list and is planar, 0 if not,
+     * and -1 if not found.
+     */
+    int      i, res;
+    gmx_bool found = FALSE;
+    for (i = 0; i < nvsiteconf && !found; i++)
+    {
+        found = (!gmx_strcasecmp(vsiteconflist[i].atomtype, atomtype) && (vsiteconflist[i].nhydrogens == 2));
+    }
+    if (found)
+    {
+        res = (vsiteconflist[i-1].isplanar == TRUE);
+    }
+    else
+    {
+        res = -1;
+    }
+
+    return res;
 }
-  
-static char *get_dummymass_name(t_vsiteconf vsiteconflist[],int nvsiteconf,char atom[], char nextheavy[])
+
+static char *get_dummymass_name(t_vsiteconf vsiteconflist[], int nvsiteconf, char atom[], char nextheavy[])
 {
-  /* Return the dummy mass name if found, or NULL if not set in ddb database */
-  int i;
-  gmx_bool found=FALSE;
-  for(i=0;i<nvsiteconf && !found;i++) {
-    found=(!gmx_strcasecmp(vsiteconflist[i].atomtype,atom) &&
-          !gmx_strcasecmp(vsiteconflist[i].nextheavytype,nextheavy));
-  }
-  if(found)
-    return vsiteconflist[i-1].dummymass;
-  else
-    return NULL;
+    /* Return the dummy mass name if found, or NULL if not set in ddb database */
+    int      i;
+    gmx_bool found = FALSE;
+    for (i = 0; i < nvsiteconf && !found; i++)
+    {
+        found = (!gmx_strcasecmp(vsiteconflist[i].atomtype, atom) &&
+                 !gmx_strcasecmp(vsiteconflist[i].nextheavytype, nextheavy));
+    }
+    if (found)
+    {
+        return vsiteconflist[i-1].dummymass;
+    }
+    else
+    {
+        return NULL;
+    }
 }
-  
+
 
 
 static real get_ddb_bond(t_vsitetop *vsitetop, int nvsitetop,
-                        const char res[],
-                        const char atom1[], const char atom2[])
+                         const char res[],
+                         const char atom1[], const char atom2[])
 {
-  int i,j;
-  
-  i=0;
-  while(i<nvsitetop && gmx_strcasecmp(res,vsitetop[i].resname))
-    i++;
-  if(i==nvsitetop)
-    gmx_fatal(FARGS,"No vsite information for residue %s found in vsite database.\n",res);
-  j=0;
-  while(j<vsitetop[i].nbonds && 
-       ( strcmp(atom1,vsitetop[i].bond[j].atom1) || strcmp(atom2,vsitetop[i].bond[j].atom2)) &&
-       ( strcmp(atom2,vsitetop[i].bond[j].atom1) || strcmp(atom1,vsitetop[i].bond[j].atom2)))
-    j++;
-  if(j==vsitetop[i].nbonds)
-    gmx_fatal(FARGS,"Couldnt find bond %s-%s for residue %s in vsite database.\n",atom1,atom2,res);
-  
-  return vsitetop[i].bond[j].value;
+    int i, j;
+
+    i = 0;
+    while (i < nvsitetop && gmx_strcasecmp(res, vsitetop[i].resname))
+    {
+        i++;
+    }
+    if (i == nvsitetop)
+    {
+        gmx_fatal(FARGS, "No vsite information for residue %s found in vsite database.\n", res);
+    }
+    j = 0;
+    while (j < vsitetop[i].nbonds &&
+           ( strcmp(atom1, vsitetop[i].bond[j].atom1) || strcmp(atom2, vsitetop[i].bond[j].atom2)) &&
+           ( strcmp(atom2, vsitetop[i].bond[j].atom1) || strcmp(atom1, vsitetop[i].bond[j].atom2)))
+    {
+        j++;
+    }
+    if (j == vsitetop[i].nbonds)
+    {
+        gmx_fatal(FARGS, "Couldnt find bond %s-%s for residue %s in vsite database.\n", atom1, atom2, res);
+    }
+
+    return vsitetop[i].bond[j].value;
 }
-      
+
 
 static real get_ddb_angle(t_vsitetop *vsitetop, int nvsitetop,
-                         const char res[], const char atom1[],
-                         const char atom2[], const char atom3[])
+                          const char res[], const char atom1[],
+                          const char atom2[], const char atom3[])
 {
-  int i,j;
-  
-  i=0;
-  while(i<nvsitetop && gmx_strcasecmp(res,vsitetop[i].resname))
-    i++;
-  if(i==nvsitetop)
-    gmx_fatal(FARGS,"No vsite information for residue %s found in vsite database.\n",res);
-  j=0;
-  while(j<vsitetop[i].nangles && 
-       ( strcmp(atom1,vsitetop[i].angle[j].atom1) || 
-         strcmp(atom2,vsitetop[i].angle[j].atom2) || 
-         strcmp(atom3,vsitetop[i].angle[j].atom3)) &&
-       ( strcmp(atom3,vsitetop[i].angle[j].atom1) || 
-         strcmp(atom2,vsitetop[i].angle[j].atom2) || 
-         strcmp(atom1,vsitetop[i].angle[j].atom3)))
-    j++;
-  if(j==vsitetop[i].nangles)
-    gmx_fatal(FARGS,"Couldnt find angle %s-%s-%s for residue %s in vsite database.\n",atom1,atom2,atom3,res);
-  
-  return vsitetop[i].angle[j].value;
+    int i, j;
+
+    i = 0;
+    while (i < nvsitetop && gmx_strcasecmp(res, vsitetop[i].resname))
+    {
+        i++;
+    }
+    if (i == nvsitetop)
+    {
+        gmx_fatal(FARGS, "No vsite information for residue %s found in vsite database.\n", res);
+    }
+    j = 0;
+    while (j < vsitetop[i].nangles &&
+           ( strcmp(atom1, vsitetop[i].angle[j].atom1) ||
+             strcmp(atom2, vsitetop[i].angle[j].atom2) ||
+             strcmp(atom3, vsitetop[i].angle[j].atom3)) &&
+           ( strcmp(atom3, vsitetop[i].angle[j].atom1) ||
+             strcmp(atom2, vsitetop[i].angle[j].atom2) ||
+             strcmp(atom1, vsitetop[i].angle[j].atom3)))
+    {
+        j++;
+    }
+    if (j == vsitetop[i].nangles)
+    {
+        gmx_fatal(FARGS, "Couldnt find angle %s-%s-%s for residue %s in vsite database.\n", atom1, atom2, atom3, res);
+    }
+
+    return vsitetop[i].angle[j].value;
 }
-      
 
-static void count_bonds(int atom, t_params *psb, char ***atomname, 
-                       int *nrbonds, int *nrHatoms, int Hatoms[], int *Heavy,
-                       int *nrheavies, int heavies[])
+
+static void count_bonds(int atom, t_params *psb, char ***atomname,
+                        int *nrbonds, int *nrHatoms, int Hatoms[], int *Heavy,
+                        int *nrheavies, int heavies[])
 {
-  int i,heavy,other,nrb,nrH,nrhv;
-  
-  /* find heavy atom bound to this hydrogen */
-  heavy=NOTSET;
-  for(i=0; (i<psb->nr) && (heavy==NOTSET); i++)
-    if (psb->param[i].AI==atom)
-      heavy=psb->param[i].AJ;
-    else if (psb->param[i].AJ==atom)
-      heavy=psb->param[i].AI;
-  if (heavy==NOTSET)
-    gmx_fatal(FARGS,"unbound hydrogen atom %d",atom+1);
-  /* find all atoms bound to heavy atom */
-  other=NOTSET;
-  nrb=0;
-  nrH=0;
-  nrhv=0;
-  for(i=0; i<psb->nr; i++) {
-    if (psb->param[i].AI==heavy)
-      other=psb->param[i].AJ;
-    else if (psb->param[i].AJ==heavy)
-      other=psb->param[i].AI;
-    if (other!=NOTSET) {
-      nrb++;
-      if (is_hydrogen(*(atomname[other]))) {
-       Hatoms[nrH]=other;
-       nrH++;
-      } else {
-       heavies[nrhv]=other;
-       nrhv++;
-      }
-      other=NOTSET;
-    }
-  }
-  *Heavy   =heavy;
-  *nrbonds =nrb;
-  *nrHatoms=nrH;
-  *nrheavies=nrhv;
+    int i, heavy, other, nrb, nrH, nrhv;
+
+    /* find heavy atom bound to this hydrogen */
+    heavy = NOTSET;
+    for (i = 0; (i < psb->nr) && (heavy == NOTSET); i++)
+    {
+        if (psb->param[i].AI == atom)
+        {
+            heavy = psb->param[i].AJ;
+        }
+        else if (psb->param[i].AJ == atom)
+        {
+            heavy = psb->param[i].AI;
+        }
+    }
+    if (heavy == NOTSET)
+    {
+        gmx_fatal(FARGS, "unbound hydrogen atom %d", atom+1);
+    }
+    /* find all atoms bound to heavy atom */
+    other = NOTSET;
+    nrb   = 0;
+    nrH   = 0;
+    nrhv  = 0;
+    for (i = 0; i < psb->nr; i++)
+    {
+        if (psb->param[i].AI == heavy)
+        {
+            other = psb->param[i].AJ;
+        }
+        else if (psb->param[i].AJ == heavy)
+        {
+            other = psb->param[i].AI;
+        }
+        if (other != NOTSET)
+        {
+            nrb++;
+            if (is_hydrogen(*(atomname[other])))
+            {
+                Hatoms[nrH] = other;
+                nrH++;
+            }
+            else
+            {
+                heavies[nrhv] = other;
+                nrhv++;
+            }
+            other = NOTSET;
+        }
+    }
+    *Heavy     = heavy;
+    *nrbonds   = nrb;
+    *nrHatoms  = nrH;
+    *nrheavies = nrhv;
 }
 
 static void print_bonds(FILE *fp, int o2n[],
-                       int nrHatoms, int Hatoms[], int Heavy,
-                       int nrheavies, int heavies[])
+                        int nrHatoms, int Hatoms[], int Heavy,
+                        int nrheavies, int heavies[])
 {
-  int i;
-  
-  fprintf(fp,"Found: %d Hatoms: ",nrHatoms);
-  for(i=0; i<nrHatoms; i++)
-    fprintf(fp," %d",o2n[Hatoms[i]]+1);
-  fprintf(fp,"; %d Heavy atoms: %d",nrheavies+1,o2n[Heavy]+1);
-  for(i=0; i<nrheavies; i++)
-    fprintf(fp," %d",o2n[heavies[i]]+1);
-  fprintf(fp,"\n");
+    int i;
+
+    fprintf(fp, "Found: %d Hatoms: ", nrHatoms);
+    for (i = 0; i < nrHatoms; i++)
+    {
+        fprintf(fp, " %d", o2n[Hatoms[i]]+1);
+    }
+    fprintf(fp, "; %d Heavy atoms: %d", nrheavies+1, o2n[Heavy]+1);
+    for (i = 0; i < nrheavies; i++)
+    {
+        fprintf(fp, " %d", o2n[heavies[i]]+1);
+    }
+    fprintf(fp, "\n");
 }
 
 static int get_atype(int atom, t_atoms *at, int nrtp, t_restp rtp[],
-                     gmx_residuetype_t rt)
+                     gmx_residuetype_t *rt)
 {
-  int type;
-  gmx_bool bNterm;
-  int  j;
-  t_restp *rtpp;
-  
-  if (at->atom[atom].m)
-    type=at->atom[atom].type;
-  else {
-    /* get type from rtp */
-    rtpp = get_restp(*(at->resinfo[at->atom[atom].resind].name),nrtp,rtp);
-    bNterm = gmx_residuetype_is_protein(rt,*(at->resinfo[at->atom[atom].resind].name)) && 
-      (at->atom[atom].resind == 0);
-    j=search_jtype(rtpp,*(at->atomname[atom]),bNterm);
-    type=rtpp->atom[j].type;
-  }
-  return type;
+    int      type;
+    gmx_bool bNterm;
+    int      j;
+    t_restp *rtpp;
+
+    if (at->atom[atom].m)
+    {
+        type = at->atom[atom].type;
+    }
+    else
+    {
+        /* get type from rtp */
+        rtpp   = get_restp(*(at->resinfo[at->atom[atom].resind].name), nrtp, rtp);
+        bNterm = gmx_residuetype_is_protein(rt, *(at->resinfo[at->atom[atom].resind].name)) &&
+            (at->atom[atom].resind == 0);
+        j    = search_jtype(rtpp, *(at->atomname[atom]), bNterm);
+        type = rtpp->atom[j].type;
+    }
+    return type;
 }
 
 static int vsite_nm2type(const char *name, gpp_atomtype_t atype)
 {
-  int tp;
-  
-  tp = get_atomtype_type(name,atype);
-  if (tp == NOTSET)
-    gmx_fatal(FARGS,"Dummy mass type (%s) not found in atom type database",
-             name);
-             
-  return tp;
+    int tp;
+
+    tp = get_atomtype_type(name, atype);
+    if (tp == NOTSET)
+    {
+        gmx_fatal(FARGS, "Dummy mass type (%s) not found in atom type database",
+                  name);
+    }
+
+    return tp;
 }
 
 static real get_amass(int atom, t_atoms *at, int nrtp, t_restp rtp[],
-                      gmx_residuetype_t rt)
+                      gmx_residuetype_t *rt)
 {
-  real mass;
-  gmx_bool bNterm;
-  int  j;
-  t_restp *rtpp;
-  
-  if (at->atom[atom].m)
-    mass=at->atom[atom].m;
-  else {
-    /* get mass from rtp */
-    rtpp = get_restp(*(at->resinfo[at->atom[atom].resind].name),nrtp,rtp);
-    bNterm = gmx_residuetype_is_protein(rt,*(at->resinfo[at->atom[atom].resind].name)) && 
-      (at->atom[atom].resind == 0);
-    j=search_jtype(rtpp,*(at->atomname[atom]),bNterm);
-    mass=rtpp->atom[j].m;
-  }
-  return mass;
+    real     mass;
+    gmx_bool bNterm;
+    int      j;
+    t_restp *rtpp;
+
+    if (at->atom[atom].m)
+    {
+        mass = at->atom[atom].m;
+    }
+    else
+    {
+        /* get mass from rtp */
+        rtpp   = get_restp(*(at->resinfo[at->atom[atom].resind].name), nrtp, rtp);
+        bNterm = gmx_residuetype_is_protein(rt, *(at->resinfo[at->atom[atom].resind].name)) &&
+            (at->atom[atom].resind == 0);
+        j    = search_jtype(rtpp, *(at->atomname[atom]), bNterm);
+        mass = rtpp->atom[j].m;
+    }
+    return mass;
 }
 
 static void my_add_param(t_params *plist, int ai, int aj, real b)
 {
-  static real c[MAXFORCEPARAM] = 
-  { NOTSET, NOTSET, NOTSET, NOTSET, NOTSET, NOTSET };
-  
-  c[0]=b;
-  add_param(plist,ai,aj,c,NULL);
+    static real c[MAXFORCEPARAM] =
+    { NOTSET, NOTSET, NOTSET, NOTSET, NOTSET, NOTSET };
+
+    c[0] = b;
+    add_param(plist, ai, aj, c, NULL);
 }
 
-static void add_vsites(t_params plist[], int vsite_type[], 
-                      int Heavy, int nrHatoms, int Hatoms[], 
-                      int nrheavies, int heavies[])
+static void add_vsites(t_params plist[], int vsite_type[],
+                       int Heavy, int nrHatoms, int Hatoms[],
+                       int nrheavies, int heavies[])
 {
-  int i,j,ftype,other,moreheavy,bb;
-  gmx_bool bSwapParity;
-  
-  for(i=0; i<nrHatoms; i++) {
-    ftype=vsite_type[Hatoms[i]];
-    /* Errors in setting the vsite_type should really be caugth earlier,
-     * because here it's not possible to print any useful error message.
-     * But it's still better to print a message than to segfault.
-     */
-    if (ftype == NOTSET) {
-      gmx_incons("Undetected error in setting up virtual sites");
-    }
-    bSwapParity = (ftype<0);
-    vsite_type[Hatoms[i]] = ftype = abs(ftype);
-    if (ftype == F_BONDS) {
-      if ( (nrheavies != 1) && (nrHatoms != 1) )
-       gmx_fatal(FARGS,"cannot make constraint in add_vsites for %d heavy "
-                   "atoms and %d hydrogen atoms",nrheavies,nrHatoms);
-      my_add_param(&(plist[F_CONSTRNC]),Hatoms[i],heavies[0],NOTSET);
-    } else {
-      switch (ftype) {
-      case F_VSITE3:
-      case F_VSITE3FD:
-      case F_VSITE3OUT:
-       if (nrheavies < 2) 
-         gmx_fatal(FARGS,"Not enough heavy atoms (%d) for %s (min 3)",
-                     nrheavies+1,
-                     interaction_function[vsite_type[Hatoms[i]]].name);
-       add_vsite3_atoms(&plist[ftype],Hatoms[i],Heavy,heavies[0],heavies[1],
-                      bSwapParity);
-       break;
-      case F_VSITE3FAD: {
-       if (nrheavies > 1)
-         moreheavy=heavies[1];
-       else {
-         /* find more heavy atoms */
-         other=moreheavy=NOTSET;
-         for(j=0; (j<plist[F_BONDS].nr) && (moreheavy==NOTSET); j++) {
-           if (plist[F_BONDS].param[j].AI==heavies[0])
-             other=plist[F_BONDS].param[j].AJ;
-           else if (plist[F_BONDS].param[j].AJ==heavies[0])
-             other=plist[F_BONDS].param[j].AI;
-           if ( (other != NOTSET) && (other != Heavy) ) 
-             moreheavy=other;
-         }
-         if (moreheavy==NOTSET)
-           gmx_fatal(FARGS,"Unbound molecule part %d-%d",Heavy+1,Hatoms[0]+1);
-       }
-       add_vsite3_atoms(&plist[ftype],Hatoms[i],Heavy,heavies[0],moreheavy,
-                      bSwapParity);
-       break;
-      }
-      case F_VSITE4FD: 
-      case F_VSITE4FDN:
-          if (nrheavies < 3) 
-          {
-              gmx_fatal(FARGS,"Not enough heavy atoms (%d) for %s (min 4)",
-                        nrheavies+1,
-                        interaction_function[vsite_type[Hatoms[i]]].name);
-          }
-          add_vsite4_atoms(&plist[ftype],  
-                           Hatoms[0], Heavy, heavies[0], heavies[1], heavies[2]);
-          break;
-      
-      default:
-       gmx_fatal(FARGS,"can't use add_vsites for interaction function %s",
-                   interaction_function[vsite_type[Hatoms[i]]].name);
-      } /* switch ftype */
-    } /* else */
-  } /* for i */
+    int      i, j, ftype, other, moreheavy, bb;
+    gmx_bool bSwapParity;
+
+    for (i = 0; i < nrHatoms; i++)
+    {
+        ftype = vsite_type[Hatoms[i]];
+        /* Errors in setting the vsite_type should really be caugth earlier,
+         * because here it's not possible to print any useful error message.
+         * But it's still better to print a message than to segfault.
+         */
+        if (ftype == NOTSET)
+        {
+            gmx_incons("Undetected error in setting up virtual sites");
+        }
+        bSwapParity           = (ftype < 0);
+        vsite_type[Hatoms[i]] = ftype = abs(ftype);
+        if (ftype == F_BONDS)
+        {
+            if ( (nrheavies != 1) && (nrHatoms != 1) )
+            {
+                gmx_fatal(FARGS, "cannot make constraint in add_vsites for %d heavy "
+                          "atoms and %d hydrogen atoms", nrheavies, nrHatoms);
+            }
+            my_add_param(&(plist[F_CONSTRNC]), Hatoms[i], heavies[0], NOTSET);
+        }
+        else
+        {
+            switch (ftype)
+            {
+                case F_VSITE3:
+                case F_VSITE3FD:
+                case F_VSITE3OUT:
+                    if (nrheavies < 2)
+                    {
+                        gmx_fatal(FARGS, "Not enough heavy atoms (%d) for %s (min 3)",
+                                  nrheavies+1,
+                                  interaction_function[vsite_type[Hatoms[i]]].name);
+                    }
+                    add_vsite3_atoms(&plist[ftype], Hatoms[i], Heavy, heavies[0], heavies[1],
+                                     bSwapParity);
+                    break;
+                case F_VSITE3FAD:
+                {
+                    if (nrheavies > 1)
+                    {
+                        moreheavy = heavies[1];
+                    }
+                    else
+                    {
+                        /* find more heavy atoms */
+                        other = moreheavy = NOTSET;
+                        for (j = 0; (j < plist[F_BONDS].nr) && (moreheavy == NOTSET); j++)
+                        {
+                            if (plist[F_BONDS].param[j].AI == heavies[0])
+                            {
+                                other = plist[F_BONDS].param[j].AJ;
+                            }
+                            else if (plist[F_BONDS].param[j].AJ == heavies[0])
+                            {
+                                other = plist[F_BONDS].param[j].AI;
+                            }
+                            if ( (other != NOTSET) && (other != Heavy) )
+                            {
+                                moreheavy = other;
+                            }
+                        }
+                        if (moreheavy == NOTSET)
+                        {
+                            gmx_fatal(FARGS, "Unbound molecule part %d-%d", Heavy+1, Hatoms[0]+1);
+                        }
+                    }
+                    add_vsite3_atoms(&plist[ftype], Hatoms[i], Heavy, heavies[0], moreheavy,
+                                     bSwapParity);
+                    break;
+                }
+                case F_VSITE4FD:
+                case F_VSITE4FDN:
+                    if (nrheavies < 3)
+                    {
+                        gmx_fatal(FARGS, "Not enough heavy atoms (%d) for %s (min 4)",
+                                  nrheavies+1,
+                                  interaction_function[vsite_type[Hatoms[i]]].name);
+                    }
+                    add_vsite4_atoms(&plist[ftype],
+                                     Hatoms[0], Heavy, heavies[0], heavies[1], heavies[2]);
+                    break;
+
+                default:
+                    gmx_fatal(FARGS, "can't use add_vsites for interaction function %s",
+                              interaction_function[vsite_type[Hatoms[i]]].name);
+            } /* switch ftype */
+        }     /* else */
+    }         /* for i */
 }
 
 #define ANGLE_6RING (DEG2RAD*120)
 
 /* cosine rule: a^2 = b^2 + c^2 - 2 b c cos(alpha) */
 /* get a^2 when a, b and alpha are given: */
-#define cosrule(b,c,alpha) ( sqr(b) + sqr(c) - 2*b*c*cos(alpha) )
+#define cosrule(b, c, alpha) ( sqr(b) + sqr(c) - 2*b*c*cos(alpha) )
 /* get cos(alpha) when a, b and c are given: */
-#define acosrule(a,b,c) ( (sqr(b)+sqr(c)-sqr(a))/(2*b*c) )
+#define acosrule(a, b, c) ( (sqr(b)+sqr(c)-sqr(a))/(2*b*c) )
 
-static int gen_vsites_6ring(t_atoms *at, int *vsite_type[], t_params plist[], 
-                         int nrfound, int *ats, real bond_cc, real bond_ch,
-                         real xcom, real ycom, gmx_bool bDoZ)
+static int gen_vsites_6ring(t_atoms *at, int *vsite_type[], t_params plist[],
+                            int nrfound, int *ats, real bond_cc, real bond_ch,
+                            real xcom, gmx_bool bDoZ)
 {
-  /* these MUST correspond to the atnms array in do_vsite_aromatics! */
-  enum { atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2, 
-        atCZ, atHZ, atNR };
-  
-  int i,nvsite;
-   real a,b,dCGCE,tmp1,tmp2,mtot,mG,mrest;
-   real xCG,yCG,xCE1,yCE1,xCE2,yCE2;
-  /* CG, CE1 and CE2 stay and each get a part of the total mass, 
-   * so the c-o-m stays the same.
-   */
-
-  if (bDoZ) {
-    if (atNR != nrfound)
-      gmx_incons("Generating vsites on 6-rings");
-  }
-
-  /* constraints between CG, CE1 and CE2: */
-  dCGCE = sqrt( cosrule(bond_cc,bond_cc,ANGLE_6RING) );
-  my_add_param(&(plist[F_CONSTRNC]),ats[atCG] ,ats[atCE1],dCGCE);
-  my_add_param(&(plist[F_CONSTRNC]),ats[atCG] ,ats[atCE2],dCGCE);
-  my_add_param(&(plist[F_CONSTRNC]),ats[atCE1],ats[atCE2],dCGCE);
-  
-  /* rest will be vsite3 */
-  mtot=0;
-  nvsite=0;
-  for(i=0; i<  (bDoZ ? atNR : atHZ) ; i++) {
-    mtot+=at->atom[ats[i]].m;
-    if ( i!=atCG && i!=atCE1 && i!=atCE2 && (bDoZ || (i!=atHZ && i!=atCZ) ) ) {
-      at->atom[ats[i]].m = at->atom[ats[i]].mB = 0;
-      (*vsite_type)[ats[i]]=F_VSITE3;
-      nvsite++;
-    }
-  }
-  /* Distribute mass so center-of-mass stays the same. 
-   * The center-of-mass in the call is defined with x=0 at
-   * the CE1-CE2 bond and y=0 at the line from CG to the middle of CE1-CE2 bond.
-   */
-  xCG=-bond_cc+bond_cc*cos(ANGLE_6RING);
-  yCG=0;
-  xCE1=0;
-  yCE1=bond_cc*sin(0.5*ANGLE_6RING);
-  xCE2=0;
-  yCE2=-bond_cc*sin(0.5*ANGLE_6RING);  
-  
-  mG = at->atom[ats[atCG]].m = at->atom[ats[atCG]].mB = xcom*mtot/xCG;
-  mrest=mtot-mG;
-  at->atom[ats[atCE1]].m = at->atom[ats[atCE1]].mB = 
-    at->atom[ats[atCE2]].m = at->atom[ats[atCE2]].mB = mrest / 2;
-  
-  /* vsite3 construction: r_d = r_i + a r_ij + b r_ik */
-  tmp1 = dCGCE*sin(ANGLE_6RING*0.5);
-  tmp2 = bond_cc*cos(0.5*ANGLE_6RING) + tmp1;
-  tmp1 *= 2;
-  a = b = - bond_ch / tmp1;
-  /* HE1 and HE2: */
-  add_vsite3_param(&plist[F_VSITE3],
-                ats[atHE1],ats[atCE1],ats[atCE2],ats[atCG], a,b);
-  add_vsite3_param(&plist[F_VSITE3],
-                ats[atHE2],ats[atCE2],ats[atCE1],ats[atCG], a,b);
-  /* CD1, CD2 and CZ: */
-  a = b = tmp2 / tmp1;
-  add_vsite3_param(&plist[F_VSITE3],
-                ats[atCD1],ats[atCE2],ats[atCE1],ats[atCG], a,b);
-  add_vsite3_param(&plist[F_VSITE3],
-                ats[atCD2],ats[atCE1],ats[atCE2],ats[atCG], a,b);
-  if (bDoZ)
+    /* these MUST correspond to the atnms array in do_vsite_aromatics! */
+    enum {
+        atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2,
+        atCZ, atHZ, atNR
+    };
+
+    int  i, nvsite;
+    real a, b, dCGCE, tmp1, tmp2, mtot, mG, mrest;
+    real xCG, yCG, xCE1, yCE1, xCE2, yCE2;
+    /* CG, CE1 and CE2 stay and each get a part of the total mass,
+     * so the c-o-m stays the same.
+     */
+
+    if (bDoZ)
+    {
+        if (atNR != nrfound)
+        {
+            gmx_incons("Generating vsites on 6-rings");
+        }
+    }
+
+    /* constraints between CG, CE1 and CE2: */
+    dCGCE = sqrt( cosrule(bond_cc, bond_cc, ANGLE_6RING) );
+    my_add_param(&(plist[F_CONSTRNC]), ats[atCG], ats[atCE1], dCGCE);
+    my_add_param(&(plist[F_CONSTRNC]), ats[atCG], ats[atCE2], dCGCE);
+    my_add_param(&(plist[F_CONSTRNC]), ats[atCE1], ats[atCE2], dCGCE);
+
+    /* rest will be vsite3 */
+    mtot   = 0;
+    nvsite = 0;
+    for (i = 0; i <  (bDoZ ? atNR : atHZ); i++)
+    {
+        mtot += at->atom[ats[i]].m;
+        if (i != atCG && i != atCE1 && i != atCE2 && (bDoZ || (i != atHZ && i != atCZ) ) )
+        {
+            at->atom[ats[i]].m    = at->atom[ats[i]].mB = 0;
+            (*vsite_type)[ats[i]] = F_VSITE3;
+            nvsite++;
+        }
+    }
+    /* Distribute mass so center-of-mass stays the same.
+     * The center-of-mass in the call is defined with x=0 at
+     * the CE1-CE2 bond and y=0 at the line from CG to the middle of CE1-CE2 bond.
+     */
+    xCG  = -bond_cc+bond_cc*cos(ANGLE_6RING);
+    yCG  = 0;
+    xCE1 = 0;
+    yCE1 = bond_cc*sin(0.5*ANGLE_6RING);
+    xCE2 = 0;
+    yCE2 = -bond_cc*sin(0.5*ANGLE_6RING);
+
+    mG                             = at->atom[ats[atCG]].m = at->atom[ats[atCG]].mB = xcom*mtot/xCG;
+    mrest                          = mtot-mG;
+    at->atom[ats[atCE1]].m         = at->atom[ats[atCE1]].mB =
+            at->atom[ats[atCE2]].m = at->atom[ats[atCE2]].mB = mrest / 2;
+
+    /* vsite3 construction: r_d = r_i + a r_ij + b r_ik */
+    tmp1  = dCGCE*sin(ANGLE_6RING*0.5);
+    tmp2  = bond_cc*cos(0.5*ANGLE_6RING) + tmp1;
+    tmp1 *= 2;
+    a     = b = -bond_ch / tmp1;
+    /* HE1 and HE2: */
     add_vsite3_param(&plist[F_VSITE3],
-                  ats[atCZ], ats[atCG], ats[atCE1],ats[atCE2],a,b);
-  /* HD1, HD2 and HZ: */
-  a = b = ( bond_ch + tmp2 ) / tmp1;
-  add_vsite3_param(&plist[F_VSITE3],
-                ats[atHD1],ats[atCE2],ats[atCE1],ats[atCG], a,b);
-  add_vsite3_param(&plist[F_VSITE3],
-                ats[atHD2],ats[atCE1],ats[atCE2],ats[atCG], a,b);
-  if (bDoZ)
+                     ats[atHE1], ats[atCE1], ats[atCE2], ats[atCG], a, b);
     add_vsite3_param(&plist[F_VSITE3],
-                  ats[atHZ], ats[atCG], ats[atCE1],ats[atCE2],a,b);
-  
-  return nvsite;
+                     ats[atHE2], ats[atCE2], ats[atCE1], ats[atCG], a, b);
+    /* CD1, CD2 and CZ: */
+    a = b = tmp2 / tmp1;
+    add_vsite3_param(&plist[F_VSITE3],
+                     ats[atCD1], ats[atCE2], ats[atCE1], ats[atCG], a, b);
+    add_vsite3_param(&plist[F_VSITE3],
+                     ats[atCD2], ats[atCE1], ats[atCE2], ats[atCG], a, b);
+    if (bDoZ)
+    {
+        add_vsite3_param(&plist[F_VSITE3],
+                         ats[atCZ], ats[atCG], ats[atCE1], ats[atCE2], a, b);
+    }
+    /* HD1, HD2 and HZ: */
+    a = b = ( bond_ch + tmp2 ) / tmp1;
+    add_vsite3_param(&plist[F_VSITE3],
+                     ats[atHD1], ats[atCE2], ats[atCE1], ats[atCG], a, b);
+    add_vsite3_param(&plist[F_VSITE3],
+                     ats[atHD2], ats[atCE1], ats[atCE2], ats[atCG], a, b);
+    if (bDoZ)
+    {
+        add_vsite3_param(&plist[F_VSITE3],
+                         ats[atHZ], ats[atCG], ats[atCE1], ats[atCE2], a, b);
+    }
+
+    return nvsite;
 }
 
-static int gen_vsites_phe(t_atoms *at, int *vsite_type[], t_params plist[], 
-                        int nrfound, int *ats, t_vsitetop *vsitetop, int nvsitetop)
+static int gen_vsites_phe(t_atoms *at, int *vsite_type[], t_params plist[],
+                          int nrfound, int *ats, t_vsitetop *vsitetop, int nvsitetop)
 {
-  real bond_cc,bond_ch;
-  real xcom,ycom,mtot;
-  int i;
-  /* these MUST correspond to the atnms array in do_vsite_aromatics! */
-  enum { atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2, 
-        atCZ, atHZ, atNR };
-  real x[atNR],y[atNR];
-  /* Aromatic rings have 6-fold symmetry, so we only need one bond length.
-   * (angle is always 120 degrees).
-   */   
-  bond_cc=get_ddb_bond(vsitetop,nvsitetop,"PHE","CD1","CE1");
-  bond_ch=get_ddb_bond(vsitetop,nvsitetop,"PHE","CD1","HD1");
-  
-  x[atCG]=-bond_cc+bond_cc*cos(ANGLE_6RING);
-  y[atCG]=0;
-  x[atCD1]=-bond_cc;
-  y[atCD1]=bond_cc*sin(0.5*ANGLE_6RING);
-  x[atHD1]=x[atCD1]+bond_ch*cos(ANGLE_6RING);
-  y[atHD1]=y[atCD1]+bond_ch*sin(ANGLE_6RING);
-  x[atCE1]=0;
-  y[atCE1]=y[atCD1];
-  x[atHE1]=x[atCE1]-bond_ch*cos(ANGLE_6RING);
-  y[atHE1]=y[atCE1]+bond_ch*sin(ANGLE_6RING);
-  x[atCD2]=x[atCD1];
-  y[atCD2]=-y[atCD1];
-  x[atHD2]=x[atHD1];
-  y[atHD2]=-y[atHD1];
-  x[atCE2]=x[atCE1];
-  y[atCE2]=-y[atCE1];
-  x[atHE2]=x[atHE1];
-  y[atHE2]=-y[atHE1];
-  x[atCZ]=bond_cc*cos(0.5*ANGLE_6RING);
-  y[atCZ]=0;
-  x[atHZ]=x[atCZ]+bond_ch;
-  y[atHZ]=0;
-
-  xcom=ycom=mtot=0;
-  for(i=0;i<atNR;i++) {
-    xcom+=x[i]*at->atom[ats[i]].m;
-    ycom+=y[i]*at->atom[ats[i]].m;
-    mtot+=at->atom[ats[i]].m;
-  }
-  xcom/=mtot;
-  ycom/=mtot;
-
-  return gen_vsites_6ring(at, vsite_type, plist, nrfound, ats, bond_cc, bond_ch, xcom, ycom, TRUE);
+    real bond_cc, bond_ch;
+    real xcom, mtot;
+    int  i;
+    /* these MUST correspond to the atnms array in do_vsite_aromatics! */
+    enum {
+        atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2,
+        atCZ, atHZ, atNR
+    };
+    real x[atNR], y[atNR];
+    /* Aromatic rings have 6-fold symmetry, so we only need one bond length.
+     * (angle is always 120 degrees).
+     */
+    bond_cc = get_ddb_bond(vsitetop, nvsitetop, "PHE", "CD1", "CE1");
+    bond_ch = get_ddb_bond(vsitetop, nvsitetop, "PHE", "CD1", "HD1");
+
+    x[atCG]  = -bond_cc+bond_cc*cos(ANGLE_6RING);
+    y[atCG]  = 0;
+    x[atCD1] = -bond_cc;
+    y[atCD1] = bond_cc*sin(0.5*ANGLE_6RING);
+    x[atHD1] = x[atCD1]+bond_ch*cos(ANGLE_6RING);
+    y[atHD1] = y[atCD1]+bond_ch*sin(ANGLE_6RING);
+    x[atCE1] = 0;
+    y[atCE1] = y[atCD1];
+    x[atHE1] = x[atCE1]-bond_ch*cos(ANGLE_6RING);
+    y[atHE1] = y[atCE1]+bond_ch*sin(ANGLE_6RING);
+    x[atCD2] = x[atCD1];
+    y[atCD2] = -y[atCD1];
+    x[atHD2] = x[atHD1];
+    y[atHD2] = -y[atHD1];
+    x[atCE2] = x[atCE1];
+    y[atCE2] = -y[atCE1];
+    x[atHE2] = x[atHE1];
+    y[atHE2] = -y[atHE1];
+    x[atCZ]  = bond_cc*cos(0.5*ANGLE_6RING);
+    y[atCZ]  = 0;
+    x[atHZ]  = x[atCZ]+bond_ch;
+    y[atHZ]  = 0;
+
+    xcom = mtot = 0;
+    for (i = 0; i < atNR; i++)
+    {
+        xcom += x[i]*at->atom[ats[i]].m;
+        mtot += at->atom[ats[i]].m;
+    }
+    xcom /= mtot;
+
+    return gen_vsites_6ring(at, vsite_type, plist, nrfound, ats, bond_cc, bond_ch, xcom, TRUE);
 }
 
-static void calc_vsite3_param(real xd,real yd,real xi,real yi,real xj,real yj,
-                             real xk, real yk, real *a, real *b)
+static void calc_vsite3_param(real xd, real yd, real xi, real yi, real xj, real yj,
+                              real xk, real yk, real *a, real *b)
 {
-  /* determine parameters by solving the equation system, since we know the
-   * virtual site coordinates here.
-   */
-  real dx_ij,dx_ik,dy_ij,dy_ik;
-  real b_ij,b_ik;
-
-  dx_ij=xj-xi;
-  dy_ij=yj-yi;
-  dx_ik=xk-xi;
-  dy_ik=yk-yi;
-  b_ij=sqrt(dx_ij*dx_ij+dy_ij*dy_ij);
-  b_ik=sqrt(dx_ik*dx_ik+dy_ik*dy_ik);
-
-  *a = ( (xd-xi)*dy_ik - dx_ik*(yd-yi) ) / (dx_ij*dy_ik - dx_ik*dy_ij);
-  *b = ( yd - yi - (*a)*dy_ij ) / dy_ik;
+    /* determine parameters by solving the equation system, since we know the
+     * virtual site coordinates here.
+     */
+    real dx_ij, dx_ik, dy_ij, dy_ik;
+    real b_ij, b_ik;
+
+    dx_ij = xj-xi;
+    dy_ij = yj-yi;
+    dx_ik = xk-xi;
+    dy_ik = yk-yi;
+    b_ij  = sqrt(dx_ij*dx_ij+dy_ij*dy_ij);
+    b_ik  = sqrt(dx_ik*dx_ik+dy_ik*dy_ik);
+
+    *a = ( (xd-xi)*dy_ik - dx_ik*(yd-yi) ) / (dx_ij*dy_ik - dx_ik*dy_ij);
+    *b = ( yd - yi - (*a)*dy_ij ) / dy_ik;
 }
 
 
 static int gen_vsites_trp(gpp_atomtype_t atype, rvec *newx[],
-                         t_atom *newatom[], char ***newatomname[], 
-                         int *o2n[], int *newvsite_type[], int *newcgnr[],
-                         t_symtab *symtab, int *nadd, rvec x[], int *cgnr[],
-                         t_atoms *at, int *vsite_type[], t_params plist[], 
-                         int nrfound, int *ats, int add_shift,
-                         t_vsitetop *vsitetop, int nvsitetop)
+                          t_atom *newatom[], char ***newatomname[],
+                          int *o2n[], int *newvsite_type[], int *newcgnr[],
+                          t_symtab *symtab, int *nadd, rvec x[], int *cgnr[],
+                          t_atoms *at, int *vsite_type[], t_params plist[],
+                          int nrfound, int *ats, int add_shift,
+                          t_vsitetop *vsitetop, int nvsitetop)
 {
 #define NMASS 2
-  /* these MUST correspond to the atnms array in do_vsite_aromatics! */
-  enum { 
-    atCB,  atCG,  atCD1, atHD1, atCD2, atNE1, atHE1, atCE2, atCE3, atHE3, 
-    atCZ2, atHZ2, atCZ3, atHZ3, atCH2, atHH2, atNR };
-  /* weights for determining the COM's of both rings (M1 and M2): */
-  real mw[NMASS][atNR] = {
-    {   0,     1,     1,     1,   0.5,     1,     1,   0.5,     0,     0,
-        0,     0,     0,     0,     0,     0 },
-    {   0,     0,     0,     0,   0.5,     0,     0,   0.5,     1,     1,
-        1,     1,     1,     1,     1,     1 }
-  };
-  real xi[atNR],yi[atNR];
-  real xcom[NMASS],ycom[NMASS],I,alpha;
-  real lineA,lineB,dist;
-  real b_CD2_CE2,b_NE1_CE2,b_CG_CD2,b_CH2_HH2,b_CE2_CZ2;
-  real b_NE1_HE1,b_CD2_CE3,b_CE3_CZ3,b_CB_CG;
-  real b_CZ2_CH2,b_CZ2_HZ2,b_CD1_HD1,b_CE3_HE3;
-  real b_CG_CD1,b_CZ3_HZ3;
-  real a_NE1_CE2_CD2,a_CE2_CD2_CG,a_CB_CG_CD2,a_CE2_CD2_CE3;
-  real a_CB_CG_CD1,a_CD2_CG_CD1,a_CE2_CZ2_HZ2,a_CZ2_CH2_HH2;
-  real a_CD2_CE2_CZ2,a_CD2_CE3_CZ3,a_CE3_CZ3_HZ3,a_CG_CD1_HD1;
-  real a_CE2_CZ2_CH2,a_HE1_NE1_CE2,a_CD2_CE3_HE3;
-  real xM[NMASS];
-  int  atM[NMASS],tpM,i,i0,j,nvsite;
-  real mwtot,mtot,mM[NMASS],dCBM1,dCBM2,dM1M2;
-  real a,b,c[MAXFORCEPARAM];
-  rvec r_ij,r_ik,t1,t2;
-  char name[10];
-
-  if (atNR != nrfound)
-    gmx_incons("atom types in gen_vsites_trp");
-  /* Get geometry from database */
-  b_CD2_CE2=get_ddb_bond(vsitetop,nvsitetop,"TRP","CD2","CE2");
-  b_NE1_CE2=get_ddb_bond(vsitetop,nvsitetop,"TRP","NE1","CE2");
-  b_CG_CD1=get_ddb_bond(vsitetop,nvsitetop,"TRP","CG","CD1");
-  b_CG_CD2=get_ddb_bond(vsitetop,nvsitetop,"TRP","CG","CD2");
-  b_CB_CG=get_ddb_bond(vsitetop,nvsitetop,"TRP","CB","CG");
-  b_CE2_CZ2=get_ddb_bond(vsitetop,nvsitetop,"TRP","CE2","CZ2");
-  b_CD2_CE3=get_ddb_bond(vsitetop,nvsitetop,"TRP","CD2","CE3");
-  b_CE3_CZ3=get_ddb_bond(vsitetop,nvsitetop,"TRP","CE3","CZ3");
-  b_CZ2_CH2=get_ddb_bond(vsitetop,nvsitetop,"TRP","CZ2","CH2");
-
-  b_CD1_HD1=get_ddb_bond(vsitetop,nvsitetop,"TRP","CD1","HD1");
-  b_CZ2_HZ2=get_ddb_bond(vsitetop,nvsitetop,"TRP","CZ2","HZ2");
-  b_NE1_HE1=get_ddb_bond(vsitetop,nvsitetop,"TRP","NE1","HE1");
-  b_CH2_HH2=get_ddb_bond(vsitetop,nvsitetop,"TRP","CH2","HH2");
-  b_CE3_HE3=get_ddb_bond(vsitetop,nvsitetop,"TRP","CE3","HE3");
-  b_CZ3_HZ3=get_ddb_bond(vsitetop,nvsitetop,"TRP","CZ3","HZ3");
-
-  a_NE1_CE2_CD2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","NE1","CE2","CD2");
-  a_CE2_CD2_CG=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CE2","CD2","CG");
-  a_CB_CG_CD2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CB","CG","CD2");
-  a_CD2_CG_CD1=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CD2","CG","CD1");
-  a_CB_CG_CD1=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CB","CG","CD1");
-  a_CE2_CD2_CE3=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CE2","CD2","CE3");
-  a_CD2_CE2_CZ2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CD2","CE2","CZ2");
-  a_CD2_CE3_CZ3=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CD2","CE3","CZ3");
-  a_CE3_CZ3_HZ3=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CE3","CZ3","HZ3");
-  a_CZ2_CH2_HH2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CZ2","CH2","HH2");
-  a_CE2_CZ2_HZ2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CE2","CZ2","HZ2");
-  a_CE2_CZ2_CH2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CE2","CZ2","CH2");
-  a_CG_CD1_HD1=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CG","CD1","HD1");
-  a_HE1_NE1_CE2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","HE1","NE1","CE2");
-  a_CD2_CE3_HE3=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TRP","CD2","CE3","HE3");
-  /* Calculate local coordinates.
-   * y-axis (x=0) is the bond CD2-CE2.
-   * x-axis (y=0) is perpendicular to the bond CD2-CE2 and
-   * intersects the middle of the bond.
-   */
-  xi[atCD2]=0;
-  yi[atCD2]=-0.5*b_CD2_CE2;
-  
-  xi[atCE2]=0;
-  yi[atCE2]=0.5*b_CD2_CE2;
-
-  xi[atNE1]=-b_NE1_CE2*sin(a_NE1_CE2_CD2);
-  yi[atNE1]=yi[atCE2]-b_NE1_CE2*cos(a_NE1_CE2_CD2);
-
-  xi[atCG]=-b_CG_CD2*sin(a_CE2_CD2_CG);
-  yi[atCG]=yi[atCD2]+b_CG_CD2*cos(a_CE2_CD2_CG);
-
-  alpha = a_CE2_CD2_CG + M_PI - a_CB_CG_CD2;
-  xi[atCB]=xi[atCG]-b_CB_CG*sin(alpha);
-  yi[atCB]=yi[atCG]+b_CB_CG*cos(alpha);
-
-  alpha = a_CE2_CD2_CG + a_CD2_CG_CD1 - M_PI;
-  xi[atCD1]=xi[atCG]-b_CG_CD1*sin(alpha);
-  yi[atCD1]=yi[atCG]+b_CG_CD1*cos(alpha);
-
-  xi[atCE3]=b_CD2_CE3*sin(a_CE2_CD2_CE3);
-  yi[atCE3]=yi[atCD2]+b_CD2_CE3*cos(a_CE2_CD2_CE3);
-
-  xi[atCZ2]=b_CE2_CZ2*sin(a_CD2_CE2_CZ2);
-  yi[atCZ2]=yi[atCE2]-b_CE2_CZ2*cos(a_CD2_CE2_CZ2);
-
-  alpha = a_CE2_CD2_CE3 + a_CD2_CE3_CZ3 - M_PI;
-  xi[atCZ3]=xi[atCE3]+b_CE3_CZ3*sin(alpha);
-  yi[atCZ3]=yi[atCE3]+b_CE3_CZ3*cos(alpha);
-
-  alpha = a_CD2_CE2_CZ2 + a_CE2_CZ2_CH2 - M_PI;
-  xi[atCH2]=xi[atCZ2]+b_CZ2_CH2*sin(alpha);
-  yi[atCH2]=yi[atCZ2]-b_CZ2_CH2*cos(alpha);
-
-  /* hydrogens */
-  alpha = a_CE2_CD2_CG + a_CD2_CG_CD1 - a_CG_CD1_HD1;
-  xi[atHD1]=xi[atCD1]-b_CD1_HD1*sin(alpha);
-  yi[atHD1]=yi[atCD1]+b_CD1_HD1*cos(alpha);
-
-  alpha = a_NE1_CE2_CD2 + M_PI - a_HE1_NE1_CE2;
-  xi[atHE1]=xi[atNE1]-b_NE1_HE1*sin(alpha);
-  yi[atHE1]=yi[atNE1]-b_NE1_HE1*cos(alpha);
-  
-  alpha = a_CE2_CD2_CE3 + M_PI - a_CD2_CE3_HE3;
-  xi[atHE3]=xi[atCE3]+b_CE3_HE3*sin(alpha);
-  yi[atHE3]=yi[atCE3]+b_CE3_HE3*cos(alpha);
-
-  alpha = a_CD2_CE2_CZ2 + M_PI - a_CE2_CZ2_HZ2;
-  xi[atHZ2]=xi[atCZ2]+b_CZ2_HZ2*sin(alpha);
-  yi[atHZ2]=yi[atCZ2]-b_CZ2_HZ2*cos(alpha);
-
-  alpha = a_CD2_CE2_CZ2 + a_CE2_CZ2_CH2 - a_CZ2_CH2_HH2;
-  xi[atHZ3]=xi[atCZ3]+b_CZ3_HZ3*sin(alpha);
-  yi[atHZ3]=yi[atCZ3]+b_CZ3_HZ3*cos(alpha);
-
-  alpha = a_CE2_CD2_CE3 + a_CD2_CE3_CZ3 - a_CE3_CZ3_HZ3;
-  xi[atHH2]=xi[atCH2]+b_CH2_HH2*sin(alpha);
-  yi[atHH2]=yi[atCH2]-b_CH2_HH2*cos(alpha);
-
-  /* Determine coeff. for the line CB-CG */
-  lineA=(yi[atCB]-yi[atCG])/(xi[atCB]-xi[atCG]);
-  lineB=yi[atCG]-lineA*xi[atCG];
-  
-  /* Calculate masses for each ring and put it on the dummy masses */
-  for(j=0; j<NMASS; j++)
-    mM[j]=xcom[j]=ycom[j]=0;
-  for(i=0; i<atNR; i++) {
-    if (i!=atCB) {
-      for(j=0; j<NMASS; j++) {
-        mM[j] += mw[j][i] * at->atom[ats[i]].m;
-        xcom[j] += xi[i] * mw[j][i] * at->atom[ats[i]].m;
-        ycom[j] += yi[i] * mw[j][i] * at->atom[ats[i]].m;
-      }  
-    }
-  }
-  for(j=0; j<NMASS; j++) {
-    xcom[j]/=mM[j];
-    ycom[j]/=mM[j];
-  }
-  
-  /* get dummy mass type */
-  tpM=vsite_nm2type("MW",atype);
-  /* make space for 2 masses: shift all atoms starting with CB */
-  i0=ats[atCB];
-  for(j=0; j<NMASS; j++)
-    atM[j]=i0+*nadd+j;
-  if (debug)
-     fprintf(stderr,"Inserting %d dummy masses at %d\n",NMASS,(*o2n)[i0]+1);
-  *nadd+=NMASS;
-  for(j=i0; j<at->nr; j++)
-    (*o2n)[j]=j+*nadd;
-  srenew(*newx,at->nr+*nadd);
-  srenew(*newatom,at->nr+*nadd);
-  srenew(*newatomname,at->nr+*nadd);
-  srenew(*newvsite_type,at->nr+*nadd);
-  srenew(*newcgnr,at->nr+*nadd);
-  for(j=0; j<NMASS; j++)
-    (*newatomname)[at->nr+*nadd-1-j]=NULL;
-  
-  /* Dummy masses will be placed at the center-of-mass in each ring. */
-
-  /* calc initial position for dummy masses in real (non-local) coordinates.
-   * Cheat by using the routine to calculate virtual site parameters. It is
-   * much easier when we have the coordinates expressed in terms of
-   * CB, CG, CD2.
-   */
-  rvec_sub(x[ats[atCB]],x[ats[atCG]],r_ij);
-  rvec_sub(x[ats[atCD2]],x[ats[atCG]],r_ik);
-  calc_vsite3_param(xcom[0],ycom[0],xi[atCG],yi[atCG],xi[atCB],yi[atCB],
-                   xi[atCD2],yi[atCD2],&a,&b);
-  svmul(a,r_ij,t1);
-  svmul(b,r_ik,t2);
-  rvec_add(t1,t2,t1);
-  rvec_add(t1,x[ats[atCG]],(*newx)[atM[0]]);
-  
-  calc_vsite3_param(xcom[1],ycom[1],xi[atCG],yi[atCG],xi[atCB],yi[atCB],
-                   xi[atCD2],yi[atCD2],&a,&b);
-  svmul(a,r_ij,t1);
-  svmul(b,r_ik,t2);
-  rvec_add(t1,t2,t1);
-  rvec_add(t1,x[ats[atCG]],(*newx)[atM[1]]);
-
-  /* set parameters for the masses */
-  for(j=0; j<NMASS; j++) {
-    sprintf(name,"MW%d",j+1);
-    (*newatomname)  [atM[j]]       = put_symtab(symtab,name);
-    (*newatom)      [atM[j]].m     = (*newatom)[atM[j]].mB    = mM[j];
-    (*newatom)      [atM[j]].q     = (*newatom)[atM[j]].qB    = 0.0;
-    (*newatom)      [atM[j]].type  = (*newatom)[atM[j]].typeB = tpM;
-    (*newatom)      [atM[j]].ptype = eptAtom;
-    (*newatom)      [atM[j]].resind= at->atom[i0].resind;
-    (*newvsite_type)[atM[j]]       = NOTSET;
-    (*newcgnr)      [atM[j]]       = (*cgnr)[i0];
-  }
-  /* renumber cgnr: */
-  for(i=i0; i<at->nr; i++)
-    (*cgnr)[i]++;
-
-  /* constraints between CB, M1 and M2 */
-  /* 'add_shift' says which atoms won't be renumbered afterwards */
-  dCBM1 = sqrt( sqr(xcom[0]-xi[atCB]) + sqr(ycom[0]-yi[atCB]) );
-  dM1M2 = sqrt( sqr(xcom[0]-xcom[1]) + sqr(ycom[0]-ycom[1]) );
-  dCBM2 = sqrt( sqr(xcom[1]-xi[atCB]) + sqr(ycom[1]-yi[atCB]) );
-  my_add_param(&(plist[F_CONSTRNC]),ats[atCB],       add_shift+atM[0],dCBM1);
-  my_add_param(&(plist[F_CONSTRNC]),ats[atCB],       add_shift+atM[1],dCBM2);
-  my_add_param(&(plist[F_CONSTRNC]),add_shift+atM[0],add_shift+atM[1],dM1M2);
-  
-  /* rest will be vsite3 */
-  nvsite=0;
-  for(i=0; i<atNR; i++)
-    if (i!=atCB) {
-      at->atom[ats[i]].m = at->atom[ats[i]].mB = 0;
-      (*vsite_type)[ats[i]] = F_VSITE3;
-      nvsite++;
-    }
-  
-  /* now define all vsites from M1, M2, CB, ie:
-     r_d = r_M1 + a r_M1_M2 + b r_M1_CB */
-  for(i=0; i<atNR; i++)
-    if ( (*vsite_type)[ats[i]] == F_VSITE3 ) {
-      calc_vsite3_param(xi[i],yi[i],xcom[0],ycom[0],xcom[1],ycom[1],xi[atCB],yi[atCB],&a,&b);
-      add_vsite3_param(&plist[F_VSITE3],
-                    ats[i],add_shift+atM[0],add_shift+atM[1],ats[atCB],a,b);
-    }
-  return nvsite;
+    /* these MUST correspond to the atnms array in do_vsite_aromatics! */
+    enum {
+        atCB,  atCG,  atCD1, atHD1, atCD2, atNE1, atHE1, atCE2, atCE3, atHE3,
+        atCZ2, atHZ2, atCZ3, atHZ3, atCH2, atHH2, atNR
+    };
+    /* weights for determining the COM's of both rings (M1 and M2): */
+    real mw[NMASS][atNR] = {
+        {   0,     1,     1,     1,   0.5,     1,     1,   0.5,     0,     0,
+            0,     0,     0,     0,     0,     0 },
+        {   0,     0,     0,     0,   0.5,     0,     0,   0.5,     1,     1,
+            1,     1,     1,     1,     1,     1 }
+    };
+
+    real xi[atNR], yi[atNR];
+    real xcom[NMASS], ycom[NMASS], I, alpha;
+    real lineA, lineB, dist;
+    real b_CD2_CE2, b_NE1_CE2, b_CG_CD2, b_CH2_HH2, b_CE2_CZ2;
+    real b_NE1_HE1, b_CD2_CE3, b_CE3_CZ3, b_CB_CG;
+    real b_CZ2_CH2, b_CZ2_HZ2, b_CD1_HD1, b_CE3_HE3;
+    real b_CG_CD1, b_CZ3_HZ3;
+    real a_NE1_CE2_CD2, a_CE2_CD2_CG, a_CB_CG_CD2, a_CE2_CD2_CE3;
+    real a_CB_CG_CD1, a_CD2_CG_CD1, a_CE2_CZ2_HZ2, a_CZ2_CH2_HH2;
+    real a_CD2_CE2_CZ2, a_CD2_CE3_CZ3, a_CE3_CZ3_HZ3, a_CG_CD1_HD1;
+    real a_CE2_CZ2_CH2, a_HE1_NE1_CE2, a_CD2_CE3_HE3;
+    real xM[NMASS];
+    int  atM[NMASS], tpM, i, i0, j, nvsite;
+    real mwtot, mtot, mM[NMASS], dCBM1, dCBM2, dM1M2;
+    real a, b, c[MAXFORCEPARAM];
+    rvec r_ij, r_ik, t1, t2;
+    char name[10];
+
+    if (atNR != nrfound)
+    {
+        gmx_incons("atom types in gen_vsites_trp");
+    }
+    /* Get geometry from database */
+    b_CD2_CE2 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CD2", "CE2");
+    b_NE1_CE2 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "NE1", "CE2");
+    b_CG_CD1  = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CG", "CD1");
+    b_CG_CD2  = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CG", "CD2");
+    b_CB_CG   = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CB", "CG");
+    b_CE2_CZ2 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CE2", "CZ2");
+    b_CD2_CE3 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CD2", "CE3");
+    b_CE3_CZ3 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CE3", "CZ3");
+    b_CZ2_CH2 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CZ2", "CH2");
+
+    b_CD1_HD1 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CD1", "HD1");
+    b_CZ2_HZ2 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CZ2", "HZ2");
+    b_NE1_HE1 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "NE1", "HE1");
+    b_CH2_HH2 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CH2", "HH2");
+    b_CE3_HE3 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CE3", "HE3");
+    b_CZ3_HZ3 = get_ddb_bond(vsitetop, nvsitetop, "TRP", "CZ3", "HZ3");
+
+    a_NE1_CE2_CD2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "NE1", "CE2", "CD2");
+    a_CE2_CD2_CG  = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CE2", "CD2", "CG");
+    a_CB_CG_CD2   = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CB", "CG", "CD2");
+    a_CD2_CG_CD1  = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CD2", "CG", "CD1");
+    a_CB_CG_CD1   = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CB", "CG", "CD1");
+
+    a_CE2_CD2_CE3 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CE2", "CD2", "CE3");
+    a_CD2_CE2_CZ2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CD2", "CE2", "CZ2");
+    a_CD2_CE3_CZ3 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CD2", "CE3", "CZ3");
+    a_CE3_CZ3_HZ3 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CE3", "CZ3", "HZ3");
+    a_CZ2_CH2_HH2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CZ2", "CH2", "HH2");
+    a_CE2_CZ2_HZ2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CE2", "CZ2", "HZ2");
+    a_CE2_CZ2_CH2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CE2", "CZ2", "CH2");
+    a_CG_CD1_HD1  = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CG", "CD1", "HD1");
+    a_HE1_NE1_CE2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "HE1", "NE1", "CE2");
+    a_CD2_CE3_HE3 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TRP", "CD2", "CE3", "HE3");
+
+    /* Calculate local coordinates.
+     * y-axis (x=0) is the bond CD2-CE2.
+     * x-axis (y=0) is perpendicular to the bond CD2-CE2 and
+     * intersects the middle of the bond.
+     */
+    xi[atCD2] = 0;
+    yi[atCD2] = -0.5*b_CD2_CE2;
+
+    xi[atCE2] = 0;
+    yi[atCE2] = 0.5*b_CD2_CE2;
+
+    xi[atNE1] = -b_NE1_CE2*sin(a_NE1_CE2_CD2);
+    yi[atNE1] = yi[atCE2]-b_NE1_CE2*cos(a_NE1_CE2_CD2);
+
+    xi[atCG] = -b_CG_CD2*sin(a_CE2_CD2_CG);
+    yi[atCG] = yi[atCD2]+b_CG_CD2*cos(a_CE2_CD2_CG);
+
+    alpha    = a_CE2_CD2_CG + M_PI - a_CB_CG_CD2;
+    xi[atCB] = xi[atCG]-b_CB_CG*sin(alpha);
+    yi[atCB] = yi[atCG]+b_CB_CG*cos(alpha);
+
+    alpha     = a_CE2_CD2_CG + a_CD2_CG_CD1 - M_PI;
+    xi[atCD1] = xi[atCG]-b_CG_CD1*sin(alpha);
+    yi[atCD1] = yi[atCG]+b_CG_CD1*cos(alpha);
+
+    xi[atCE3] = b_CD2_CE3*sin(a_CE2_CD2_CE3);
+    yi[atCE3] = yi[atCD2]+b_CD2_CE3*cos(a_CE2_CD2_CE3);
+
+    xi[atCZ2] = b_CE2_CZ2*sin(a_CD2_CE2_CZ2);
+    yi[atCZ2] = yi[atCE2]-b_CE2_CZ2*cos(a_CD2_CE2_CZ2);
+
+    alpha     = a_CE2_CD2_CE3 + a_CD2_CE3_CZ3 - M_PI;
+    xi[atCZ3] = xi[atCE3]+b_CE3_CZ3*sin(alpha);
+    yi[atCZ3] = yi[atCE3]+b_CE3_CZ3*cos(alpha);
+
+    alpha     = a_CD2_CE2_CZ2 + a_CE2_CZ2_CH2 - M_PI;
+    xi[atCH2] = xi[atCZ2]+b_CZ2_CH2*sin(alpha);
+    yi[atCH2] = yi[atCZ2]-b_CZ2_CH2*cos(alpha);
+
+    /* hydrogens */
+    alpha     = a_CE2_CD2_CG + a_CD2_CG_CD1 - a_CG_CD1_HD1;
+    xi[atHD1] = xi[atCD1]-b_CD1_HD1*sin(alpha);
+    yi[atHD1] = yi[atCD1]+b_CD1_HD1*cos(alpha);
+
+    alpha     = a_NE1_CE2_CD2 + M_PI - a_HE1_NE1_CE2;
+    xi[atHE1] = xi[atNE1]-b_NE1_HE1*sin(alpha);
+    yi[atHE1] = yi[atNE1]-b_NE1_HE1*cos(alpha);
+
+    alpha     = a_CE2_CD2_CE3 + M_PI - a_CD2_CE3_HE3;
+    xi[atHE3] = xi[atCE3]+b_CE3_HE3*sin(alpha);
+    yi[atHE3] = yi[atCE3]+b_CE3_HE3*cos(alpha);
+
+    alpha     = a_CD2_CE2_CZ2 + M_PI - a_CE2_CZ2_HZ2;
+    xi[atHZ2] = xi[atCZ2]+b_CZ2_HZ2*sin(alpha);
+    yi[atHZ2] = yi[atCZ2]-b_CZ2_HZ2*cos(alpha);
+
+    alpha     = a_CD2_CE2_CZ2 + a_CE2_CZ2_CH2 - a_CZ2_CH2_HH2;
+    xi[atHZ3] = xi[atCZ3]+b_CZ3_HZ3*sin(alpha);
+    yi[atHZ3] = yi[atCZ3]+b_CZ3_HZ3*cos(alpha);
+
+    alpha     = a_CE2_CD2_CE3 + a_CD2_CE3_CZ3 - a_CE3_CZ3_HZ3;
+    xi[atHH2] = xi[atCH2]+b_CH2_HH2*sin(alpha);
+    yi[atHH2] = yi[atCH2]-b_CH2_HH2*cos(alpha);
+
+    /* Determine coeff. for the line CB-CG */
+    lineA = (yi[atCB]-yi[atCG])/(xi[atCB]-xi[atCG]);
+    lineB = yi[atCG]-lineA*xi[atCG];
+
+    /* Calculate masses for each ring and put it on the dummy masses */
+    for (j = 0; j < NMASS; j++)
+    {
+        mM[j] = xcom[j] = ycom[j] = 0;
+    }
+    for (i = 0; i < atNR; i++)
+    {
+        if (i != atCB)
+        {
+            for (j = 0; j < NMASS; j++)
+            {
+                mM[j]   += mw[j][i] * at->atom[ats[i]].m;
+                xcom[j] += xi[i] * mw[j][i] * at->atom[ats[i]].m;
+                ycom[j] += yi[i] * mw[j][i] * at->atom[ats[i]].m;
+            }
+        }
+    }
+    for (j = 0; j < NMASS; j++)
+    {
+        xcom[j] /= mM[j];
+        ycom[j] /= mM[j];
+    }
+
+    /* get dummy mass type */
+    tpM = vsite_nm2type("MW", atype);
+    /* make space for 2 masses: shift all atoms starting with CB */
+    i0 = ats[atCB];
+    for (j = 0; j < NMASS; j++)
+    {
+        atM[j] = i0+*nadd+j;
+    }
+    if (debug)
+    {
+        fprintf(stderr, "Inserting %d dummy masses at %d\n", NMASS, (*o2n)[i0]+1);
+    }
+    *nadd += NMASS;
+    for (j = i0; j < at->nr; j++)
+    {
+        (*o2n)[j] = j+*nadd;
+    }
+    srenew(*newx, at->nr+*nadd);
+    srenew(*newatom, at->nr+*nadd);
+    srenew(*newatomname, at->nr+*nadd);
+    srenew(*newvsite_type, at->nr+*nadd);
+    srenew(*newcgnr, at->nr+*nadd);
+    for (j = 0; j < NMASS; j++)
+    {
+        (*newatomname)[at->nr+*nadd-1-j] = NULL;
+    }
+
+    /* Dummy masses will be placed at the center-of-mass in each ring. */
+
+    /* calc initial position for dummy masses in real (non-local) coordinates.
+     * Cheat by using the routine to calculate virtual site parameters. It is
+     * much easier when we have the coordinates expressed in terms of
+     * CB, CG, CD2.
+     */
+    rvec_sub(x[ats[atCB]], x[ats[atCG]], r_ij);
+    rvec_sub(x[ats[atCD2]], x[ats[atCG]], r_ik);
+    calc_vsite3_param(xcom[0], ycom[0], xi[atCG], yi[atCG], xi[atCB], yi[atCB],
+                      xi[atCD2], yi[atCD2], &a, &b);
+    svmul(a, r_ij, t1);
+    svmul(b, r_ik, t2);
+    rvec_add(t1, t2, t1);
+    rvec_add(t1, x[ats[atCG]], (*newx)[atM[0]]);
+
+    calc_vsite3_param(xcom[1], ycom[1], xi[atCG], yi[atCG], xi[atCB], yi[atCB],
+                      xi[atCD2], yi[atCD2], &a, &b);
+    svmul(a, r_ij, t1);
+    svmul(b, r_ik, t2);
+    rvec_add(t1, t2, t1);
+    rvec_add(t1, x[ats[atCG]], (*newx)[atM[1]]);
+
+    /* set parameters for the masses */
+    for (j = 0; j < NMASS; j++)
+    {
+        sprintf(name, "MW%d", j+1);
+        (*newatomname)  [atM[j]]         = put_symtab(symtab, name);
+        (*newatom)      [atM[j]].m       = (*newatom)[atM[j]].mB    = mM[j];
+        (*newatom)      [atM[j]].q       = (*newatom)[atM[j]].qB    = 0.0;
+        (*newatom)      [atM[j]].type    = (*newatom)[atM[j]].typeB = tpM;
+        (*newatom)      [atM[j]].ptype   = eptAtom;
+        (*newatom)      [atM[j]].resind  = at->atom[i0].resind;
+        (*newatom)      [atM[j]].elem[0] = 'M';
+        (*newatom)      [atM[j]].elem[1] = '\0';
+        (*newvsite_type)[atM[j]]         = NOTSET;
+        (*newcgnr)      [atM[j]]         = (*cgnr)[i0];
+    }
+    /* renumber cgnr: */
+    for (i = i0; i < at->nr; i++)
+    {
+        (*cgnr)[i]++;
+    }
+
+    /* constraints between CB, M1 and M2 */
+    /* 'add_shift' says which atoms won't be renumbered afterwards */
+    dCBM1 = sqrt( sqr(xcom[0]-xi[atCB]) + sqr(ycom[0]-yi[atCB]) );
+    dM1M2 = sqrt( sqr(xcom[0]-xcom[1]) + sqr(ycom[0]-ycom[1]) );
+    dCBM2 = sqrt( sqr(xcom[1]-xi[atCB]) + sqr(ycom[1]-yi[atCB]) );
+    my_add_param(&(plist[F_CONSTRNC]), ats[atCB],       add_shift+atM[0], dCBM1);
+    my_add_param(&(plist[F_CONSTRNC]), ats[atCB],       add_shift+atM[1], dCBM2);
+    my_add_param(&(plist[F_CONSTRNC]), add_shift+atM[0], add_shift+atM[1], dM1M2);
+
+    /* rest will be vsite3 */
+    nvsite = 0;
+    for (i = 0; i < atNR; i++)
+    {
+        if (i != atCB)
+        {
+            at->atom[ats[i]].m    = at->atom[ats[i]].mB = 0;
+            (*vsite_type)[ats[i]] = F_VSITE3;
+            nvsite++;
+        }
+    }
+
+    /* now define all vsites from M1, M2, CB, ie:
+       r_d = r_M1 + a r_M1_M2 + b r_M1_CB */
+    for (i = 0; i < atNR; i++)
+    {
+        if ( (*vsite_type)[ats[i]] == F_VSITE3)
+        {
+            calc_vsite3_param(xi[i], yi[i], xcom[0], ycom[0], xcom[1], ycom[1], xi[atCB], yi[atCB], &a, &b);
+            add_vsite3_param(&plist[F_VSITE3],
+                             ats[i], add_shift+atM[0], add_shift+atM[1], ats[atCB], a, b);
+        }
+    }
+    return nvsite;
 #undef NMASS
 }
 
 
 static int gen_vsites_tyr(gpp_atomtype_t atype, rvec *newx[],
-                         t_atom *newatom[], char ***newatomname[], 
-                       int *o2n[], int *newvsite_type[], int *newcgnr[],
-                         t_symtab *symtab, int *nadd, rvec x[], int *cgnr[],
-                         t_atoms *at, int *vsite_type[], t_params plist[], 
-                         int nrfound, int *ats, int add_shift,
-                         t_vsitetop *vsitetop, int nvsitetop)
+                          t_atom *newatom[], char ***newatomname[],
+                          int *o2n[], int *newvsite_type[], int *newcgnr[],
+                          t_symtab *symtab, int *nadd, rvec x[], int *cgnr[],
+                          t_atoms *at, int *vsite_type[], t_params plist[],
+                          int nrfound, int *ats, int add_shift,
+                          t_vsitetop *vsitetop, int nvsitetop)
 {
-  int nvsite,i,i0,j,atM,tpM;
-  real dCGCE,dCEOH,dCGM,tmp1,a,b;
-  real bond_cc,bond_ch,bond_co,bond_oh,angle_coh;
-  real xcom,ycom,mtot;
-  real vmass,vdist,mM;
-  rvec r1;
-  char name[10];
-
-  /* these MUST correspond to the atnms array in do_vsite_aromatics! */
-  enum { atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2, 
-        atCZ, atOH, atHH, atNR };
-  real xi[atNR],yi[atNR];
-  /* CG, CE1, CE2 (as in general 6-ring) and OH and HH stay, 
-     rest gets virtualized.
-     Now we have two linked triangles with one improper keeping them flat */
-  if (atNR != nrfound)
-    gmx_incons("Number of atom types in gen_vsites_tyr");
-
-  /* Aromatic rings have 6-fold symmetry, so we only need one bond length
-   * for the ring part (angle is always 120 degrees).
-   */
-  bond_cc=get_ddb_bond(vsitetop,nvsitetop,"TYR","CD1","CE1");
-  bond_ch=get_ddb_bond(vsitetop,nvsitetop,"TYR","CD1","HD1");
-  bond_co=get_ddb_bond(vsitetop,nvsitetop,"TYR","CZ","OH");
-  bond_oh=get_ddb_bond(vsitetop,nvsitetop,"TYR","OH","HH");
-  angle_coh=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,"TYR","CZ","OH","HH");
-  
-  xi[atCG]=-bond_cc+bond_cc*cos(ANGLE_6RING);
-  yi[atCG]=0;
-  xi[atCD1]=-bond_cc;
-  yi[atCD1]=bond_cc*sin(0.5*ANGLE_6RING);
-  xi[atHD1]=xi[atCD1]+bond_ch*cos(ANGLE_6RING);
-  yi[atHD1]=yi[atCD1]+bond_ch*sin(ANGLE_6RING);
-  xi[atCE1]=0;
-  yi[atCE1]=yi[atCD1];
-  xi[atHE1]=xi[atCE1]-bond_ch*cos(ANGLE_6RING);
-  yi[atHE1]=yi[atCE1]+bond_ch*sin(ANGLE_6RING);
-  xi[atCD2]=xi[atCD1];
-  yi[atCD2]=-yi[atCD1];
-  xi[atHD2]=xi[atHD1];
-  yi[atHD2]=-yi[atHD1];
-  xi[atCE2]=xi[atCE1];
-  yi[atCE2]=-yi[atCE1];
-  xi[atHE2]=xi[atHE1];
-  yi[atHE2]=-yi[atHE1];
-  xi[atCZ]=bond_cc*cos(0.5*ANGLE_6RING);
-  yi[atCZ]=0;
-  xi[atOH]=xi[atCZ]+bond_co;
-  yi[atOH]=0;
-
-  xcom=ycom=mtot=0;
-  for(i=0;i<atOH;i++) {
-    xcom+=xi[i]*at->atom[ats[i]].m;
-    ycom+=yi[i]*at->atom[ats[i]].m;
-    mtot+=at->atom[ats[i]].m;
-  }
-  xcom/=mtot;
-  ycom/=mtot;
-
-  /* first do 6 ring as default, 
-     except CZ (we'll do that different) and HZ (we don't have that): */
-  nvsite = gen_vsites_6ring(at, vsite_type, plist, nrfound, ats, bond_cc, bond_ch, xcom, ycom, FALSE);
-  
-  /* then construct CZ from the 2nd triangle */
-  /* vsite3 construction: r_d = r_i + a r_ij + b r_ik */
-  a = b = 0.5 * bond_co / ( bond_co - bond_cc*cos(ANGLE_6RING) );
-  add_vsite3_param(&plist[F_VSITE3],
-                ats[atCZ],ats[atOH],ats[atCE1],ats[atCE2],a,b);
-  at->atom[ats[atCZ]].m = at->atom[ats[atCZ]].mB = 0;
-  
-  /* constraints between CE1, CE2 and OH */
-  dCGCE = sqrt( cosrule(bond_cc,bond_cc,ANGLE_6RING) );
-  dCEOH = sqrt( cosrule(bond_cc,bond_co,ANGLE_6RING) );
-  my_add_param(&(plist[F_CONSTRNC]),ats[atCE1],ats[atOH],dCEOH);
-  my_add_param(&(plist[F_CONSTRNC]),ats[atCE2],ats[atOH],dCEOH);
-
-  /* We also want to constrain the angle C-O-H, but since CZ is constructed
-   * we need to introduce a constraint to CG.
-   * CG is much further away, so that will lead to instabilities in LINCS
-   * when we constrain both CG-HH and OH-HH distances. Instead of requiring
-   * the use of lincs_order=8 we introduce a dummy mass three times further
-   * away from OH than HH. The mass is accordingly a third, with the remaining
-   * 2/3 moved to OH. This shouldnt cause any problems since the forces will
-   * apply to the HH constructed atom and not directly on the virtual mass.
-   */
-
-  vdist=2.0*bond_oh;
-  mM=at->atom[ats[atHH]].m/2.0;
-  at->atom[ats[atOH]].m+=mM;  /* add 1/2 of original H mass */
-  at->atom[ats[atOH]].mB+=mM; /* add 1/2 of original H mass */
-  at->atom[ats[atHH]].m=at->atom[ats[atHH]].mB=0;
-  
-  /* get dummy mass type */
-  tpM=vsite_nm2type("MW",atype);
-  /* make space for 1 mass: shift HH only */
-  i0=ats[atHH];
-  atM=i0+*nadd;
-  if (debug)
-     fprintf(stderr,"Inserting 1 dummy mass at %d\n",(*o2n)[i0]+1);
-  (*nadd)++;
-  for(j=i0; j<at->nr; j++)
-    (*o2n)[j]=j+*nadd;
-  srenew(*newx,at->nr+*nadd);
-  srenew(*newatom,at->nr+*nadd);
-  srenew(*newatomname,at->nr+*nadd);
-  srenew(*newvsite_type,at->nr+*nadd);
-  srenew(*newcgnr,at->nr+*nadd);
-  (*newatomname)[at->nr+*nadd-1]=NULL; 
-  
-  /* Calc the dummy mass initial position */
-  rvec_sub(x[ats[atHH]],x[ats[atOH]],r1);
-  svmul(2.0,r1,r1);
-  rvec_add(r1,x[ats[atHH]],(*newx)[atM]);
-  
-  strcpy(name,"MW1");
-  (*newatomname)  [atM]       = put_symtab(symtab,name);
-  (*newatom)      [atM].m     = (*newatom)[atM].mB    = mM;
-  (*newatom)      [atM].q     = (*newatom)[atM].qB    = 0.0;
-  (*newatom)      [atM].type  = (*newatom)[atM].typeB = tpM;
-  (*newatom)      [atM].ptype = eptAtom;
-  (*newatom)      [atM].resind= at->atom[i0].resind;
-  (*newvsite_type)[atM]       = NOTSET;
-  (*newcgnr)      [atM]       = (*cgnr)[i0]; 
-  /* renumber cgnr: */
-  for(i=i0; i<at->nr; i++)
-    (*cgnr)[i]++;
-
-  (*vsite_type)[ats[atHH]] = F_VSITE2;
-  nvsite++;
-  /* assume we also want the COH angle constrained: */
-  tmp1 = bond_cc*cos(0.5*ANGLE_6RING) + dCGCE*sin(ANGLE_6RING*0.5) + bond_co;
-  dCGM = sqrt( cosrule(tmp1,vdist,angle_coh) );
-  my_add_param(&(plist[F_CONSTRNC]),ats[atCG],add_shift+atM,dCGM);
-  my_add_param(&(plist[F_CONSTRNC]),ats[atOH],add_shift+atM,vdist);
-
-  add_vsite2_param(&plist[F_VSITE2],
-                ats[atHH],ats[atOH],add_shift+atM,1.0/2.0);
-  return nvsite;
+    int  nvsite, i, i0, j, atM, tpM;
+    real dCGCE, dCEOH, dCGM, tmp1, a, b;
+    real bond_cc, bond_ch, bond_co, bond_oh, angle_coh;
+    real xcom, mtot;
+    real vmass, vdist, mM;
+    rvec r1;
+    char name[10];
+
+    /* these MUST correspond to the atnms array in do_vsite_aromatics! */
+    enum {
+        atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2,
+        atCZ, atOH, atHH, atNR
+    };
+    real xi[atNR], yi[atNR];
+    /* CG, CE1, CE2 (as in general 6-ring) and OH and HH stay,
+       rest gets virtualized.
+       Now we have two linked triangles with one improper keeping them flat */
+    if (atNR != nrfound)
+    {
+        gmx_incons("Number of atom types in gen_vsites_tyr");
+    }
+
+    /* Aromatic rings have 6-fold symmetry, so we only need one bond length
+     * for the ring part (angle is always 120 degrees).
+     */
+    bond_cc   = get_ddb_bond(vsitetop, nvsitetop, "TYR", "CD1", "CE1");
+    bond_ch   = get_ddb_bond(vsitetop, nvsitetop, "TYR", "CD1", "HD1");
+    bond_co   = get_ddb_bond(vsitetop, nvsitetop, "TYR", "CZ", "OH");
+    bond_oh   = get_ddb_bond(vsitetop, nvsitetop, "TYR", "OH", "HH");
+    angle_coh = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, "TYR", "CZ", "OH", "HH");
+
+    xi[atCG]  = -bond_cc+bond_cc*cos(ANGLE_6RING);
+    yi[atCG]  = 0;
+    xi[atCD1] = -bond_cc;
+    yi[atCD1] = bond_cc*sin(0.5*ANGLE_6RING);
+    xi[atHD1] = xi[atCD1]+bond_ch*cos(ANGLE_6RING);
+    yi[atHD1] = yi[atCD1]+bond_ch*sin(ANGLE_6RING);
+    xi[atCE1] = 0;
+    yi[atCE1] = yi[atCD1];
+    xi[atHE1] = xi[atCE1]-bond_ch*cos(ANGLE_6RING);
+    yi[atHE1] = yi[atCE1]+bond_ch*sin(ANGLE_6RING);
+    xi[atCD2] = xi[atCD1];
+    yi[atCD2] = -yi[atCD1];
+    xi[atHD2] = xi[atHD1];
+    yi[atHD2] = -yi[atHD1];
+    xi[atCE2] = xi[atCE1];
+    yi[atCE2] = -yi[atCE1];
+    xi[atHE2] = xi[atHE1];
+    yi[atHE2] = -yi[atHE1];
+    xi[atCZ]  = bond_cc*cos(0.5*ANGLE_6RING);
+    yi[atCZ]  = 0;
+    xi[atOH]  = xi[atCZ]+bond_co;
+    yi[atOH]  = 0;
+
+    xcom = mtot = 0;
+    for (i = 0; i < atOH; i++)
+    {
+        xcom += xi[i]*at->atom[ats[i]].m;
+        mtot += at->atom[ats[i]].m;
+    }
+    xcom /= mtot;
+
+    /* first do 6 ring as default,
+       except CZ (we'll do that different) and HZ (we don't have that): */
+    nvsite = gen_vsites_6ring(at, vsite_type, plist, nrfound, ats, bond_cc, bond_ch, xcom, FALSE);
+
+    /* then construct CZ from the 2nd triangle */
+    /* vsite3 construction: r_d = r_i + a r_ij + b r_ik */
+    a = b = 0.5 * bond_co / ( bond_co - bond_cc*cos(ANGLE_6RING) );
+    add_vsite3_param(&plist[F_VSITE3],
+                     ats[atCZ], ats[atOH], ats[atCE1], ats[atCE2], a, b);
+    at->atom[ats[atCZ]].m = at->atom[ats[atCZ]].mB = 0;
+
+    /* constraints between CE1, CE2 and OH */
+    dCGCE = sqrt( cosrule(bond_cc, bond_cc, ANGLE_6RING) );
+    dCEOH = sqrt( cosrule(bond_cc, bond_co, ANGLE_6RING) );
+    my_add_param(&(plist[F_CONSTRNC]), ats[atCE1], ats[atOH], dCEOH);
+    my_add_param(&(plist[F_CONSTRNC]), ats[atCE2], ats[atOH], dCEOH);
+
+    /* We also want to constrain the angle C-O-H, but since CZ is constructed
+     * we need to introduce a constraint to CG.
+     * CG is much further away, so that will lead to instabilities in LINCS
+     * when we constrain both CG-HH and OH-HH distances. Instead of requiring
+     * the use of lincs_order=8 we introduce a dummy mass three times further
+     * away from OH than HH. The mass is accordingly a third, with the remaining
+     * 2/3 moved to OH. This shouldnt cause any problems since the forces will
+     * apply to the HH constructed atom and not directly on the virtual mass.
+     */
+
+    vdist                   = 2.0*bond_oh;
+    mM                      = at->atom[ats[atHH]].m/2.0;
+    at->atom[ats[atOH]].m  += mM; /* add 1/2 of original H mass */
+    at->atom[ats[atOH]].mB += mM; /* add 1/2 of original H mass */
+    at->atom[ats[atHH]].m   = at->atom[ats[atHH]].mB = 0;
+
+    /* get dummy mass type */
+    tpM = vsite_nm2type("MW", atype);
+    /* make space for 1 mass: shift HH only */
+    i0  = ats[atHH];
+    atM = i0+*nadd;
+    if (debug)
+    {
+        fprintf(stderr, "Inserting 1 dummy mass at %d\n", (*o2n)[i0]+1);
+    }
+    (*nadd)++;
+    for (j = i0; j < at->nr; j++)
+    {
+        (*o2n)[j] = j+*nadd;
+    }
+    srenew(*newx, at->nr+*nadd);
+    srenew(*newatom, at->nr+*nadd);
+    srenew(*newatomname, at->nr+*nadd);
+    srenew(*newvsite_type, at->nr+*nadd);
+    srenew(*newcgnr, at->nr+*nadd);
+    (*newatomname)[at->nr+*nadd-1] = NULL;
+
+    /* Calc the dummy mass initial position */
+    rvec_sub(x[ats[atHH]], x[ats[atOH]], r1);
+    svmul(2.0, r1, r1);
+    rvec_add(r1, x[ats[atHH]], (*newx)[atM]);
+
+    strcpy(name, "MW1");
+    (*newatomname)  [atM]         = put_symtab(symtab, name);
+    (*newatom)      [atM].m       = (*newatom)[atM].mB    = mM;
+    (*newatom)      [atM].q       = (*newatom)[atM].qB    = 0.0;
+    (*newatom)      [atM].type    = (*newatom)[atM].typeB = tpM;
+    (*newatom)      [atM].ptype   = eptAtom;
+    (*newatom)      [atM].resind  = at->atom[i0].resind;
+    (*newatom)      [atM].elem[0] = 'M';
+    (*newatom)      [atM].elem[1] = '\0';
+    (*newvsite_type)[atM]         = NOTSET;
+    (*newcgnr)      [atM]         = (*cgnr)[i0];
+    /* renumber cgnr: */
+    for (i = i0; i < at->nr; i++)
+    {
+        (*cgnr)[i]++;
+    }
+
+    (*vsite_type)[ats[atHH]] = F_VSITE2;
+    nvsite++;
+    /* assume we also want the COH angle constrained: */
+    tmp1 = bond_cc*cos(0.5*ANGLE_6RING) + dCGCE*sin(ANGLE_6RING*0.5) + bond_co;
+    dCGM = sqrt( cosrule(tmp1, vdist, angle_coh) );
+    my_add_param(&(plist[F_CONSTRNC]), ats[atCG], add_shift+atM, dCGM);
+    my_add_param(&(plist[F_CONSTRNC]), ats[atOH], add_shift+atM, vdist);
+
+    add_vsite2_param(&plist[F_VSITE2],
+                     ats[atHH], ats[atOH], add_shift+atM, 1.0/2.0);
+    return nvsite;
 }
-      
-static int gen_vsites_his(t_atoms *at, int *vsite_type[], t_params plist[], 
-                       int nrfound, int *ats, t_vsitetop *vsitetop, int nvsitetop)
+
+static int gen_vsites_his(t_atoms *at, int *vsite_type[], t_params plist[],
+                          int nrfound, int *ats, t_vsitetop *vsitetop, int nvsitetop)
 {
-  int nvsite,i;
-  real a,b,alpha,dCGCE1,dCGNE2;
-  real sinalpha,cosalpha;
-  real xcom,ycom,mtot;
-  real mG,mrest,mCE1,mNE2;
-  real b_CG_ND1,b_ND1_CE1,b_CE1_NE2,b_CG_CD2,b_CD2_NE2;
-  real b_ND1_HD1,b_NE2_HE2,b_CE1_HE1,b_CD2_HD2;
-  real a_CG_ND1_CE1,a_CG_CD2_NE2,a_ND1_CE1_NE2,a_CE1_NE2_CD2;
-  real a_NE2_CE1_HE1,a_NE2_CD2_HD2,a_CE1_ND1_HD1,a_CE1_NE2_HE2;
-  char resname[10];
-
-  /* these MUST correspond to the atnms array in do_vsite_aromatics! */
-  enum { atCG, atND1, atHD1, atCD2, atHD2, atCE1, atHE1, atNE2, atHE2, atNR };
-  real x[atNR],y[atNR];
-
-  /* CG, CE1 and NE2 stay, each gets part of the total mass,
-     rest gets virtualized */
-  /* check number of atoms, 3 hydrogens may be missing: */
-  /* assert( nrfound >= atNR-3 || nrfound <= atNR );
-   * Don't understand the above logic. Shouldn't it be && rather than || ???
-   */
-  if ((nrfound < atNR-3) || (nrfound > atNR))
-    gmx_incons("Generating vsites for HIS");
-  
-  /* avoid warnings about uninitialized variables */
-  b_ND1_HD1=b_NE2_HE2=b_CE1_HE1=b_CD2_HD2=a_NE2_CE1_HE1=
-    a_NE2_CD2_HD2=a_CE1_ND1_HD1=a_CE1_NE2_HE2=0;
-
-  if(ats[atHD1]!=NOTSET) {
-    if(ats[atHE2]!=NOTSET) 
-      sprintf(resname,"HISH");
-    else 
-      sprintf(resname,"HISA");
-  } else {
-    sprintf(resname,"HISB");
-  }
-  
-  /* Get geometry from database */
-  b_CG_ND1=get_ddb_bond(vsitetop,nvsitetop,resname,"CG","ND1");
-  b_ND1_CE1=get_ddb_bond(vsitetop,nvsitetop,resname,"ND1","CE1");
-  b_CE1_NE2=get_ddb_bond(vsitetop,nvsitetop,resname,"CE1","NE2");
-  b_CG_CD2 =get_ddb_bond(vsitetop,nvsitetop,resname,"CG","CD2");
-  b_CD2_NE2=get_ddb_bond(vsitetop,nvsitetop,resname,"CD2","NE2");
-  a_CG_ND1_CE1=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,resname,"CG","ND1","CE1");
-  a_CG_CD2_NE2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,resname,"CG","CD2","NE2");
-  a_ND1_CE1_NE2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,resname,"ND1","CE1","NE2");
-  a_CE1_NE2_CD2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,resname,"CE1","NE2","CD2");
-
-  if(ats[atHD1]!=NOTSET) {
-    b_ND1_HD1=get_ddb_bond(vsitetop,nvsitetop,resname,"ND1","HD1");
-    a_CE1_ND1_HD1=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,resname,"CE1","ND1","HD1");
-  }
-  if(ats[atHE2]!=NOTSET) {
-    b_NE2_HE2=get_ddb_bond(vsitetop,nvsitetop,resname,"NE2","HE2");
-    a_CE1_NE2_HE2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,resname,"CE1","NE2","HE2");
-  }
-  if(ats[atHD2]!=NOTSET) {
-    b_CD2_HD2=get_ddb_bond(vsitetop,nvsitetop,resname,"CD2","HD2");
-    a_NE2_CD2_HD2=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,resname,"NE2","CD2","HD2");
-  }
-  if(ats[atHE1]!=NOTSET) {
-    b_CE1_HE1=get_ddb_bond(vsitetop,nvsitetop,resname,"CE1","HE1");
-    a_NE2_CE1_HE1=DEG2RAD*get_ddb_angle(vsitetop,nvsitetop,resname,"NE2","CE1","HE1");
-  }
-
-  /* constraints between CG, CE1 and NE1 */
-  dCGCE1   = sqrt( cosrule(b_CG_ND1,b_ND1_CE1,a_CG_ND1_CE1) );
-  dCGNE2   = sqrt( cosrule(b_CG_CD2,b_CD2_NE2,a_CG_CD2_NE2) );
-
-  my_add_param(&(plist[F_CONSTRNC]),ats[atCG] ,ats[atCE1],dCGCE1);
-  my_add_param(&(plist[F_CONSTRNC]),ats[atCG] ,ats[atNE2],dCGNE2);
-  /* we already have a constraint CE1-NE2, so we don't add it again */
-  
-  /* calculate the positions in a local frame of reference. 
-   * The x-axis is the line from CG that makes a right angle
-   * with the bond CE1-NE2, and the y-axis the bond CE1-NE2.
-   */
-  /* First calculate the x-axis intersection with y-axis (=yCE1).
-   * Get cos(angle CG-CE1-NE2) :
-   */
-  cosalpha=acosrule(dCGNE2,dCGCE1,b_CE1_NE2);
-  x[atCE1] = 0;
-  y[atCE1] = cosalpha*dCGCE1;
-  x[atNE2] = 0;
-  y[atNE2] = y[atCE1]-b_CE1_NE2;
-  sinalpha=sqrt(1-cosalpha*cosalpha);
-  x[atCG]  = - sinalpha*dCGCE1;
-  y[atCG]  = 0;
-  x[atHE1] = x[atHE2] = x[atHD1] = x[atHD2] = 0;
-  y[atHE1] = y[atHE2] = y[atHD1] = y[atHD2] = 0;
-  
-  /* calculate ND1 and CD2 positions from CE1 and NE2 */
-
-  x[atND1] = -b_ND1_CE1*sin(a_ND1_CE1_NE2);
-  y[atND1] = y[atCE1]-b_ND1_CE1*cos(a_ND1_CE1_NE2);
-
-  x[atCD2] = -b_CD2_NE2*sin(a_CE1_NE2_CD2);
-  y[atCD2] = y[atNE2]+b_CD2_NE2*cos(a_CE1_NE2_CD2);
-
-  /* And finally the hydrogen positions */
-  if(ats[atHE1]!=NOTSET) {  
-    x[atHE1] = x[atCE1] + b_CE1_HE1*sin(a_NE2_CE1_HE1);
-    y[atHE1] = y[atCE1] - b_CE1_HE1*cos(a_NE2_CE1_HE1);
-  }
-  /* HD2 - first get (ccw) angle from (positive) y-axis */
-  if(ats[atHD2]!=NOTSET) {  
-    alpha = a_CE1_NE2_CD2 + M_PI - a_NE2_CD2_HD2;
-    x[atHD2] = x[atCD2] - b_CD2_HD2*sin(alpha);
-    y[atHD2] = y[atCD2] + b_CD2_HD2*cos(alpha);
-  }
-  if(ats[atHD1]!=NOTSET) {
-    /* HD1 - first get (cw) angle from (positive) y-axis */
-    alpha = a_ND1_CE1_NE2 + M_PI - a_CE1_ND1_HD1;
-    x[atHD1] = x[atND1] - b_ND1_HD1*sin(alpha);
-    y[atHD1] = y[atND1] - b_ND1_HD1*cos(alpha);
-  }
-  if(ats[atHE2]!=NOTSET) {
-    x[atHE2] = x[atNE2] + b_NE2_HE2*sin(a_CE1_NE2_HE2);
-    y[atHE2] = y[atNE2] + b_NE2_HE2*cos(a_CE1_NE2_HE2);
-  }
-  /* Have all coordinates now */
-  
-  /* calc center-of-mass; keep atoms CG, CE1, NE2 and
-   * set the rest to vsite3
-   */
-  mtot=xcom=ycom=0;
-  nvsite=0;
-  for(i=0; i<atNR; i++) 
-    if (ats[i]!=NOTSET) {
-      mtot+=at->atom[ats[i]].m;
-      xcom+=x[i]*at->atom[ats[i]].m;
-      ycom+=y[i]*at->atom[ats[i]].m;
-      if (i!=atCG && i!=atCE1 && i!=atNE2) {
-       at->atom[ats[i]].m = at->atom[ats[i]].mB = 0;
-       (*vsite_type)[ats[i]]=F_VSITE3;
-       nvsite++;
-      }
-    } 
-  if (nvsite+3 != nrfound)
-    gmx_incons("Generating vsites for HIS");
-
-  xcom/=mtot;
-  ycom/=mtot;
-  
-  /* distribute mass so that com stays the same */
-  mG = xcom*mtot/x[atCG];
-  mrest = mtot-mG;
-  mCE1 = (ycom-y[atNE2])*mrest/(y[atCE1]-y[atNE2]);
-  mNE2 = mrest-mCE1;
-  
-  at->atom[ats[atCG]].m = at->atom[ats[atCG]].mB = mG;
-  at->atom[ats[atCE1]].m = at->atom[ats[atCE1]].mB = mCE1;
-  at->atom[ats[atNE2]].m = at->atom[ats[atNE2]].mB = mNE2;
-  
-  /* HE1 */
-  if (ats[atHE1]!=NOTSET) {
-    calc_vsite3_param(x[atHE1],y[atHE1],x[atCE1],y[atCE1],x[atNE2],y[atNE2],
-                     x[atCG],y[atCG],&a,&b);
-    add_vsite3_param(&plist[F_VSITE3],
-                  ats[atHE1],ats[atCE1],ats[atNE2],ats[atCG],a,b);
-  }
-  /* HE2 */
-  if (ats[atHE2]!=NOTSET) {
-    calc_vsite3_param(x[atHE2],y[atHE2],x[atNE2],y[atNE2],x[atCE1],y[atCE1],
-                     x[atCG],y[atCG],&a,&b);
-    add_vsite3_param(&plist[F_VSITE3],
-                  ats[atHE2],ats[atNE2],ats[atCE1],ats[atCG],a,b);
-  }
-  
-  /* ND1 */
-  calc_vsite3_param(x[atND1],y[atND1],x[atNE2],y[atNE2],x[atCE1],y[atCE1],
-                   x[atCG],y[atCG],&a,&b);
-  add_vsite3_param(&plist[F_VSITE3],
-                ats[atND1],ats[atNE2],ats[atCE1],ats[atCG],a,b);
-  
-  /* CD2 */
-  calc_vsite3_param(x[atCD2],y[atCD2],x[atCE1],y[atCE1],x[atNE2],y[atNE2],
-                   x[atCG],y[atCG],&a,&b);
-  add_vsite3_param(&plist[F_VSITE3],
-                ats[atCD2],ats[atCE1],ats[atNE2],ats[atCG],a,b);
-  
-  /* HD1 */
-  if (ats[atHD1]!=NOTSET) {
-    calc_vsite3_param(x[atHD1],y[atHD1],x[atNE2],y[atNE2],x[atCE1],y[atCE1],
-                     x[atCG],y[atCG],&a,&b);
+    int  nvsite, i;
+    real a, b, alpha, dCGCE1, dCGNE2;
+    real sinalpha, cosalpha;
+    real xcom, ycom, mtot;
+    real mG, mrest, mCE1, mNE2;
+    real b_CG_ND1, b_ND1_CE1, b_CE1_NE2, b_CG_CD2, b_CD2_NE2;
+    real b_ND1_HD1, b_NE2_HE2, b_CE1_HE1, b_CD2_HD2;
+    real a_CG_ND1_CE1, a_CG_CD2_NE2, a_ND1_CE1_NE2, a_CE1_NE2_CD2;
+    real a_NE2_CE1_HE1, a_NE2_CD2_HD2, a_CE1_ND1_HD1, a_CE1_NE2_HE2;
+    char resname[10];
+
+    /* these MUST correspond to the atnms array in do_vsite_aromatics! */
+    enum {
+        atCG, atND1, atHD1, atCD2, atHD2, atCE1, atHE1, atNE2, atHE2, atNR
+    };
+    real x[atNR], y[atNR];
+
+    /* CG, CE1 and NE2 stay, each gets part of the total mass,
+       rest gets virtualized */
+    /* check number of atoms, 3 hydrogens may be missing: */
+    /* assert( nrfound >= atNR-3 || nrfound <= atNR );
+     * Don't understand the above logic. Shouldn't it be && rather than || ???
+     */
+    if ((nrfound < atNR-3) || (nrfound > atNR))
+    {
+        gmx_incons("Generating vsites for HIS");
+    }
+
+    /* avoid warnings about uninitialized variables */
+    b_ND1_HD1 = b_NE2_HE2 = b_CE1_HE1 = b_CD2_HD2 = a_NE2_CE1_HE1 =
+                        a_NE2_CD2_HD2 = a_CE1_ND1_HD1 = a_CE1_NE2_HE2 = 0;
+
+    if (ats[atHD1] != NOTSET)
+    {
+        if (ats[atHE2] != NOTSET)
+        {
+            sprintf(resname, "HISH");
+        }
+        else
+        {
+            sprintf(resname, "HISA");
+        }
+    }
+    else
+    {
+        sprintf(resname, "HISB");
+    }
+
+    /* Get geometry from database */
+    b_CG_ND1      = get_ddb_bond(vsitetop, nvsitetop, resname, "CG", "ND1");
+    b_ND1_CE1     = get_ddb_bond(vsitetop, nvsitetop, resname, "ND1", "CE1");
+    b_CE1_NE2     = get_ddb_bond(vsitetop, nvsitetop, resname, "CE1", "NE2");
+    b_CG_CD2      = get_ddb_bond(vsitetop, nvsitetop, resname, "CG", "CD2");
+    b_CD2_NE2     = get_ddb_bond(vsitetop, nvsitetop, resname, "CD2", "NE2");
+    a_CG_ND1_CE1  = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, resname, "CG", "ND1", "CE1");
+    a_CG_CD2_NE2  = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, resname, "CG", "CD2", "NE2");
+    a_ND1_CE1_NE2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, resname, "ND1", "CE1", "NE2");
+    a_CE1_NE2_CD2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, resname, "CE1", "NE2", "CD2");
+
+    if (ats[atHD1] != NOTSET)
+    {
+        b_ND1_HD1     = get_ddb_bond(vsitetop, nvsitetop, resname, "ND1", "HD1");
+        a_CE1_ND1_HD1 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, resname, "CE1", "ND1", "HD1");
+    }
+    if (ats[atHE2] != NOTSET)
+    {
+        b_NE2_HE2     = get_ddb_bond(vsitetop, nvsitetop, resname, "NE2", "HE2");
+        a_CE1_NE2_HE2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, resname, "CE1", "NE2", "HE2");
+    }
+    if (ats[atHD2] != NOTSET)
+    {
+        b_CD2_HD2     = get_ddb_bond(vsitetop, nvsitetop, resname, "CD2", "HD2");
+        a_NE2_CD2_HD2 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, resname, "NE2", "CD2", "HD2");
+    }
+    if (ats[atHE1] != NOTSET)
+    {
+        b_CE1_HE1     = get_ddb_bond(vsitetop, nvsitetop, resname, "CE1", "HE1");
+        a_NE2_CE1_HE1 = DEG2RAD*get_ddb_angle(vsitetop, nvsitetop, resname, "NE2", "CE1", "HE1");
+    }
+
+    /* constraints between CG, CE1 and NE1 */
+    dCGCE1   = sqrt( cosrule(b_CG_ND1, b_ND1_CE1, a_CG_ND1_CE1) );
+    dCGNE2   = sqrt( cosrule(b_CG_CD2, b_CD2_NE2, a_CG_CD2_NE2) );
+
+    my_add_param(&(plist[F_CONSTRNC]), ats[atCG], ats[atCE1], dCGCE1);
+    my_add_param(&(plist[F_CONSTRNC]), ats[atCG], ats[atNE2], dCGNE2);
+    /* we already have a constraint CE1-NE2, so we don't add it again */
+
+    /* calculate the positions in a local frame of reference.
+     * The x-axis is the line from CG that makes a right angle
+     * with the bond CE1-NE2, and the y-axis the bond CE1-NE2.
+     */
+    /* First calculate the x-axis intersection with y-axis (=yCE1).
+     * Get cos(angle CG-CE1-NE2) :
+     */
+    cosalpha = acosrule(dCGNE2, dCGCE1, b_CE1_NE2);
+    x[atCE1] = 0;
+    y[atCE1] = cosalpha*dCGCE1;
+    x[atNE2] = 0;
+    y[atNE2] = y[atCE1]-b_CE1_NE2;
+    sinalpha = sqrt(1-cosalpha*cosalpha);
+    x[atCG]  = -sinalpha*dCGCE1;
+    y[atCG]  = 0;
+    x[atHE1] = x[atHE2] = x[atHD1] = x[atHD2] = 0;
+    y[atHE1] = y[atHE2] = y[atHD1] = y[atHD2] = 0;
+
+    /* calculate ND1 and CD2 positions from CE1 and NE2 */
+
+    x[atND1] = -b_ND1_CE1*sin(a_ND1_CE1_NE2);
+    y[atND1] = y[atCE1]-b_ND1_CE1*cos(a_ND1_CE1_NE2);
+
+    x[atCD2] = -b_CD2_NE2*sin(a_CE1_NE2_CD2);
+    y[atCD2] = y[atNE2]+b_CD2_NE2*cos(a_CE1_NE2_CD2);
+
+    /* And finally the hydrogen positions */
+    if (ats[atHE1] != NOTSET)
+    {
+        x[atHE1] = x[atCE1] + b_CE1_HE1*sin(a_NE2_CE1_HE1);
+        y[atHE1] = y[atCE1] - b_CE1_HE1*cos(a_NE2_CE1_HE1);
+    }
+    /* HD2 - first get (ccw) angle from (positive) y-axis */
+    if (ats[atHD2] != NOTSET)
+    {
+        alpha    = a_CE1_NE2_CD2 + M_PI - a_NE2_CD2_HD2;
+        x[atHD2] = x[atCD2] - b_CD2_HD2*sin(alpha);
+        y[atHD2] = y[atCD2] + b_CD2_HD2*cos(alpha);
+    }
+    if (ats[atHD1] != NOTSET)
+    {
+        /* HD1 - first get (cw) angle from (positive) y-axis */
+        alpha    = a_ND1_CE1_NE2 + M_PI - a_CE1_ND1_HD1;
+        x[atHD1] = x[atND1] - b_ND1_HD1*sin(alpha);
+        y[atHD1] = y[atND1] - b_ND1_HD1*cos(alpha);
+    }
+    if (ats[atHE2] != NOTSET)
+    {
+        x[atHE2] = x[atNE2] + b_NE2_HE2*sin(a_CE1_NE2_HE2);
+        y[atHE2] = y[atNE2] + b_NE2_HE2*cos(a_CE1_NE2_HE2);
+    }
+    /* Have all coordinates now */
+
+    /* calc center-of-mass; keep atoms CG, CE1, NE2 and
+     * set the rest to vsite3
+     */
+    mtot   = xcom = ycom = 0;
+    nvsite = 0;
+    for (i = 0; i < atNR; i++)
+    {
+        if (ats[i] != NOTSET)
+        {
+            mtot += at->atom[ats[i]].m;
+            xcom += x[i]*at->atom[ats[i]].m;
+            ycom += y[i]*at->atom[ats[i]].m;
+            if (i != atCG && i != atCE1 && i != atNE2)
+            {
+                at->atom[ats[i]].m    = at->atom[ats[i]].mB = 0;
+                (*vsite_type)[ats[i]] = F_VSITE3;
+                nvsite++;
+            }
+        }
+    }
+    if (nvsite+3 != nrfound)
+    {
+        gmx_incons("Generating vsites for HIS");
+    }
+
+    xcom /= mtot;
+    ycom /= mtot;
+
+    /* distribute mass so that com stays the same */
+    mG    = xcom*mtot/x[atCG];
+    mrest = mtot-mG;
+    mCE1  = (ycom-y[atNE2])*mrest/(y[atCE1]-y[atNE2]);
+    mNE2  = mrest-mCE1;
+
+    at->atom[ats[atCG]].m  = at->atom[ats[atCG]].mB = mG;
+    at->atom[ats[atCE1]].m = at->atom[ats[atCE1]].mB = mCE1;
+    at->atom[ats[atNE2]].m = at->atom[ats[atNE2]].mB = mNE2;
+
+    /* HE1 */
+    if (ats[atHE1] != NOTSET)
+    {
+        calc_vsite3_param(x[atHE1], y[atHE1], x[atCE1], y[atCE1], x[atNE2], y[atNE2],
+                          x[atCG], y[atCG], &a, &b);
+        add_vsite3_param(&plist[F_VSITE3],
+                         ats[atHE1], ats[atCE1], ats[atNE2], ats[atCG], a, b);
+    }
+    /* HE2 */
+    if (ats[atHE2] != NOTSET)
+    {
+        calc_vsite3_param(x[atHE2], y[atHE2], x[atNE2], y[atNE2], x[atCE1], y[atCE1],
+                          x[atCG], y[atCG], &a, &b);
+        add_vsite3_param(&plist[F_VSITE3],
+                         ats[atHE2], ats[atNE2], ats[atCE1], ats[atCG], a, b);
+    }
+
+    /* ND1 */
+    calc_vsite3_param(x[atND1], y[atND1], x[atNE2], y[atNE2], x[atCE1], y[atCE1],
+                      x[atCG], y[atCG], &a, &b);
     add_vsite3_param(&plist[F_VSITE3],
-                  ats[atHD1],ats[atNE2],ats[atCE1],ats[atCG],a,b);
-  }
-  /* HD2 */
-  if (ats[atHD2]!=NOTSET) {
-    calc_vsite3_param(x[atHD2],y[atHD2],x[atCE1],y[atCE1],x[atNE2],y[atNE2],
-                     x[atCG],y[atCG],&a,&b);
+                     ats[atND1], ats[atNE2], ats[atCE1], ats[atCG], a, b);
+
+    /* CD2 */
+    calc_vsite3_param(x[atCD2], y[atCD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2],
+                      x[atCG], y[atCG], &a, &b);
     add_vsite3_param(&plist[F_VSITE3],
-                  ats[atHD2],ats[atCE1],ats[atNE2],ats[atCG],a,b);
-  }  
-  return nvsite;
+                     ats[atCD2], ats[atCE1], ats[atNE2], ats[atCG], a, b);
+
+    /* HD1 */
+    if (ats[atHD1] != NOTSET)
+    {
+        calc_vsite3_param(x[atHD1], y[atHD1], x[atNE2], y[atNE2], x[atCE1], y[atCE1],
+                          x[atCG], y[atCG], &a, &b);
+        add_vsite3_param(&plist[F_VSITE3],
+                         ats[atHD1], ats[atNE2], ats[atCE1], ats[atCG], a, b);
+    }
+    /* HD2 */
+    if (ats[atHD2] != NOTSET)
+    {
+        calc_vsite3_param(x[atHD2], y[atHD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2],
+                          x[atCG], y[atCG], &a, &b);
+        add_vsite3_param(&plist[F_VSITE3],
+                         ats[atHD2], ats[atCE1], ats[atNE2], ats[atCG], a, b);
+    }
+    return nvsite;
 }
 
 static gmx_bool is_vsite(int vsite_type)
 {
-  if (vsite_type == NOTSET)
-    return FALSE;
-  switch ( abs(vsite_type) ) {
-  case F_VSITE3:
-  case F_VSITE3FD:
-  case F_VSITE3OUT:
-  case F_VSITE3FAD:
-  case F_VSITE4FD:
-  case F_VSITE4FDN:
-    return TRUE;
-  default:
-    return FALSE;
-  }
+    if (vsite_type == NOTSET)
+    {
+        return FALSE;
+    }
+    switch (abs(vsite_type) )
+    {
+        case F_VSITE3:
+        case F_VSITE3FD:
+        case F_VSITE3OUT:
+        case F_VSITE3FAD:
+        case F_VSITE4FD:
+        case F_VSITE4FDN:
+            return TRUE;
+        default:
+            return FALSE;
+    }
 }
 
 static char atomnamesuffix[] = "1234";
 
-void do_vsites(int nrtp, t_restp rtp[], gpp_atomtype_t atype, 
-              t_atoms *at, t_symtab *symtab, rvec *x[], 
-              t_params plist[], int *vsite_type[], int *cgnr[], 
-              real mHmult, gmx_bool bVsiteAromatics,
-              const char *ffdir)
+void do_vsites(int nrtp, t_restp rtp[], gpp_atomtype_t atype,
+               t_atoms *at, t_symtab *symtab, rvec *x[],
+               t_params plist[], int *vsite_type[], int *cgnr[],
+               real mHmult, gmx_bool bVsiteAromatics,
+               const char *ffdir)
 {
 #define MAXATOMSPERRESIDUE 16
-  int  i,j,k,m,i0,ni0,whatres,resind,add_shift,ftype,nvsite,nadd;
-  int  ai,aj,ak,al;
-  int  nrfound=0,needed,nrbonds,nrHatoms,Heavy,nrheavies,tpM,tpHeavy;
-  int  Hatoms[4],heavies[4],bb;
-  gmx_bool bWARNING,bAddVsiteParam,bFirstWater;
-  matrix tmpmat;
-  gmx_bool *bResProcessed;
-  real mHtot,mtot,fact,fact2;
-  rvec rpar,rperp,temp;
-  char name[10],tpname[32],nexttpname[32],*ch;
-  rvec *newx;
-  int  *o2n,*newvsite_type,*newcgnr,ats[MAXATOMSPERRESIDUE];
-  t_atom *newatom;
-  t_params *params;
-  char ***newatomname;
-  char *resnm=NULL;
-  int  ndb,f;
-  char **db;
-  int  nvsiteconf,nvsitetop,cmplength;
-  gmx_bool isN,planarN,bFound;
-  gmx_residuetype_t rt;
-    
-  t_vsiteconf *vsiteconflist; 
-  /* pointer to a list of CH3/NH3/NH2 configuration entries.
-   * See comments in read_vsite_database. It isnt beautiful,
-   * but it had to be fixed, and I dont even want to try to 
-   * maintain this part of the code...
-   */
-  t_vsitetop *vsitetop;       
-  /* Pointer to a list of geometry (bond/angle) entries for
-   * residues like PHE, TRP, TYR, HIS, etc., where we need
-   * to know the geometry to construct vsite aromatics.
-   * Note that equilibrium geometry isnt necessarily the same
-   * as the individual bond and angle values given in the
-   * force field (rings can be strained).
-   */
-
-  /* if bVsiteAromatics=TRUE do_vsites will specifically convert atoms in 
-     PHE, TRP, TYR and HIS to a construction of virtual sites */
-  enum                    { resPHE, resTRP, resTYR, resHIS, resNR };
-  const char *resnms[resNR]   = {   "PHE",  "TRP",  "TYR",  "HIS" };
-       /* Amber03 alternative names for termini */
-  const char *resnmsN[resNR]  = {  "NPHE", "NTRP", "NTYR", "NHIS" };
-  const char *resnmsC[resNR]  = {  "CPHE", "CTRP", "CTYR", "CHIS" };
-  /* HIS can be known as HISH, HIS1, HISA, HID, HIE, HIP, etc. too */
-  gmx_bool bPartial[resNR]  = {  FALSE,  FALSE,  FALSE,   TRUE  };
-  /* the atnms for every residue MUST correspond to the enums in the 
-     gen_vsites_* (one for each residue) routines! */
-  /* also the atom names in atnms MUST be in the same order as in the .rtp! */
-  const char *atnms[resNR][MAXATOMSPERRESIDUE+1] = { 
-    { "CG", /* PHE */
-      "CD1", "HD1", "CD2", "HD2", 
-      "CE1", "HE1", "CE2", "HE2", 
-      "CZ", "HZ", NULL },
-    { "CB", /* TRP */
-      "CG",
-      "CD1", "HD1", "CD2", 
-      "NE1", "HE1", "CE2", "CE3", "HE3", 
-      "CZ2", "HZ2", "CZ3", "HZ3", 
-      "CH2", "HH2", NULL },
-    { "CG", /* TYR */
-      "CD1", "HD1", "CD2", "HD2", 
-      "CE1", "HE1", "CE2", "HE2", 
-      "CZ", "OH", "HH", NULL },
-    { "CG", /* HIS */
-      "ND1", "HD1", "CD2", "HD2",
-      "CE1", "HE1", "NE2", "HE2", NULL }
-  };
-    
-  if (debug) {
-    printf("Searching for atoms to make virtual sites ...\n");
-    fprintf(debug,"# # # VSITES # # #\n");
-  }
-
-  ndb = fflib_search_file_end(ffdir,".vsd",FALSE,&db);
-  nvsiteconf    = 0;
-  vsiteconflist = NULL;
-  nvsitetop     = 0;
-  vsitetop      = NULL;
-  for(f=0; f<ndb; f++) {
-    read_vsite_database(db[f],&vsiteconflist,&nvsiteconf,&vsitetop,&nvsitetop);
-    sfree(db[f]);
-  }
-  sfree(db);
-  
-  bFirstWater=TRUE;
-  nvsite=0;
-  nadd=0;
-  /* we need a marker for which atoms should *not* be renumbered afterwards */
-  add_shift = 10*at->nr;
-  /* make arrays where masses can be inserted into */ 
-  snew(newx,at->nr); 
-  snew(newatom,at->nr);
-  snew(newatomname,at->nr);
-  snew(newvsite_type,at->nr);
-  snew(newcgnr,at->nr);
-  /* make index array to tell where the atoms go to when masses are inserted */
-  snew(o2n,at->nr);
-  for(i=0; i<at->nr; i++)
-    o2n[i]=i;
-  /* make index to tell which residues were already processed */
-  snew(bResProcessed,at->nres);
-    
-  gmx_residuetype_init(&rt);
-    
-  /* generate vsite constructions */
-  /* loop over all atoms */
-  resind = -1;
-  for(i=0; (i<at->nr); i++) {
-    if (at->atom[i].resind != resind) {
-      resind = at->atom[i].resind;
-      resnm  = *(at->resinfo[resind].name);
-    }
-    /* first check for aromatics to virtualize */
-    /* don't waste our effort on DNA, water etc. */
-    /* Only do the vsite aromatic stuff when we reach the 
-     * CA atom, since there might be an X2/X3 group on the
-     * N-terminus that must be treated first.
+    int               i, j, k, m, i0, ni0, whatres, resind, add_shift, ftype, nvsite, nadd;
+    int               ai, aj, ak, al;
+    int               nrfound = 0, needed, nrbonds, nrHatoms, Heavy, nrheavies, tpM, tpHeavy;
+    int               Hatoms[4], heavies[4], bb;
+    gmx_bool          bWARNING, bAddVsiteParam, bFirstWater;
+    matrix            tmpmat;
+    gmx_bool         *bResProcessed;
+    real              mHtot, mtot, fact, fact2;
+    rvec              rpar, rperp, temp;
+    char              name[10], tpname[32], nexttpname[32], *ch;
+    rvec             *newx;
+    int              *o2n, *newvsite_type, *newcgnr, ats[MAXATOMSPERRESIDUE];
+    t_atom           *newatom;
+    t_params         *params;
+    char           ***newatomname;
+    char             *resnm = NULL;
+    int               ndb, f;
+    char            **db;
+    int               nvsiteconf, nvsitetop, cmplength;
+    gmx_bool          isN, planarN, bFound;
+    gmx_residuetype_t*rt;
+
+    t_vsiteconf      *vsiteconflist;
+    /* pointer to a list of CH3/NH3/NH2 configuration entries.
+     * See comments in read_vsite_database. It isnt beautiful,
+     * but it had to be fixed, and I dont even want to try to
+     * maintain this part of the code...
      */
-    if ( bVsiteAromatics &&
-        !strcmp(*(at->atomname[i]),"CA") &&
-        !bResProcessed[resind] &&
-        gmx_residuetype_is_protein(rt,*(at->resinfo[resind].name)) ) {
-      /* mark this residue */
-      bResProcessed[resind] = TRUE;
-      /* find out if this residue needs converting */
-      whatres=NOTSET;
-      for(j=0; j<resNR && whatres==NOTSET; j++) {
-                 
-       cmplength = bPartial[j] ? strlen(resnm)-1 : strlen(resnm);
-       
-       bFound = ((gmx_strncasecmp(resnm,resnms[j], cmplength)==0) ||
-                 (gmx_strncasecmp(resnm,resnmsN[j],cmplength)==0) ||
-                 (gmx_strncasecmp(resnm,resnmsC[j],cmplength)==0));
-       
-       if ( bFound ) {
-         whatres=j;
-         /* get atoms we will be needing for the conversion */
-         nrfound=0;
-         for (k=0; atnms[j][k]; k++) 
-      {
-           ats[k]=NOTSET;
-          for(m=i; m<at->nr && at->atom[m].resind==resind && ats[k]==NOTSET;m++) 
+    t_vsitetop *vsitetop;
+    /* Pointer to a list of geometry (bond/angle) entries for
+     * residues like PHE, TRP, TYR, HIS, etc., where we need
+     * to know the geometry to construct vsite aromatics.
+     * Note that equilibrium geometry isnt necessarily the same
+     * as the individual bond and angle values given in the
+     * force field (rings can be strained).
+     */
+
+    /* if bVsiteAromatics=TRUE do_vsites will specifically convert atoms in
+       PHE, TRP, TYR and HIS to a construction of virtual sites */
+    enum                    {
+        resPHE, resTRP, resTYR, resHIS, resNR
+    };
+    const char *resnms[resNR]   = {   "PHE",  "TRP",  "TYR",  "HIS" };
+    /* Amber03 alternative names for termini */
+    const char *resnmsN[resNR]  = {  "NPHE", "NTRP", "NTYR", "NHIS" };
+    const char *resnmsC[resNR]  = {  "CPHE", "CTRP", "CTYR", "CHIS" };
+    /* HIS can be known as HISH, HIS1, HISA, HID, HIE, HIP, etc. too */
+    gmx_bool    bPartial[resNR]  = {  FALSE,  FALSE,  FALSE,   TRUE  };
+    /* the atnms for every residue MUST correspond to the enums in the
+       gen_vsites_* (one for each residue) routines! */
+    /* also the atom names in atnms MUST be in the same order as in the .rtp! */
+    const char *atnms[resNR][MAXATOMSPERRESIDUE+1] = {
+        { "CG", /* PHE */
+          "CD1", "HD1", "CD2", "HD2",
+          "CE1", "HE1", "CE2", "HE2",
+          "CZ", "HZ", NULL },
+        { "CB", /* TRP */
+          "CG",
+          "CD1", "HD1", "CD2",
+          "NE1", "HE1", "CE2", "CE3", "HE3",
+          "CZ2", "HZ2", "CZ3", "HZ3",
+          "CH2", "HH2", NULL },
+        { "CG", /* TYR */
+          "CD1", "HD1", "CD2", "HD2",
+          "CE1", "HE1", "CE2", "HE2",
+          "CZ", "OH", "HH", NULL },
+        { "CG", /* HIS */
+          "ND1", "HD1", "CD2", "HD2",
+          "CE1", "HE1", "NE2", "HE2", NULL }
+    };
+
+    if (debug)
+    {
+        printf("Searching for atoms to make virtual sites ...\n");
+        fprintf(debug, "# # # VSITES # # #\n");
+    }
+
+    ndb           = fflib_search_file_end(ffdir, ".vsd", FALSE, &db);
+    nvsiteconf    = 0;
+    vsiteconflist = NULL;
+    nvsitetop     = 0;
+    vsitetop      = NULL;
+    for (f = 0; f < ndb; f++)
+    {
+        read_vsite_database(db[f], &vsiteconflist, &nvsiteconf, &vsitetop, &nvsitetop);
+        sfree(db[f]);
+    }
+    sfree(db);
+
+    bFirstWater = TRUE;
+    nvsite      = 0;
+    nadd        = 0;
+    /* we need a marker for which atoms should *not* be renumbered afterwards */
+    add_shift = 10*at->nr;
+    /* make arrays where masses can be inserted into */
+    snew(newx, at->nr);
+    snew(newatom, at->nr);
+    snew(newatomname, at->nr);
+    snew(newvsite_type, at->nr);
+    snew(newcgnr, at->nr);
+    /* make index array to tell where the atoms go to when masses are inserted */
+    snew(o2n, at->nr);
+    for (i = 0; i < at->nr; i++)
+    {
+        o2n[i] = i;
+    }
+    /* make index to tell which residues were already processed */
+    snew(bResProcessed, at->nres);
+
+    gmx_residuetype_init(&rt);
+
+    /* generate vsite constructions */
+    /* loop over all atoms */
+    resind = -1;
+    for (i = 0; (i < at->nr); i++)
+    {
+        if (at->atom[i].resind != resind)
         {
-             if (gmx_strcasecmp(*(at->atomname[m]),atnms[j][k])==0) 
-          {
-              ats[k]=m;
-              nrfound++;
-             }
-           }
-         }
-        
-      /* now k is number of atom names in atnms[j] */
-      if (j==resHIS)
-      {
-          needed = k-3;
-      }
-         else
-         {
-          needed = k;
-      }
-      if (nrfound<needed)
-         {
-          gmx_fatal(FARGS,"not enough atoms found (%d, need %d) in "
-                    "residue %s %d while\n             "
-                    "generating aromatics virtual site construction",
-                    nrfound,needed,resnm,at->resinfo[resind].nr);
-      }
-      /* Advance overall atom counter */
-      i++;
-    }
-      }
-      /* the enums for every residue MUST correspond to atnms[residue] */
-      switch (whatres) {
-      case resPHE: 
-       if (debug) fprintf(stderr,"PHE at %d\n",o2n[ats[0]]+1);
-       nvsite+=gen_vsites_phe(at, vsite_type, plist, nrfound, ats, vsitetop, nvsitetop);
-       break;
-      case resTRP: 
-       if (debug) fprintf(stderr,"TRP at %d\n",o2n[ats[0]]+1);
-       nvsite+=gen_vsites_trp(atype, &newx, &newatom, &newatomname, &o2n, 
-                          &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr,
-                          at, vsite_type, plist, nrfound, ats, add_shift, vsitetop, nvsitetop);
-       break;
-      case resTYR: 
-       if (debug) fprintf(stderr,"TYR at %d\n",o2n[ats[0]]+1);
-       nvsite+=gen_vsites_tyr(atype, &newx, &newatom, &newatomname, &o2n, 
-                          &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr,
-                          at, vsite_type, plist, nrfound, ats, add_shift, vsitetop, nvsitetop);
-       break;
-      case resHIS: 
-       if (debug) fprintf(stderr,"HIS at %d\n",o2n[ats[0]]+1);
-       nvsite+=gen_vsites_his(at, vsite_type, plist, nrfound, ats, vsitetop, nvsitetop);
-       break;
-      case NOTSET:
-       /* this means this residue won't be processed */
-       break;
-      default:
-       gmx_fatal(FARGS,"DEATH HORROR in do_vsites (%s:%d)",
-                   __FILE__,__LINE__);
-      } /* switch whatres */
-      /* skip back to beginning of residue */
-      while(i>0 && at->atom[i-1].resind == resind)
-       i--;
-    } /* if bVsiteAromatics & is protein */
-    
-    /* now process the rest of the hydrogens */
-    /* only process hydrogen atoms which are not already set */
-    if ( ((*vsite_type)[i]==NOTSET) && is_hydrogen(*(at->atomname[i]))) {
-      /* find heavy atom, count #bonds from it and #H atoms bound to it
-        and return H atom numbers (Hatoms) and heavy atom numbers (heavies) */
-      count_bonds(i, &plist[F_BONDS], at->atomname, 
-                 &nrbonds, &nrHatoms, Hatoms, &Heavy, &nrheavies, heavies);
-      /* get Heavy atom type */
-      tpHeavy=get_atype(Heavy,at,nrtp,rtp,rt);
-      strcpy(tpname,get_atomtype_name(tpHeavy,atype));
-
-      bWARNING=FALSE;
-      bAddVsiteParam=TRUE;
-      /* nested if's which check nrHatoms, nrbonds and atomname */
-      if (nrHatoms == 1) {
-       switch(nrbonds) {
-       case 2: /* -O-H */
-         (*vsite_type)[i]=F_BONDS;
-         break;
-       case 3: /* =CH-, -NH- or =NH+- */
-         (*vsite_type)[i]=F_VSITE3FD;
-         break;
-       case 4: /* --CH- (tert) */
-        /* The old type 4FD had stability issues, so 
-         * all new constructs should use 4FDN
+            resind = at->atom[i].resind;
+            resnm  = *(at->resinfo[resind].name);
+        }
+        /* first check for aromatics to virtualize */
+        /* don't waste our effort on DNA, water etc. */
+        /* Only do the vsite aromatic stuff when we reach the
+         * CA atom, since there might be an X2/X3 group on the
+         * N-terminus that must be treated first.
          */
-         (*vsite_type)[i]=F_VSITE4FDN;
-        
-        /* Check parity of heavy atoms from coordinates */
-        ai = Heavy;
-        aj = heavies[0];
-        ak = heavies[1];
-        al = heavies[2];
-        rvec_sub((*x)[aj],(*x)[ai],tmpmat[0]);
-        rvec_sub((*x)[ak],(*x)[ai],tmpmat[1]);
-        rvec_sub((*x)[al],(*x)[ai],tmpmat[2]);
-        
-        if(det(tmpmat)>0)
+        if (bVsiteAromatics &&
+            !strcmp(*(at->atomname[i]), "CA") &&
+            !bResProcessed[resind] &&
+            gmx_residuetype_is_protein(rt, *(at->resinfo[resind].name)) )
         {
-            /* swap parity */
-            heavies[1] = aj;
-            heavies[0] = ak;
-        }
-        
-         break;
-       default: /* nrbonds != 2, 3 or 4 */
-         bWARNING=TRUE;
-       }
-       
-      } else if ( /*(nrHatoms == 2) && (nrbonds == 2) && REMOVED this test
-                  DvdS 19-01-04 */
-                 (gmx_strncasecmp(*at->atomname[Heavy],"OW",2)==0) ) {
-       bAddVsiteParam=FALSE; /* this is water: skip these hydrogens */
-       if (bFirstWater) {
-         bFirstWater=FALSE;
-         if (debug)
-           fprintf(debug,
-                   "Not converting hydrogens in water to virtual sites\n");
-       }
-      } else if ( (nrHatoms == 2) && (nrbonds == 4) ) {
-       /* -CH2- , -NH2+- */
-       (*vsite_type)[Hatoms[0]] = F_VSITE3OUT;
-       (*vsite_type)[Hatoms[1]] =-F_VSITE3OUT;
-      } else {
-       /* 2 or 3 hydrogen atom, with 3 or 4 bonds in total to the heavy atom.
-        * If it is a nitrogen, first check if it is planar.
-        */
-       isN=planarN=FALSE;
-       if((nrHatoms == 2) && ((*at->atomname[Heavy])[0]=='N')) {
-         isN=TRUE;
-         j=nitrogen_is_planar(vsiteconflist,nvsiteconf,tpname);
-         if(j<0) 
-           gmx_fatal(FARGS,"No vsite database NH2 entry for type %s\n",tpname);
-         planarN=(j==1);
-       }
-       if ( (nrHatoms == 2) && (nrbonds == 3) && ( !isN || planarN ) ) {
-         /* =CH2 or, if it is a nitrogen NH2, it is a planar one */
-         (*vsite_type)[Hatoms[0]] = F_VSITE3FAD;
-         (*vsite_type)[Hatoms[1]] =-F_VSITE3FAD;
-       } else if ( ( (nrHatoms == 2) && (nrbonds == 3) && 
-                     ( isN && !planarN ) ) || 
-                   ( (nrHatoms == 3) && (nrbonds == 4) ) ) {
-         /* CH3, NH3 or non-planar NH2 group */
-       int  Hat_vsite_type[3] = { F_VSITE3, F_VSITE3OUT, F_VSITE3OUT };
-       gmx_bool Hat_SwapParity[3] = { FALSE,    TRUE,        FALSE };
-       
-       if (debug) fprintf(stderr,"-XH3 or nonplanar NH2 group at %d\n",i+1);
-       bAddVsiteParam=FALSE; /* we'll do this ourselves! */
-       /* -NH2 (umbrella), -NH3+ or -CH3 */
-       (*vsite_type)[Heavy]       = F_VSITE3;
-       for (j=0; j<nrHatoms; j++)
-         (*vsite_type)[Hatoms[j]] = Hat_vsite_type[j];
-       /* get dummy mass type from first char of heavy atom type (N or C) */
-       
-       strcpy(nexttpname,get_atomtype_name(get_atype(heavies[0],at,nrtp,rtp,rt),atype));
-       ch=get_dummymass_name(vsiteconflist,nvsiteconf,tpname,nexttpname);
-
-       if (ch == NULL) {
-         if (ndb > 0) {
-           gmx_fatal(FARGS,"Can't find dummy mass for type %s bonded to type %s in the virtual site database (.vsd files). Add it to the database!\n",tpname,nexttpname);
-         } else {
-            gmx_fatal(FARGS,"A dummy mass for type %s bonded to type %s is required, but no virtual site database (.vsd) files where found.\n",tpname,nexttpname);
-         }
-       } else {
-         strcpy(name,ch);
-       }
-
-       tpM=vsite_nm2type(name,atype);
-       /* make space for 2 masses: shift all atoms starting with 'Heavy' */
+            /* mark this residue */
+            bResProcessed[resind] = TRUE;
+            /* find out if this residue needs converting */
+            whatres = NOTSET;
+            for (j = 0; j < resNR && whatres == NOTSET; j++)
+            {
+
+                cmplength = bPartial[j] ? strlen(resnm)-1 : strlen(resnm);
+
+                bFound = ((gmx_strncasecmp(resnm, resnms[j], cmplength) == 0) ||
+                          (gmx_strncasecmp(resnm, resnmsN[j], cmplength) == 0) ||
+                          (gmx_strncasecmp(resnm, resnmsC[j], cmplength) == 0));
+
+                if (bFound)
+                {
+                    whatres = j;
+                    /* get atoms we will be needing for the conversion */
+                    nrfound = 0;
+                    for (k = 0; atnms[j][k]; k++)
+                    {
+                        ats[k] = NOTSET;
+                        for (m = i; m < at->nr && at->atom[m].resind == resind && ats[k] == NOTSET; m++)
+                        {
+                            if (gmx_strcasecmp(*(at->atomname[m]), atnms[j][k]) == 0)
+                            {
+                                ats[k] = m;
+                                nrfound++;
+                            }
+                        }
+                    }
+
+                    /* now k is number of atom names in atnms[j] */
+                    if (j == resHIS)
+                    {
+                        needed = k-3;
+                    }
+                    else
+                    {
+                        needed = k;
+                    }
+                    if (nrfound < needed)
+                    {
+                        gmx_fatal(FARGS, "not enough atoms found (%d, need %d) in "
+                                  "residue %s %d while\n             "
+                                  "generating aromatics virtual site construction",
+                                  nrfound, needed, resnm, at->resinfo[resind].nr);
+                    }
+                    /* Advance overall atom counter */
+                    i++;
+                }
+            }
+            /* the enums for every residue MUST correspond to atnms[residue] */
+            switch (whatres)
+            {
+                case resPHE:
+                    if (debug)
+                    {
+                        fprintf(stderr, "PHE at %d\n", o2n[ats[0]]+1);
+                    }
+                    nvsite += gen_vsites_phe(at, vsite_type, plist, nrfound, ats, vsitetop, nvsitetop);
+                    break;
+                case resTRP:
+                    if (debug)
+                    {
+                        fprintf(stderr, "TRP at %d\n", o2n[ats[0]]+1);
+                    }
+                    nvsite += gen_vsites_trp(atype, &newx, &newatom, &newatomname, &o2n,
+                                             &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr,
+                                             at, vsite_type, plist, nrfound, ats, add_shift, vsitetop, nvsitetop);
+                    break;
+                case resTYR:
+                    if (debug)
+                    {
+                        fprintf(stderr, "TYR at %d\n", o2n[ats[0]]+1);
+                    }
+                    nvsite += gen_vsites_tyr(atype, &newx, &newatom, &newatomname, &o2n,
+                                             &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr,
+                                             at, vsite_type, plist, nrfound, ats, add_shift, vsitetop, nvsitetop);
+                    break;
+                case resHIS:
+                    if (debug)
+                    {
+                        fprintf(stderr, "HIS at %d\n", o2n[ats[0]]+1);
+                    }
+                    nvsite += gen_vsites_his(at, vsite_type, plist, nrfound, ats, vsitetop, nvsitetop);
+                    break;
+                case NOTSET:
+                    /* this means this residue won't be processed */
+                    break;
+                default:
+                    gmx_fatal(FARGS, "DEATH HORROR in do_vsites (%s:%d)",
+                              __FILE__, __LINE__);
+            } /* switch whatres */
+              /* skip back to beginning of residue */
+            while (i > 0 && at->atom[i-1].resind == resind)
+            {
+                i--;
+            }
+        } /* if bVsiteAromatics & is protein */
+
+        /* now process the rest of the hydrogens */
+        /* only process hydrogen atoms which are not already set */
+        if ( ((*vsite_type)[i] == NOTSET) && is_hydrogen(*(at->atomname[i])))
+        {
+            /* find heavy atom, count #bonds from it and #H atoms bound to it
+               and return H atom numbers (Hatoms) and heavy atom numbers (heavies) */
+            count_bonds(i, &plist[F_BONDS], at->atomname,
+                        &nrbonds, &nrHatoms, Hatoms, &Heavy, &nrheavies, heavies);
+            /* get Heavy atom type */
+            tpHeavy = get_atype(Heavy, at, nrtp, rtp, rt);
+            strcpy(tpname, get_atomtype_name(tpHeavy, atype));
+
+            bWARNING       = FALSE;
+            bAddVsiteParam = TRUE;
+            /* nested if's which check nrHatoms, nrbonds and atomname */
+            if (nrHatoms == 1)
+            {
+                switch (nrbonds)
+                {
+                    case 2: /* -O-H */
+                        (*vsite_type)[i] = F_BONDS;
+                        break;
+                    case 3: /* =CH-, -NH- or =NH+- */
+                        (*vsite_type)[i] = F_VSITE3FD;
+                        break;
+                    case 4: /* --CH- (tert) */
+                        /* The old type 4FD had stability issues, so
+                         * all new constructs should use 4FDN
+                         */
+                        (*vsite_type)[i] = F_VSITE4FDN;
+
+                        /* Check parity of heavy atoms from coordinates */
+                        ai = Heavy;
+                        aj = heavies[0];
+                        ak = heavies[1];
+                        al = heavies[2];
+                        rvec_sub((*x)[aj], (*x)[ai], tmpmat[0]);
+                        rvec_sub((*x)[ak], (*x)[ai], tmpmat[1]);
+                        rvec_sub((*x)[al], (*x)[ai], tmpmat[2]);
+
+                        if (det(tmpmat) > 0)
+                        {
+                            /* swap parity */
+                            heavies[1] = aj;
+                            heavies[0] = ak;
+                        }
+
+                        break;
+                    default: /* nrbonds != 2, 3 or 4 */
+                        bWARNING = TRUE;
+                }
+
+            }
+            else if ( /*(nrHatoms == 2) && (nrbonds == 2) && REMOVED this test
+                         DvdS 19-01-04 */
+                (gmx_strncasecmp(*at->atomname[Heavy], "OW", 2) == 0) )
+            {
+                bAddVsiteParam = FALSE; /* this is water: skip these hydrogens */
+                if (bFirstWater)
+                {
+                    bFirstWater = FALSE;
+                    if (debug)
+                    {
+                        fprintf(debug,
+                                "Not converting hydrogens in water to virtual sites\n");
+                    }
+                }
+            }
+            else if ( (nrHatoms == 2) && (nrbonds == 4) )
+            {
+                /* -CH2- , -NH2+- */
+                (*vsite_type)[Hatoms[0]] = F_VSITE3OUT;
+                (*vsite_type)[Hatoms[1]] = -F_VSITE3OUT;
+            }
+            else
+            {
+                /* 2 or 3 hydrogen atom, with 3 or 4 bonds in total to the heavy atom.
+                 * If it is a nitrogen, first check if it is planar.
+                 */
+                isN = planarN = FALSE;
+                if ((nrHatoms == 2) && ((*at->atomname[Heavy])[0] == 'N'))
+                {
+                    isN = TRUE;
+                    j   = nitrogen_is_planar(vsiteconflist, nvsiteconf, tpname);
+                    if (j < 0)
+                    {
+                        gmx_fatal(FARGS, "No vsite database NH2 entry for type %s\n", tpname);
+                    }
+                    planarN = (j == 1);
+                }
+                if ( (nrHatoms == 2) && (nrbonds == 3) && ( !isN || planarN ) )
+                {
+                    /* =CH2 or, if it is a nitrogen NH2, it is a planar one */
+                    (*vsite_type)[Hatoms[0]] = F_VSITE3FAD;
+                    (*vsite_type)[Hatoms[1]] = -F_VSITE3FAD;
+                }
+                else if ( ( (nrHatoms == 2) && (nrbonds == 3) &&
+                            ( isN && !planarN ) ) ||
+                          ( (nrHatoms == 3) && (nrbonds == 4) ) )
+                {
+                    /* CH3, NH3 or non-planar NH2 group */
+                    int      Hat_vsite_type[3] = { F_VSITE3, F_VSITE3OUT, F_VSITE3OUT };
+                    gmx_bool Hat_SwapParity[3] = { FALSE,    TRUE,        FALSE };
+
+                    if (debug)
+                    {
+                        fprintf(stderr, "-XH3 or nonplanar NH2 group at %d\n", i+1);
+                    }
+                    bAddVsiteParam = FALSE; /* we'll do this ourselves! */
+                    /* -NH2 (umbrella), -NH3+ or -CH3 */
+                    (*vsite_type)[Heavy]       = F_VSITE3;
+                    for (j = 0; j < nrHatoms; j++)
+                    {
+                        (*vsite_type)[Hatoms[j]] = Hat_vsite_type[j];
+                    }
+                    /* get dummy mass type from first char of heavy atom type (N or C) */
+
+                    strcpy(nexttpname, get_atomtype_name(get_atype(heavies[0], at, nrtp, rtp, rt), atype));
+                    ch = get_dummymass_name(vsiteconflist, nvsiteconf, tpname, nexttpname);
+
+                    if (ch == NULL)
+                    {
+                        if (ndb > 0)
+                        {
+                            gmx_fatal(FARGS, "Can't find dummy mass for type %s bonded to type %s in the virtual site database (.vsd files). Add it to the database!\n", tpname, nexttpname);
+                        }
+                        else
+                        {
+                            gmx_fatal(FARGS, "A dummy mass for type %s bonded to type %s is required, but no virtual site database (.vsd) files where found.\n", tpname, nexttpname);
+                        }
+                    }
+                    else
+                    {
+                        strcpy(name, ch);
+                    }
+
+                    tpM = vsite_nm2type(name, atype);
+                    /* make space for 2 masses: shift all atoms starting with 'Heavy' */
 #define NMASS 2
-       i0=Heavy;
-       ni0=i0+nadd;
-       if (debug) 
-         fprintf(stderr,"Inserting %d dummy masses at %d\n",NMASS,o2n[i0]+1);
-       nadd+=NMASS;
-       for(j=i0; j<at->nr; j++)
-         o2n[j]=j+nadd; 
-
-       srenew(newx,at->nr+nadd);
-       srenew(newatom,at->nr+nadd);
-       srenew(newatomname,at->nr+nadd);
-       srenew(newvsite_type,at->nr+nadd);
-       srenew(newcgnr,at->nr+nadd);
-
-       for(j=0; j<NMASS; j++)
-         newatomname[at->nr+nadd-1-j]=NULL;
-
-       /* calculate starting position for the masses */
-       mHtot=0;
-       /* get atom masses, and set Heavy and Hatoms mass to zero */
-       for(j=0; j<nrHatoms; j++) {
-         mHtot += get_amass(Hatoms[j],at,nrtp,rtp,rt);
-         at->atom[Hatoms[j]].m = at->atom[Hatoms[j]].mB = 0;
-       }
-       mtot = mHtot + get_amass(Heavy,at,nrtp,rtp,rt);
-       at->atom[Heavy].m = at->atom[Heavy].mB = 0;
-       if (mHmult != 1.0)
-         mHtot *= mHmult;
-       fact2=mHtot/mtot;
-       fact=sqrt(fact2);
-       /* generate vectors parallel and perpendicular to rotational axis:
-        * rpar  = Heavy -> Hcom
-        * rperp = Hcom  -> H1   */
-       clear_rvec(rpar);
-       for(j=0; j<nrHatoms; j++)
-         rvec_inc(rpar,(*x)[Hatoms[j]]);
-       svmul(1.0/nrHatoms,rpar,rpar); /* rpar = ( H1+H2+H3 ) / 3 */
-       rvec_dec(rpar,(*x)[Heavy]);    /*        - Heavy          */
-       rvec_sub((*x)[Hatoms[0]],(*x)[Heavy],rperp);
-       rvec_dec(rperp,rpar);          /* rperp = H1 - Heavy - rpar */
-       /* calc mass positions */
-       svmul(fact2,rpar,temp);
-       for (j=0; (j<NMASS); j++) /* xM = xN + fact2 * rpar +/- fact * rperp */
-         rvec_add((*x)[Heavy],temp,newx[ni0+j]);
-       svmul(fact,rperp,temp);
-       rvec_inc(newx[ni0  ],temp);
-       rvec_dec(newx[ni0+1],temp);
-       /* set atom parameters for the masses */
-       for(j=0; (j<NMASS); j++) {
-         /* make name: "M??#" or "M?#" (? is atomname, # is number) */
-         name[0]='M';
-         for(k=0; (*at->atomname[Heavy])[k] && ( k < NMASS ); k++ )
-           name[k+1]=(*at->atomname[Heavy])[k];
-         name[k+1]=atomnamesuffix[j];
-         name[k+2]='\0';
-         newatomname[ni0+j]   = put_symtab(symtab,name);
-         newatom[ni0+j].m     = newatom[ni0+j].mB    = mtot/NMASS;
-         newatom[ni0+j].q     = newatom[ni0+j].qB    = 0.0;
-         newatom[ni0+j].type  = newatom[ni0+j].typeB = tpM;
-         newatom[ni0+j].ptype = eptAtom;
-         newatom[ni0+j].resind= at->atom[i0].resind;
-         newvsite_type[ni0+j] = NOTSET;
-         newcgnr[ni0+j]       = (*cgnr)[i0];
-       }
-       /* add constraints between dummy masses and to heavies[0] */
-       /* 'add_shift' says which atoms won't be renumbered afterwards */
-       my_add_param(&(plist[F_CONSTRNC]),heavies[0],  add_shift+ni0,  NOTSET);
-       my_add_param(&(plist[F_CONSTRNC]),heavies[0],  add_shift+ni0+1,NOTSET);
-       my_add_param(&(plist[F_CONSTRNC]),add_shift+ni0,add_shift+ni0+1,NOTSET);
-       
-       /* generate Heavy, H1, H2 and H3 from M1, M2 and heavies[0] */
-       /* note that vsite_type cannot be NOTSET, because we just set it */
-       add_vsite3_atoms  (&plist[(*vsite_type)[Heavy]],
-                        Heavy,     heavies[0], add_shift+ni0, add_shift+ni0+1,
-                        FALSE);
-       for(j=0; j<nrHatoms; j++)
-         add_vsite3_atoms(&plist[(*vsite_type)[Hatoms[j]]], 
-                        Hatoms[j], heavies[0], add_shift+ni0, add_shift+ni0+1,
-                        Hat_SwapParity[j]);
+                    i0  = Heavy;
+                    ni0 = i0+nadd;
+                    if (debug)
+                    {
+                        fprintf(stderr, "Inserting %d dummy masses at %d\n", NMASS, o2n[i0]+1);
+                    }
+                    nadd += NMASS;
+                    for (j = i0; j < at->nr; j++)
+                    {
+                        o2n[j] = j+nadd;
+                    }
+
+                    srenew(newx, at->nr+nadd);
+                    srenew(newatom, at->nr+nadd);
+                    srenew(newatomname, at->nr+nadd);
+                    srenew(newvsite_type, at->nr+nadd);
+                    srenew(newcgnr, at->nr+nadd);
+
+                    for (j = 0; j < NMASS; j++)
+                    {
+                        newatomname[at->nr+nadd-1-j] = NULL;
+                    }
+
+                    /* calculate starting position for the masses */
+                    mHtot = 0;
+                    /* get atom masses, and set Heavy and Hatoms mass to zero */
+                    for (j = 0; j < nrHatoms; j++)
+                    {
+                        mHtot                += get_amass(Hatoms[j], at, nrtp, rtp, rt);
+                        at->atom[Hatoms[j]].m = at->atom[Hatoms[j]].mB = 0;
+                    }
+                    mtot              = mHtot + get_amass(Heavy, at, nrtp, rtp, rt);
+                    at->atom[Heavy].m = at->atom[Heavy].mB = 0;
+                    if (mHmult != 1.0)
+                    {
+                        mHtot *= mHmult;
+                    }
+                    fact2 = mHtot/mtot;
+                    fact  = sqrt(fact2);
+                    /* generate vectors parallel and perpendicular to rotational axis:
+                     * rpar  = Heavy -> Hcom
+                     * rperp = Hcom  -> H1   */
+                    clear_rvec(rpar);
+                    for (j = 0; j < nrHatoms; j++)
+                    {
+                        rvec_inc(rpar, (*x)[Hatoms[j]]);
+                    }
+                    svmul(1.0/nrHatoms, rpar, rpar); /* rpar = ( H1+H2+H3 ) / 3 */
+                    rvec_dec(rpar, (*x)[Heavy]);     /*        - Heavy          */
+                    rvec_sub((*x)[Hatoms[0]], (*x)[Heavy], rperp);
+                    rvec_dec(rperp, rpar);           /* rperp = H1 - Heavy - rpar */
+                    /* calc mass positions */
+                    svmul(fact2, rpar, temp);
+                    for (j = 0; (j < NMASS); j++) /* xM = xN + fact2 * rpar +/- fact * rperp */
+                    {
+                        rvec_add((*x)[Heavy], temp, newx[ni0+j]);
+                    }
+                    svmul(fact, rperp, temp);
+                    rvec_inc(newx[ni0  ], temp);
+                    rvec_dec(newx[ni0+1], temp);
+                    /* set atom parameters for the masses */
+                    for (j = 0; (j < NMASS); j++)
+                    {
+                        /* make name: "M??#" or "M?#" (? is atomname, # is number) */
+                        name[0] = 'M';
+                        for (k = 0; (*at->atomname[Heavy])[k] && ( k < NMASS ); k++)
+                        {
+                            name[k+1] = (*at->atomname[Heavy])[k];
+                        }
+                        name[k+1]              = atomnamesuffix[j];
+                        name[k+2]              = '\0';
+                        newatomname[ni0+j]     = put_symtab(symtab, name);
+                        newatom[ni0+j].m       = newatom[ni0+j].mB    = mtot/NMASS;
+                        newatom[ni0+j].q       = newatom[ni0+j].qB    = 0.0;
+                        newatom[ni0+j].type    = newatom[ni0+j].typeB = tpM;
+                        newatom[ni0+j].ptype   = eptAtom;
+                        newatom[ni0+j].resind  = at->atom[i0].resind;
+                        newatom[ni0+j].elem[0] = 'M';
+                        newatom[ni0+j].elem[1] = '\0';
+                        newvsite_type[ni0+j]   = NOTSET;
+                        newcgnr[ni0+j]         = (*cgnr)[i0];
+                    }
+                    /* add constraints between dummy masses and to heavies[0] */
+                    /* 'add_shift' says which atoms won't be renumbered afterwards */
+                    my_add_param(&(plist[F_CONSTRNC]), heavies[0],  add_shift+ni0,  NOTSET);
+                    my_add_param(&(plist[F_CONSTRNC]), heavies[0],  add_shift+ni0+1, NOTSET);
+                    my_add_param(&(plist[F_CONSTRNC]), add_shift+ni0, add_shift+ni0+1, NOTSET);
+
+                    /* generate Heavy, H1, H2 and H3 from M1, M2 and heavies[0] */
+                    /* note that vsite_type cannot be NOTSET, because we just set it */
+                    add_vsite3_atoms  (&plist[(*vsite_type)[Heavy]],
+                                       Heavy,     heavies[0], add_shift+ni0, add_shift+ni0+1,
+                                       FALSE);
+                    for (j = 0; j < nrHatoms; j++)
+                    {
+                        add_vsite3_atoms(&plist[(*vsite_type)[Hatoms[j]]],
+                                         Hatoms[j], heavies[0], add_shift+ni0, add_shift+ni0+1,
+                                         Hat_SwapParity[j]);
+                    }
 #undef NMASS
-       } else
-         bWARNING=TRUE;
-    
-      }
-      if (bWARNING)
-       fprintf(stderr,
-               "Warning: cannot convert atom %d %s (bound to a heavy atom "
-               "%s with \n"
-               "         %d bonds and %d bound hydrogens atoms) to virtual site\n",
-               i+1,*(at->atomname[i]),tpname,nrbonds,nrHatoms);
-      if (bAddVsiteParam) {
-       /* add vsite parameters to topology, 
-          also get rid of negative vsite_types */
-       add_vsites(plist, (*vsite_type), Heavy, nrHatoms, Hatoms,
-                  nrheavies, heavies);
-       /* transfer mass of virtual site to Heavy atom */
-       for(j=0; j<nrHatoms; j++) 
-         if (is_vsite((*vsite_type)[Hatoms[j]])) {
-           at->atom[Heavy].m += at->atom[Hatoms[j]].m;
-           at->atom[Heavy].mB = at->atom[Heavy].m;
-           at->atom[Hatoms[j]].m = at->atom[Hatoms[j]].mB = 0;
-         }
-      }
-      nvsite+=nrHatoms;
-      if (debug) {
-       fprintf(debug,"atom %d: ",o2n[i]+1);
-       print_bonds(debug,o2n,nrHatoms,Hatoms,Heavy,nrheavies,heavies);
-      }
-    } /* if vsite NOTSET & is hydrogen */
-    
-  } /* for i < at->nr */
-
-  gmx_residuetype_destroy(rt);
-    
-  if (debug) {
-    fprintf(debug,"Before inserting new atoms:\n");
-    for(i=0; i<at->nr; i++)
-      fprintf(debug,"%4d %4d %4s %4d %4s %6d %-10s\n",i+1,o2n[i]+1,
-             at->atomname[i]?*(at->atomname[i]):"(NULL)",
-             at->resinfo[at->atom[i].resind].nr,
-             at->resinfo[at->atom[i].resind].name ?
-             *(at->resinfo[at->atom[i].resind].name):"(NULL)",
-             (*cgnr)[i],
-             ((*vsite_type)[i]==NOTSET) ? 
-             "NOTSET" : interaction_function[(*vsite_type)[i]].name);
-    fprintf(debug,"new atoms to be inserted:\n");
-    for(i=0; i<at->nr+nadd; i++)
-      if (newatomname[i])
-       fprintf(debug,"%4d %4s %4d %6d %-10s\n",i+1,
-               newatomname[i]?*(newatomname[i]):"(NULL)",
-               newatom[i].resind,newcgnr[i],
-               (newvsite_type[i]==NOTSET) ? 
-               "NOTSET" : interaction_function[newvsite_type[i]].name);
-  }
-  
-  /* add all original atoms to the new arrays, using o2n index array */
-  for(i=0; i<at->nr; i++) {
-    newatomname  [o2n[i]] = at->atomname [i];
-    newatom      [o2n[i]] = at->atom     [i];
-    newvsite_type[o2n[i]] = (*vsite_type)[i];
-    newcgnr      [o2n[i]] = (*cgnr)      [i];
-    copy_rvec((*x)[i],newx[o2n[i]]);
-  }
-  /* throw away old atoms */
-  sfree(at->atom);
-  sfree(at->atomname);
-  sfree(*vsite_type);
-  sfree(*cgnr);
-  sfree(*x);
-  /* put in the new ones */
-  at->nr      += nadd;
-  at->atom     = newatom;
-  at->atomname = newatomname;
-  *vsite_type  = newvsite_type;
-  *cgnr        = newcgnr;
-  *x           = newx;
-  if (at->nr > add_shift)
-    gmx_fatal(FARGS,"Added impossible amount of dummy masses "
-               "(%d on a total of %d atoms)\n",nadd,at->nr-nadd);
-  
-  if (debug) {
-    fprintf(debug,"After inserting new atoms:\n");
-    for(i=0; i<at->nr; i++)
-      fprintf(debug,"%4d %4s %4d %4s %6d %-10s\n",i+1,
-             at->atomname[i]?*(at->atomname[i]):"(NULL)",
-             at->resinfo[at->atom[i].resind].nr, 
-             at->resinfo[at->atom[i].resind].name ?
-             *(at->resinfo[at->atom[i].resind].name):"(NULL)",
-             (*cgnr)[i],
-             ((*vsite_type)[i]==NOTSET) ? 
-             "NOTSET" : interaction_function[(*vsite_type)[i]].name);
-  }
-  
-  /* now renumber all the interactions because of the added atoms */
-  for (ftype=0; ftype<F_NRE; ftype++) {
-    params=&(plist[ftype]);
+                }
+                else
+                {
+                    bWARNING = TRUE;
+                }
+
+            }
+            if (bWARNING)
+            {
+                fprintf(stderr,
+                        "Warning: cannot convert atom %d %s (bound to a heavy atom "
+                        "%s with \n"
+                        "         %d bonds and %d bound hydrogens atoms) to virtual site\n",
+                        i+1, *(at->atomname[i]), tpname, nrbonds, nrHatoms);
+            }
+            if (bAddVsiteParam)
+            {
+                /* add vsite parameters to topology,
+                   also get rid of negative vsite_types */
+                add_vsites(plist, (*vsite_type), Heavy, nrHatoms, Hatoms,
+                           nrheavies, heavies);
+                /* transfer mass of virtual site to Heavy atom */
+                for (j = 0; j < nrHatoms; j++)
+                {
+                    if (is_vsite((*vsite_type)[Hatoms[j]]))
+                    {
+                        at->atom[Heavy].m    += at->atom[Hatoms[j]].m;
+                        at->atom[Heavy].mB    = at->atom[Heavy].m;
+                        at->atom[Hatoms[j]].m = at->atom[Hatoms[j]].mB = 0;
+                    }
+                }
+            }
+            nvsite += nrHatoms;
+            if (debug)
+            {
+                fprintf(debug, "atom %d: ", o2n[i]+1);
+                print_bonds(debug, o2n, nrHatoms, Hatoms, Heavy, nrheavies, heavies);
+            }
+        } /* if vsite NOTSET & is hydrogen */
+
+    }     /* for i < at->nr */
+
+    gmx_residuetype_destroy(rt);
+
     if (debug)
-      fprintf(debug,"Renumbering %d %s\n", params->nr,
-             interaction_function[ftype].longname);
-    for (i=0; i<params->nr; i++) {
-      for (j=0; j<NRAL(ftype); j++)
-       if (params->param[i].a[j]>=add_shift) {
-         if (debug) fprintf(debug," [%u -> %u]",params->param[i].a[j],
-                            params->param[i].a[j]-add_shift);
-         params->param[i].a[j]=params->param[i].a[j]-add_shift;
-       } else {
-         if (debug) fprintf(debug," [%u -> %d]",params->param[i].a[j],
-                            o2n[params->param[i].a[j]]);
-         params->param[i].a[j]=o2n[params->param[i].a[j]];
-       }
-      if (debug) fprintf(debug,"\n");
-    }
-  }
-  /* now check if atoms in the added constraints are in increasing order */
-  params=&(plist[F_CONSTRNC]);
-  for(i=0; i<params->nr; i++)
-    if ( params->param[i].AI > params->param[i].AJ ) {
-      j                   = params->param[i].AJ;
-      params->param[i].AJ = params->param[i].AI;
-      params->param[i].AI = j;
-    }
-  
-  /* clean up */
-  sfree(o2n);
-  
-  /* tell the user what we did */
-  fprintf(stderr,"Marked %d virtual sites\n",nvsite);
-  fprintf(stderr,"Added %d dummy masses\n",nadd);
-  fprintf(stderr,"Added %d new constraints\n",plist[F_CONSTRNC].nr);
+    {
+        fprintf(debug, "Before inserting new atoms:\n");
+        for (i = 0; i < at->nr; i++)
+        {
+            fprintf(debug, "%4d %4d %4s %4d %4s %6d %-10s\n", i+1, o2n[i]+1,
+                    at->atomname[i] ? *(at->atomname[i]) : "(NULL)",
+                    at->resinfo[at->atom[i].resind].nr,
+                    at->resinfo[at->atom[i].resind].name ?
+                    *(at->resinfo[at->atom[i].resind].name) : "(NULL)",
+                    (*cgnr)[i],
+                    ((*vsite_type)[i] == NOTSET) ?
+                    "NOTSET" : interaction_function[(*vsite_type)[i]].name);
+        }
+        fprintf(debug, "new atoms to be inserted:\n");
+        for (i = 0; i < at->nr+nadd; i++)
+        {
+            if (newatomname[i])
+            {
+                fprintf(debug, "%4d %4s %4d %6d %-10s\n", i+1,
+                        newatomname[i] ? *(newatomname[i]) : "(NULL)",
+                        newatom[i].resind, newcgnr[i],
+                        (newvsite_type[i] == NOTSET) ?
+                        "NOTSET" : interaction_function[newvsite_type[i]].name);
+            }
+        }
+    }
+
+    /* add all original atoms to the new arrays, using o2n index array */
+    for (i = 0; i < at->nr; i++)
+    {
+        newatomname  [o2n[i]] = at->atomname [i];
+        newatom      [o2n[i]] = at->atom     [i];
+        newvsite_type[o2n[i]] = (*vsite_type)[i];
+        newcgnr      [o2n[i]] = (*cgnr)      [i];
+        copy_rvec((*x)[i], newx[o2n[i]]);
+    }
+    /* throw away old atoms */
+    sfree(at->atom);
+    sfree(at->atomname);
+    sfree(*vsite_type);
+    sfree(*cgnr);
+    sfree(*x);
+    /* put in the new ones */
+    at->nr      += nadd;
+    at->atom     = newatom;
+    at->atomname = newatomname;
+    *vsite_type  = newvsite_type;
+    *cgnr        = newcgnr;
+    *x           = newx;
+    if (at->nr > add_shift)
+    {
+        gmx_fatal(FARGS, "Added impossible amount of dummy masses "
+                  "(%d on a total of %d atoms)\n", nadd, at->nr-nadd);
+    }
+
+    if (debug)
+    {
+        fprintf(debug, "After inserting new atoms:\n");
+        for (i = 0; i < at->nr; i++)
+        {
+            fprintf(debug, "%4d %4s %4d %4s %6d %-10s\n", i+1,
+                    at->atomname[i] ? *(at->atomname[i]) : "(NULL)",
+                    at->resinfo[at->atom[i].resind].nr,
+                    at->resinfo[at->atom[i].resind].name ?
+                    *(at->resinfo[at->atom[i].resind].name) : "(NULL)",
+                    (*cgnr)[i],
+                    ((*vsite_type)[i] == NOTSET) ?
+                    "NOTSET" : interaction_function[(*vsite_type)[i]].name);
+        }
+    }
+
+    /* now renumber all the interactions because of the added atoms */
+    for (ftype = 0; ftype < F_NRE; ftype++)
+    {
+        params = &(plist[ftype]);
+        if (debug)
+        {
+            fprintf(debug, "Renumbering %d %s\n", params->nr,
+                    interaction_function[ftype].longname);
+        }
+        for (i = 0; i < params->nr; i++)
+        {
+            for (j = 0; j < NRAL(ftype); j++)
+            {
+                if (params->param[i].a[j] >= add_shift)
+                {
+                    if (debug)
+                    {
+                        fprintf(debug, " [%d -> %d]", params->param[i].a[j],
+                                params->param[i].a[j]-add_shift);
+                    }
+                    params->param[i].a[j] = params->param[i].a[j]-add_shift;
+                }
+                else
+                {
+                    if (debug)
+                    {
+                        fprintf(debug, " [%d -> %d]", params->param[i].a[j],
+                                o2n[params->param[i].a[j]]);
+                    }
+                    params->param[i].a[j] = o2n[params->param[i].a[j]];
+                }
+            }
+            if (debug)
+            {
+                fprintf(debug, "\n");
+            }
+        }
+    }
+    /* now check if atoms in the added constraints are in increasing order */
+    params = &(plist[F_CONSTRNC]);
+    for (i = 0; i < params->nr; i++)
+    {
+        if (params->param[i].AI > params->param[i].AJ)
+        {
+            j                   = params->param[i].AJ;
+            params->param[i].AJ = params->param[i].AI;
+            params->param[i].AI = j;
+        }
+    }
+
+    /* clean up */
+    sfree(o2n);
+
+    /* tell the user what we did */
+    fprintf(stderr, "Marked %d virtual sites\n", nvsite);
+    fprintf(stderr, "Added %d dummy masses\n", nadd);
+    fprintf(stderr, "Added %d new constraints\n", plist[F_CONSTRNC].nr);
 }
-  
+
 void do_h_mass(t_params *psb, int vsite_type[], t_atoms *at, real mHmult,
-              gmx_bool bDeuterate)
+               gmx_bool bDeuterate)
 {
-  int i,j,a;
-  
-  /* loop over all atoms */
-  for (i=0; i<at->nr; i++)
-    /* adjust masses if i is hydrogen and not a virtual site */
-    if ( !is_vsite(vsite_type[i]) && is_hydrogen(*(at->atomname[i])) ) {
-      /* find bonded heavy atom */
-      a=NOTSET;
-      for(j=0; (j<psb->nr) && (a==NOTSET); j++) {
-       /* if other atom is not a virtual site, it is the one we want */
-       if ( (psb->param[j].AI==i) && 
-            !is_vsite(vsite_type[psb->param[j].AJ]) )
-         a=psb->param[j].AJ;
-       else if ( (psb->param[j].AJ==i) && 
-                 !is_vsite(vsite_type[psb->param[j].AI]) )
-         a=psb->param[j].AI;
-      }
-      if (a==NOTSET)
-       gmx_fatal(FARGS,"Unbound hydrogen atom (%d) found while adjusting mass",
-                   i+1);
-      
-      /* adjust mass of i (hydrogen) with mHmult
-        and correct mass of a (bonded atom) with same amount */
-      if (!bDeuterate) {
-       at->atom[a].m -= (mHmult-1.0)*at->atom[i].m;
-       at->atom[a].mB-= (mHmult-1.0)*at->atom[i].m;
-      }
-      at->atom[i].m *= mHmult;
-      at->atom[i].mB*= mHmult;
+    int i, j, a;
+
+    /* loop over all atoms */
+    for (i = 0; i < at->nr; i++)
+    {
+        /* adjust masses if i is hydrogen and not a virtual site */
+        if (!is_vsite(vsite_type[i]) && is_hydrogen(*(at->atomname[i])) )
+        {
+            /* find bonded heavy atom */
+            a = NOTSET;
+            for (j = 0; (j < psb->nr) && (a == NOTSET); j++)
+            {
+                /* if other atom is not a virtual site, it is the one we want */
+                if ( (psb->param[j].AI == i) &&
+                     !is_vsite(vsite_type[psb->param[j].AJ]) )
+                {
+                    a = psb->param[j].AJ;
+                }
+                else if ( (psb->param[j].AJ == i) &&
+                          !is_vsite(vsite_type[psb->param[j].AI]) )
+                {
+                    a = psb->param[j].AI;
+                }
+            }
+            if (a == NOTSET)
+            {
+                gmx_fatal(FARGS, "Unbound hydrogen atom (%d) found while adjusting mass",
+                          i+1);
+            }
+
+            /* adjust mass of i (hydrogen) with mHmult
+               and correct mass of a (bonded atom) with same amount */
+            if (!bDeuterate)
+            {
+                at->atom[a].m  -= (mHmult-1.0)*at->atom[i].m;
+                at->atom[a].mB -= (mHmult-1.0)*at->atom[i].m;
+            }
+            at->atom[i].m  *= mHmult;
+            at->atom[i].mB *= mHmult;
+        }
     }
 }
-