Code beautification with uncrustify
[alexxy/gromacs.git] / src / tools / addconf.c
index c799b750c472ed5bc1712e3bff27abc2d5d11427..ef6723f07d3047f13249a0f528389f058e1180f7 100644 (file)
@@ -56,498 +56,606 @@ static real box_margin;
 
 static real max_dist(rvec *x, real *r, int start, int end)
 {
-  real maxd;
-  int i,j;
-
-  maxd=0;
-  for(i=start; i<end; i++)
-    for(j=i+1; j<end; j++)
-      maxd=max(maxd,sqrt(distance2(x[i],x[j]))+0.5*(r[i]+r[j]));
+    real maxd;
+    int  i, j;
+
+    maxd = 0;
+    for (i = start; i < end; i++)
+    {
+        for (j = i+1; j < end; j++)
+        {
+            maxd = max(maxd, sqrt(distance2(x[i], x[j]))+0.5*(r[i]+r[j]));
+        }
+    }
 
-  return 0.5*maxd;
+    return 0.5*maxd;
 }
 
-static gmx_bool outside_box_minus_margin2(rvec x,matrix box)
+static gmx_bool outside_box_minus_margin2(rvec x, matrix box)
 {
-  return ( (x[XX]<2*box_margin) || (x[XX]>box[XX][XX]-2*box_margin) ||
-          (x[YY]<2*box_margin) || (x[YY]>box[YY][YY]-2*box_margin) ||
-          (x[ZZ]<2*box_margin) || (x[ZZ]>box[ZZ][ZZ]-2*box_margin) );
+    return ( (x[XX] < 2*box_margin) || (x[XX] > box[XX][XX]-2*box_margin) ||
+             (x[YY] < 2*box_margin) || (x[YY] > box[YY][YY]-2*box_margin) ||
+             (x[ZZ] < 2*box_margin) || (x[ZZ] > box[ZZ][ZZ]-2*box_margin) );
 }
 
-static gmx_bool outside_box_plus_margin(rvec x,matrix box)
+static gmx_bool outside_box_plus_margin(rvec x, matrix box)
 {
-  return ( (x[XX]<-box_margin) || (x[XX]>box[XX][XX]+box_margin) ||
-          (x[YY]<-box_margin) || (x[YY]>box[YY][YY]+box_margin) ||
-          (x[ZZ]<-box_margin) || (x[ZZ]>box[ZZ][ZZ]+box_margin) );
+    return ( (x[XX] < -box_margin) || (x[XX] > box[XX][XX]+box_margin) ||
+             (x[YY] < -box_margin) || (x[YY] > box[YY][YY]+box_margin) ||
+             (x[ZZ] < -box_margin) || (x[ZZ] > box[ZZ][ZZ]+box_margin) );
 }
 
-static int mark_res(int at, gmx_bool *mark, int natoms, t_atom *atom,int *nmark)
+static int mark_res(int at, gmx_bool *mark, int natoms, t_atom *atom, int *nmark)
 {
-  int resind;
+    int resind;
 
-  resind = atom[at].resind;
-  while( (at > 0) && (resind==atom[at-1].resind) )
-    at--;
-  while( (at < natoms) && (resind==atom[at].resind) ) {
-    if (!mark[at]) {
-      mark[at]=TRUE;
-      (*nmark)++;
+    resind = atom[at].resind;
+    while ( (at > 0) && (resind == atom[at-1].resind) )
+    {
+        at--;
+    }
+    while ( (at < natoms) && (resind == atom[at].resind) )
+    {
+        if (!mark[at])
+        {
+            mark[at] = TRUE;
+            (*nmark)++;
+        }
+        at++;
     }
-    at++;
-  }
 
-  return at;
+    return at;
 }
 
-static real find_max_real(int n,real radius[])
+static real find_max_real(int n, real radius[])
 {
-  int  i;
-  real rmax;
-
-  rmax = 0;
-  if (n > 0) {
-    rmax = radius[0];
-    for(i=1; (i<n); i++)
-      rmax = max(rmax,radius[i]);
-  }
-  return rmax;
+    int  i;
+    real rmax;
+
+    rmax = 0;
+    if (n > 0)
+    {
+        rmax = radius[0];
+        for (i = 1; (i < n); i++)
+        {
+            rmax = max(rmax, radius[i]);
+        }
+    }
+    return rmax;
 }
 
-static void combine_atoms(t_atoms *ap,t_atoms *as,
-                         rvec xp[],rvec *vp,rvec xs[],rvec *vs,
-                         t_atoms **a_comb,rvec **x_comb,rvec **v_comb)
+static void combine_atoms(t_atoms *ap, t_atoms *as,
+                          rvec xp[], rvec *vp, rvec xs[], rvec *vs,
+                          t_atoms **a_comb, rvec **x_comb, rvec **v_comb)
 {
-  t_atoms *ac;
-  rvec    *xc,*vc=NULL;
-  int     i,j,natot,res0;
-
-  /* Total number of atoms */
-  natot = ap->nr+as->nr;
-
-  snew(ac,1);
-  init_t_atoms(ac,natot,FALSE);
-
-  snew(xc,natot);
-  if (vp && vs) snew(vc,natot);
-
-  /* Fill the new structures */
-  for(i=j=0; (i<ap->nr); i++,j++) {
-    copy_rvec(xp[i],xc[j]);
-    if (vc) copy_rvec(vp[i],vc[j]);
-    memcpy(&(ac->atom[j]),&(ap->atom[i]),sizeof(ap->atom[i]));
-    ac->atom[j].type = 0;
-  }
-  res0 = ap->nres;
-  for(i=0; (i<as->nr); i++,j++) {
-    copy_rvec(xs[i],xc[j]);
-    if (vc) copy_rvec(vs[i],vc[j]);
-    memcpy(&(ac->atom[j]),&(as->atom[i]),sizeof(as->atom[i]));
-    ac->atom[j].type    = 0;
-    ac->atom[j].resind += res0;
-  }
-  ac->nr   = j;
-  ac->nres = ac->atom[j-1].resind+1;
-  /* Fill all elements to prevent uninitialized memory */
-  for(i=0; i<ac->nr; i++) {
-    ac->atom[i].m     = 1;
-    ac->atom[i].q     = 0;
-    ac->atom[i].mB    = 1;
-    ac->atom[i].qB    = 0;
-    ac->atom[i].type  = 0;
-    ac->atom[i].typeB = 0;
-    ac->atom[i].ptype = eptAtom;
-  }
-
-  /* Return values */
-  *a_comb = ac;
-  *x_comb = xc;
-  *v_comb = vc;
+    t_atoms *ac;
+    rvec    *xc, *vc = NULL;
+    int      i, j, natot, res0;
+
+    /* Total number of atoms */
+    natot = ap->nr+as->nr;
+
+    snew(ac, 1);
+    init_t_atoms(ac, natot, FALSE);
+
+    snew(xc, natot);
+    if (vp && vs)
+    {
+        snew(vc, natot);
+    }
+
+    /* Fill the new structures */
+    for (i = j = 0; (i < ap->nr); i++, j++)
+    {
+        copy_rvec(xp[i], xc[j]);
+        if (vc)
+        {
+            copy_rvec(vp[i], vc[j]);
+        }
+        memcpy(&(ac->atom[j]), &(ap->atom[i]), sizeof(ap->atom[i]));
+        ac->atom[j].type = 0;
+    }
+    res0 = ap->nres;
+    for (i = 0; (i < as->nr); i++, j++)
+    {
+        copy_rvec(xs[i], xc[j]);
+        if (vc)
+        {
+            copy_rvec(vs[i], vc[j]);
+        }
+        memcpy(&(ac->atom[j]), &(as->atom[i]), sizeof(as->atom[i]));
+        ac->atom[j].type    = 0;
+        ac->atom[j].resind += res0;
+    }
+    ac->nr   = j;
+    ac->nres = ac->atom[j-1].resind+1;
+    /* Fill all elements to prevent uninitialized memory */
+    for (i = 0; i < ac->nr; i++)
+    {
+        ac->atom[i].m     = 1;
+        ac->atom[i].q     = 0;
+        ac->atom[i].mB    = 1;
+        ac->atom[i].qB    = 0;
+        ac->atom[i].type  = 0;
+        ac->atom[i].typeB = 0;
+        ac->atom[i].ptype = eptAtom;
+    }
+
+    /* Return values */
+    *a_comb = ac;
+    *x_comb = xc;
+    *v_comb = vc;
 }
 
-static t_forcerec *fr=NULL;
+static t_forcerec *fr = NULL;
 
-void do_nsgrid(FILE *fp,gmx_bool bVerbose,
-              matrix box,rvec x[],t_atoms *atoms,real rlong,
+void do_nsgrid(FILE *fp, gmx_bool bVerbose,
+               matrix box, rvec x[], t_atoms *atoms, real rlong,
                const output_env_t oenv)
 {
-  gmx_mtop_t *mtop;
-  gmx_localtop_t *top;
-  t_mdatoms  *md;
-  t_block    *cgs;
-  t_inputrec *ir;
-  t_nrnb     nrnb;
-  t_commrec  *cr;
-  int        *cg_index;
-  gmx_moltype_t *molt;
-  gmx_ffparams_t *ffp;
-  ivec       *nFreeze;
-  int        i,m,natoms;
-  rvec       box_size;
-  real       *lambda,*dvdl;
-
-  natoms = atoms->nr;
-
-  /* Charge group index */
-  snew(cg_index,natoms);
-  for(i=0; (i<natoms); i++)
-    cg_index[i]=i;
-
-  /* Topology needs charge groups and exclusions */
-  snew(mtop,1);
-  init_mtop(mtop);
-  mtop->natoms = natoms;
-  /* Make one moltype that contains the whol system */
-  mtop->nmoltype = 1;
-  snew(mtop->moltype,mtop->nmoltype);
-  molt = &mtop->moltype[0];
-  molt->name  = mtop->name;
-  molt->atoms = *atoms;
-  stupid_fill_block(&molt->cgs,mtop->natoms,FALSE);
-  stupid_fill_blocka(&molt->excls,natoms);
-  /* Make one molblock for the whole system */
-  mtop->nmolblock = 1;
-  snew(mtop->molblock,mtop->nmolblock);
-  mtop->molblock[0].type = 0;
-  mtop->molblock[0].nmol = 1;
-  mtop->molblock[0].natoms_mol = natoms;
-  /* Initialize a single energy group */
-  mtop->groups.grps[egcENER].nr = 1;
-  mtop->groups.ngrpnr[egcENER]  = 0;
-  mtop->groups.grpnr[egcENER]   = NULL;
-
-  ffp = &mtop->ffparams;
-
-  ffp->ntypes = 1;
-  ffp->atnr   = 1;
-  ffp->reppow = 12;
-  snew(ffp->functype,1);
-  snew(ffp->iparams,1);
-  ffp->iparams[0].lj.c6  = 1;
-  ffp->iparams[0].lj.c12 = 1;
-
-  /* inputrec structure */
-  snew(ir,1);
-  ir->coulombtype = eelCUT;
-  ir->vdwtype     = evdwCUT;
-  ir->ndelta      = 2;
-  ir->ns_type     = ensGRID;
-  snew(ir->opts.egp_flags,1);
-
-  top = gmx_mtop_generate_local_top(mtop,ir);
-
-  /* Some nasty shortcuts */
-  cgs  = &(top->cgs);
+    gmx_mtop_t     *mtop;
+    gmx_localtop_t *top;
+    t_mdatoms      *md;
+    t_block        *cgs;
+    t_inputrec     *ir;
+    t_nrnb          nrnb;
+    t_commrec      *cr;
+    int            *cg_index;
+    gmx_moltype_t  *molt;
+    gmx_ffparams_t *ffp;
+    ivec           *nFreeze;
+    int             i, m, natoms;
+    rvec            box_size;
+    real           *lambda, *dvdl;
+
+    natoms = atoms->nr;
+
+    /* Charge group index */
+    snew(cg_index, natoms);
+    for (i = 0; (i < natoms); i++)
+    {
+        cg_index[i] = i;
+    }
+
+    /* Topology needs charge groups and exclusions */
+    snew(mtop, 1);
+    init_mtop(mtop);
+    mtop->natoms = natoms;
+    /* Make one moltype that contains the whol system */
+    mtop->nmoltype = 1;
+    snew(mtop->moltype, mtop->nmoltype);
+    molt        = &mtop->moltype[0];
+    molt->name  = mtop->name;
+    molt->atoms = *atoms;
+    stupid_fill_block(&molt->cgs, mtop->natoms, FALSE);
+    stupid_fill_blocka(&molt->excls, natoms);
+    /* Make one molblock for the whole system */
+    mtop->nmolblock = 1;
+    snew(mtop->molblock, mtop->nmolblock);
+    mtop->molblock[0].type       = 0;
+    mtop->molblock[0].nmol       = 1;
+    mtop->molblock[0].natoms_mol = natoms;
+    /* Initialize a single energy group */
+    mtop->groups.grps[egcENER].nr = 1;
+    mtop->groups.ngrpnr[egcENER]  = 0;
+    mtop->groups.grpnr[egcENER]   = NULL;
+
+    ffp = &mtop->ffparams;
+
+    ffp->ntypes = 1;
+    ffp->atnr   = 1;
+    ffp->reppow = 12;
+    snew(ffp->functype, 1);
+    snew(ffp->iparams, 1);
+    ffp->iparams[0].lj.c6  = 1;
+    ffp->iparams[0].lj.c12 = 1;
+
+    /* inputrec structure */
+    snew(ir, 1);
+    ir->coulombtype = eelCUT;
+    ir->vdwtype     = evdwCUT;
+    ir->ndelta      = 2;
+    ir->ns_type     = ensGRID;
+    snew(ir->opts.egp_flags, 1);
+
+    top = gmx_mtop_generate_local_top(mtop, ir);
+
+    /* Some nasty shortcuts */
+    cgs  = &(top->cgs);
 
     /* mdatoms structure */
-  snew(nFreeze,2);
-  snew(md,1);
-  md = init_mdatoms(fp,mtop,FALSE);
-  atoms2md(mtop,ir,0,NULL,0,mtop->natoms,md);
-  sfree(nFreeze);
-
-  /* forcerec structure */
-  if (fr == NULL)
-    fr = mk_forcerec();
-  snew(cr,1);
-  cr->nnodes   = 1;
-  /* cr->nthreads = 1; */
-
-  /*    ir->rlist       = ir->rcoulomb = ir->rvdw = rlong;
-       printf("Neighborsearching with a cut-off of %g\n",rlong);
-       init_forcerec(stdout,fr,ir,top,cr,md,box,FALSE,NULL,NULL,NULL,TRUE);*/
-  fr->cg0 = 0;
-  fr->hcg = top->cgs.nr;
-  fr->nWatMol = 0;
-
-  /* Prepare for neighboursearching */
-  init_nrnb(&nrnb);
-
-  /* Init things dependent on parameters */
-  ir->rlistlong = ir->rlist = ir->rcoulomb = ir->rvdw = rlong;
-  /* create free energy data to avoid NULLs */
-  snew(ir->fepvals,1);
-  printf("Neighborsearching with a cut-off of %g\n",rlong);
-  init_forcerec(stdout,oenv,fr,NULL,ir,mtop,cr,box,FALSE,
-                NULL,NULL,NULL,NULL,NULL,TRUE,-1);
-  if (debug)
-    pr_forcerec(debug,fr,cr);
-
-  /* Calculate new stuff dependent on coords and box */
-  for(m=0; (m<DIM); m++)
-    box_size[m] = box[m][m];
-  calc_shifts(box,fr->shift_vec);
-  put_charge_groups_in_box(fp,0,cgs->nr,fr->ePBC,box,cgs,x,fr->cg_cm);
-
-  /* Do the actual neighboursearching */
-  snew(lambda,efptNR);
-  snew(dvdl,efptNR);
-  init_neighbor_list(fp,fr,md->homenr);
-  search_neighbours(fp,fr,x,box,top,
-                   &mtop->groups,cr,&nrnb,md,lambda,dvdl,NULL,TRUE,FALSE,FALSE);
-
-  if (debug)
-    dump_nblist(debug,cr,fr,0);
-
-  if (bVerbose)
-    fprintf(stderr,"Successfully made neighbourlist\n");
+    snew(nFreeze, 2);
+    snew(md, 1);
+    md = init_mdatoms(fp, mtop, FALSE);
+    atoms2md(mtop, ir, 0, NULL, 0, mtop->natoms, md);
+    sfree(nFreeze);
+
+    /* forcerec structure */
+    if (fr == NULL)
+    {
+        fr = mk_forcerec();
+    }
+    snew(cr, 1);
+    cr->nnodes   = 1;
+    /* cr->nthreads = 1; */
+
+    /*    ir->rlist       = ir->rcoulomb = ir->rvdw = rlong;
+       printf("Neighborsearching with a cut-off of %g\n",rlong);
+       init_forcerec(stdout,fr,ir,top,cr,md,box,FALSE,NULL,NULL,NULL,TRUE);*/
+    fr->cg0     = 0;
+    fr->hcg     = top->cgs.nr;
+    fr->nWatMol = 0;
+
+    /* Prepare for neighboursearching */
+    init_nrnb(&nrnb);
+
+    /* Init things dependent on parameters */
+    ir->rlistlong = ir->rlist = ir->rcoulomb = ir->rvdw = rlong;
+    /* create free energy data to avoid NULLs */
+    snew(ir->fepvals, 1);
+    printf("Neighborsearching with a cut-off of %g\n", rlong);
+    init_forcerec(stdout, oenv, fr, NULL, ir, mtop, cr, box, FALSE,
+                  NULL, NULL, NULL, NULL, NULL, TRUE, -1);
+    if (debug)
+    {
+        pr_forcerec(debug, fr, cr);
+    }
+
+    /* Calculate new stuff dependent on coords and box */
+    for (m = 0; (m < DIM); m++)
+    {
+        box_size[m] = box[m][m];
+    }
+    calc_shifts(box, fr->shift_vec);
+    put_charge_groups_in_box(fp, 0, cgs->nr, fr->ePBC, box, cgs, x, fr->cg_cm);
+
+    /* Do the actual neighboursearching */
+    snew(lambda, efptNR);
+    snew(dvdl, efptNR);
+    init_neighbor_list(fp, fr, md->homenr);
+    search_neighbours(fp, fr, x, box, top,
+                      &mtop->groups, cr, &nrnb, md, lambda, dvdl, NULL, TRUE, FALSE, FALSE);
+
+    if (debug)
+    {
+        dump_nblist(debug, cr, fr, 0);
+    }
+
+    if (bVerbose)
+    {
+        fprintf(stderr, "Successfully made neighbourlist\n");
+    }
 }
 
-gmx_bool bXor(gmx_bool b1,gmx_bool b2)
+gmx_bool bXor(gmx_bool b1, gmx_bool b2)
 {
-  return (b1 && !b2) || (b2 && !b1);
+    return (b1 && !b2) || (b2 && !b1);
 }
 
 void add_conf(t_atoms *atoms, rvec **x, rvec **v, real **r, gmx_bool bSrenew,
-             int ePBC, matrix box, gmx_bool bInsert,
-             t_atoms *atoms_solvt,rvec *x_solvt,rvec *v_solvt,real *r_solvt,
-             gmx_bool bVerbose,real rshell,int max_sol, const output_env_t oenv)
+              int ePBC, matrix box, gmx_bool bInsert,
+              t_atoms *atoms_solvt, rvec *x_solvt, rvec *v_solvt, real *r_solvt,
+              gmx_bool bVerbose, real rshell, int max_sol, const output_env_t oenv)
 {
-  t_nblist   *nlist;
-  t_atoms    *atoms_all;
-  real       max_vdw,*r_prot,*r_all,n2,r2,ib1,ib2;
-  int        natoms_prot,natoms_solvt;
-  int        i,j,jj,m,j0,j1,jjj,jnres,jnr,inr,iprot,is1,is2;
-  int        prev,resnr,nresadd,d,k,ncells,maxincell;
-  int        dx0,dx1,dy0,dy1,dz0,dz1;
-  int        ntest,nremove,nkeep;
-  rvec       dx,xi,xj,xpp,*x_all,*v_all;
-  gmx_bool       *remove,*keep;
-  int        bSolSol;
-
-  natoms_prot  = atoms->nr;
-  natoms_solvt = atoms_solvt->nr;
-  if (natoms_solvt <= 0) {
-    fprintf(stderr,"WARNING: Nothing to add\n");
-    return;
-  }
-
-  if (ePBC == epbcSCREW)
-    gmx_fatal(FARGS,"Sorry, %s pbc is not yet supported",epbc_names[ePBC]);
-
-  if (bVerbose)
-    fprintf(stderr,"Calculating Overlap...\n");
-
-  /* Set margin around box edges to largest solvent dimension.
-   * The maximum distance between atoms in a solvent molecule should
-   * be calculated. At the moment a fudge factor of 3 is used.
-   */
-  r_prot     = *r;
-  box_margin = 3*find_max_real(natoms_solvt,r_solvt);
-  max_vdw    = max(3*find_max_real(natoms_prot,r_prot),box_margin);
-  fprintf(stderr,"box_margin = %g\n",box_margin);
-
-  snew(remove,natoms_solvt);
-
-  nremove = 0;
-  if (!bInsert) {
-    for(i=0; i<atoms_solvt->nr; i++)
-      if ( outside_box_plus_margin(x_solvt[i],box) )
-       i=mark_res(i,remove,atoms_solvt->nr,atoms_solvt->atom,&nremove);
-    fprintf(stderr,"Removed %d atoms that were outside the box\n",nremove);
-  }
-
-  /* Define grid stuff for genbox */
-  /* Largest VDW radius */
-  snew(r_all,natoms_prot+natoms_solvt);
-  for(i=j=0; i<natoms_prot; i++,j++)
-    r_all[j]=r_prot[i];
-  for(i=0; i<natoms_solvt; i++,j++)
-    r_all[j]=r_solvt[i];
-
-  /* Combine arrays */
-  combine_atoms(atoms,atoms_solvt,*x,v?*v:NULL,x_solvt,v_solvt,
-               &atoms_all,&x_all,&v_all);
-
-  /* Do neighboursearching step */
-  do_nsgrid(stdout,bVerbose,box,x_all,atoms_all,max_vdw,oenv);
-
-  /* check solvent with solute */
-  nlist = &(fr->nblists[0].nlist_sr[eNL_VDW]);
-  fprintf(stderr,"nri = %d, nrj = %d\n",nlist->nri,nlist->nrj);
-  for(bSolSol=0; (bSolSol<=(bInsert ? 0 : 1)); bSolSol++) {
-    ntest = nremove = 0;
-    fprintf(stderr,"Checking %s-Solvent overlap:",
-           bSolSol ? "Solvent" : "Protein");
-    for(i=0; (i<nlist->nri && nremove<natoms_solvt); i++) {
-      inr = nlist->iinr[i];
-      j0  = nlist->jindex[i];
-      j1  = nlist->jindex[i+1];
-      rvec_add(x_all[inr],fr->shift_vec[nlist->shift[i]],xi);
-
-      for(j=j0; (j<j1 && nremove<natoms_solvt); j++) {
-       jnr = nlist->jjnr[j];
-       copy_rvec(x_all[jnr],xj);
-
-       /* Check solvent-protein and solvent-solvent */
-       is1 = inr-natoms_prot;
-       is2 = jnr-natoms_prot;
-
-       /* Check if at least one of the atoms is a solvent that is not yet
-        * listed for removal, and if both are solvent, that they are not in the
-        * same residue.
-        */
-       if ((!bSolSol &&
-            bXor((is1 >= 0),(is2 >= 0)) &&  /* One atom is protein */
-            ((is1 < 0) || ((is1 >= 0) && !remove[is1])) &&
-            ((is2 < 0) || ((is2 >= 0) && !remove[is2]))) ||
-
-           (bSolSol  &&
-            (is1 >= 0) && (!remove[is1]) &&   /* is1 is solvent */
-            (is2 >= 0) && (!remove[is2]) &&   /* is2 is solvent */
-            (bInsert || /* when inserting also check inside the box */
-             (outside_box_minus_margin2(x_solvt[is1],box) && /* is1 on edge */
-              outside_box_minus_margin2(x_solvt[is2],box))   /* is2 on edge */
-             ) &&
-            (atoms_solvt->atom[is1].resind !=  /* Not the same residue */
-             atoms_solvt->atom[is2].resind))) {
-
-         ntest++;
-         rvec_sub(xi,xj,dx);
-         n2 = norm2(dx);
-         r2 = sqr(r_all[inr]+r_all[jnr]);
-         if (n2 < r2) {
-           if (bInsert) {
-             nremove = natoms_solvt;
-             for(k=0; k<nremove; k++) {
-               remove[k] = TRUE;
-             }
-           }
-           /* Need only remove one of the solvents... */
-           if (is2 >= 0)
-             (void) mark_res(is2,remove,natoms_solvt,atoms_solvt->atom,
-                             &nremove);
-           else if (is1 >= 0)
-             (void) mark_res(is1,remove,natoms_solvt,atoms_solvt->atom,
-                             &nremove);
-           else
-             fprintf(stderr,"Neither atom is solvent%d %d\n",is1,is2);
-         }
-       }
-      }
-    }
-    if (!bInsert) {
-      fprintf(stderr," tested %d pairs, removed %d atoms.\n",ntest,nremove);
-    }
-  }
-  if (debug)
-    for(i=0; i<natoms_solvt; i++)
-      fprintf(debug,"remove[%5d] = %s\n",i,bool_names[remove[i]]);
-
-  /* Search again, now with another cut-off */
-  if (rshell > 0) {
-    do_nsgrid(stdout,bVerbose,box,x_all,atoms_all,rshell,oenv);
+    t_nblist       *nlist;
+    t_atoms        *atoms_all;
+    real            max_vdw, *r_prot, *r_all, n2, r2, ib1, ib2;
+    int             natoms_prot, natoms_solvt;
+    int             i, j, jj, m, j0, j1, jjj, jnres, jnr, inr, iprot, is1, is2;
+    int             prev, resnr, nresadd, d, k, ncells, maxincell;
+    int             dx0, dx1, dy0, dy1, dz0, dz1;
+    int             ntest, nremove, nkeep;
+    rvec            dx, xi, xj, xpp, *x_all, *v_all;
+    gmx_bool       *remove, *keep;
+    int             bSolSol;
+
+    natoms_prot  = atoms->nr;
+    natoms_solvt = atoms_solvt->nr;
+    if (natoms_solvt <= 0)
+    {
+        fprintf(stderr, "WARNING: Nothing to add\n");
+        return;
+    }
+
+    if (ePBC == epbcSCREW)
+    {
+        gmx_fatal(FARGS, "Sorry, %s pbc is not yet supported", epbc_names[ePBC]);
+    }
+
+    if (bVerbose)
+    {
+        fprintf(stderr, "Calculating Overlap...\n");
+    }
+
+    /* Set margin around box edges to largest solvent dimension.
+     * The maximum distance between atoms in a solvent molecule should
+     * be calculated. At the moment a fudge factor of 3 is used.
+     */
+    r_prot     = *r;
+    box_margin = 3*find_max_real(natoms_solvt, r_solvt);
+    max_vdw    = max(3*find_max_real(natoms_prot, r_prot), box_margin);
+    fprintf(stderr, "box_margin = %g\n", box_margin);
+
+    snew(remove, natoms_solvt);
+
+    nremove = 0;
+    if (!bInsert)
+    {
+        for (i = 0; i < atoms_solvt->nr; i++)
+        {
+            if (outside_box_plus_margin(x_solvt[i], box) )
+            {
+                i = mark_res(i, remove, atoms_solvt->nr, atoms_solvt->atom, &nremove);
+            }
+        }
+        fprintf(stderr, "Removed %d atoms that were outside the box\n", nremove);
+    }
+
+    /* Define grid stuff for genbox */
+    /* Largest VDW radius */
+    snew(r_all, natoms_prot+natoms_solvt);
+    for (i = j = 0; i < natoms_prot; i++, j++)
+    {
+        r_all[j] = r_prot[i];
+    }
+    for (i = 0; i < natoms_solvt; i++, j++)
+    {
+        r_all[j] = r_solvt[i];
+    }
+
+    /* Combine arrays */
+    combine_atoms(atoms, atoms_solvt, *x, v ? *v : NULL, x_solvt, v_solvt,
+                  &atoms_all, &x_all, &v_all);
+
+    /* Do neighboursearching step */
+    do_nsgrid(stdout, bVerbose, box, x_all, atoms_all, max_vdw, oenv);
+
+    /* check solvent with solute */
     nlist = &(fr->nblists[0].nlist_sr[eNL_VDW]);
-    fprintf(stderr,"nri = %d, nrj = %d\n",nlist->nri,nlist->nrj);
-    nkeep = 0;
-    snew(keep,natoms_solvt);
-    for(i=0; i<nlist->nri; i++) {
-      inr = nlist->iinr[i];
-      j0  = nlist->jindex[i];
-      j1  = nlist->jindex[i+1];
-
-      for(j=j0; j<j1; j++) {
-       jnr = nlist->jjnr[j];
-
-       /* Check solvent-protein and solvent-solvent */
-       is1 = inr-natoms_prot;
-       is2 = jnr-natoms_prot;
-
-       /* Check if at least one of the atoms is a solvent that is not yet
-        * listed for removal, and if both are solvent, that they are not in the
-        * same residue.
-        */
-       if (is1>=0 && is2<0)
-         mark_res(is1,keep,natoms_solvt,atoms_solvt->atom,&nkeep);
-       else if (is1<0 && is2>=0)
-         mark_res(is2,keep,natoms_solvt,atoms_solvt->atom,&nkeep);
-      }
-    }
-    fprintf(stderr,"Keeping %d solvent atoms after proximity check\n",
-           nkeep);
-    for (i=0; i<natoms_solvt; i++)
-      remove[i] = remove[i] || !keep[i];
-    sfree(keep);
-  }
-  /* count how many atoms and residues will be added and make space */
-  if (bInsert) {
-    j     = atoms_solvt->nr;
-    jnres = atoms_solvt->nres;
-  } else {
-    j     = 0;
-    jnres = 0;
-    for (i=0; ((i<atoms_solvt->nr) &&
-              ((max_sol == 0) || (jnres < max_sol))); i++) {
-      if (!remove[i]) {
-       j++;
-       if ((i == 0) ||
-           (atoms_solvt->atom[i].resind != atoms_solvt->atom[i-1].resind))
-         jnres++;
-      }
-    }
-  }
-  if (debug)
-    fprintf(debug,"Will add %d atoms in %d residues\n",j,jnres);
-  if (!bInsert) {
-    /* Flag the remaing solvent atoms to be removed */
-    jjj = atoms_solvt->atom[i-1].resind;
-    for ( ; (i<atoms_solvt->nr); i++) {
-      if (atoms_solvt->atom[i].resind > jjj)
-       remove[i] = TRUE;
-      else
-       j++;
-    }
-  }
-
-  if (bSrenew) {
-    srenew(atoms->resinfo,  atoms->nres+jnres);
-    srenew(atoms->atomname, atoms->nr+j);
-    srenew(atoms->atom,     atoms->nr+j);
-    srenew(*x,              atoms->nr+j);
-    if (v) srenew(*v,       atoms->nr+j);
-    srenew(*r,              atoms->nr+j);
-  }
-
-  /* add the selected atoms_solvt to atoms */
-  if (atoms->nr > 0) {
-    resnr = atoms->resinfo[atoms->atom[atoms->nr-1].resind].nr;
-  } else {
-    resnr = 0;
-  }
-  prev = -1;
-  nresadd = 0;
-  for (i=0; i<atoms_solvt->nr; i++) {
-    if (!remove[i]) {
-      if (prev == -1 ||
-         atoms_solvt->atom[i].resind != atoms_solvt->atom[prev].resind) {
-       nresadd ++;
-       atoms->nres++;
-       resnr++;
-       atoms->resinfo[atoms->nres-1] =
-         atoms_solvt->resinfo[atoms_solvt->atom[i].resind];
-       atoms->resinfo[atoms->nres-1].nr = resnr;
-       /* calculate shift of the solvent molecule using the first atom */
-       copy_rvec(x_solvt[i],dx);
-       put_atoms_in_box(ePBC,box,1,&dx);
-       rvec_dec(dx,x_solvt[i]);
-      }
-      atoms->atom[atoms->nr] = atoms_solvt->atom[i];
-      atoms->atomname[atoms->nr] = atoms_solvt->atomname[i];
-      rvec_add(x_solvt[i],dx,(*x)[atoms->nr]);
-      if (v) copy_rvec(v_solvt[i],(*v)[atoms->nr]);
-      (*r)[atoms->nr]   = r_solvt[i];
-      atoms->atom[atoms->nr].resind = atoms->nres-1;
-      atoms->nr++;
-      prev=i;
-    }
-  }
-  if (bSrenew)
-    srenew(atoms->resinfo,  atoms->nres+nresadd);
-
-  if (bVerbose)
-    fprintf(stderr,"Added %d molecules\n",nresadd);
-
-  sfree(remove);
-  done_atom(atoms_all);
-  sfree(x_all);
-  sfree(v_all);
+    fprintf(stderr, "nri = %d, nrj = %d\n", nlist->nri, nlist->nrj);
+    for (bSolSol = 0; (bSolSol <= (bInsert ? 0 : 1)); bSolSol++)
+    {
+        ntest = nremove = 0;
+        fprintf(stderr, "Checking %s-Solvent overlap:",
+                bSolSol ? "Solvent" : "Protein");
+        for (i = 0; (i < nlist->nri && nremove < natoms_solvt); i++)
+        {
+            inr = nlist->iinr[i];
+            j0  = nlist->jindex[i];
+            j1  = nlist->jindex[i+1];
+            rvec_add(x_all[inr], fr->shift_vec[nlist->shift[i]], xi);
+
+            for (j = j0; (j < j1 && nremove < natoms_solvt); j++)
+            {
+                jnr = nlist->jjnr[j];
+                copy_rvec(x_all[jnr], xj);
+
+                /* Check solvent-protein and solvent-solvent */
+                is1 = inr-natoms_prot;
+                is2 = jnr-natoms_prot;
+
+                /* Check if at least one of the atoms is a solvent that is not yet
+                 * listed for removal, and if both are solvent, that they are not in the
+                 * same residue.
+                 */
+                if ((!bSolSol &&
+                     bXor((is1 >= 0), (is2 >= 0)) && /* One atom is protein */
+                     ((is1 < 0) || ((is1 >= 0) && !remove[is1])) &&
+                     ((is2 < 0) || ((is2 >= 0) && !remove[is2]))) ||
+
+                    (bSolSol  &&
+                     (is1 >= 0) && (!remove[is1]) &&                   /* is1 is solvent */
+                     (is2 >= 0) && (!remove[is2]) &&                   /* is2 is solvent */
+                     (bInsert ||                                       /* when inserting also check inside the box */
+                      (outside_box_minus_margin2(x_solvt[is1], box) && /* is1 on edge */
+                       outside_box_minus_margin2(x_solvt[is2], box))   /* is2 on edge */
+                     ) &&
+                     (atoms_solvt->atom[is1].resind !=                 /* Not the same residue */
+                      atoms_solvt->atom[is2].resind)))
+                {
+
+                    ntest++;
+                    rvec_sub(xi, xj, dx);
+                    n2 = norm2(dx);
+                    r2 = sqr(r_all[inr]+r_all[jnr]);
+                    if (n2 < r2)
+                    {
+                        if (bInsert)
+                        {
+                            nremove = natoms_solvt;
+                            for (k = 0; k < nremove; k++)
+                            {
+                                remove[k] = TRUE;
+                            }
+                        }
+                        /* Need only remove one of the solvents... */
+                        if (is2 >= 0)
+                        {
+                            (void) mark_res(is2, remove, natoms_solvt, atoms_solvt->atom,
+                                            &nremove);
+                        }
+                        else if (is1 >= 0)
+                        {
+                            (void) mark_res(is1, remove, natoms_solvt, atoms_solvt->atom,
+                                            &nremove);
+                        }
+                        else
+                        {
+                            fprintf(stderr, "Neither atom is solvent%d %d\n", is1, is2);
+                        }
+                    }
+                }
+            }
+        }
+        if (!bInsert)
+        {
+            fprintf(stderr, " tested %d pairs, removed %d atoms.\n", ntest, nremove);
+        }
+    }
+    if (debug)
+    {
+        for (i = 0; i < natoms_solvt; i++)
+        {
+            fprintf(debug, "remove[%5d] = %s\n", i, bool_names[remove[i]]);
+        }
+    }
+
+    /* Search again, now with another cut-off */
+    if (rshell > 0)
+    {
+        do_nsgrid(stdout, bVerbose, box, x_all, atoms_all, rshell, oenv);
+        nlist = &(fr->nblists[0].nlist_sr[eNL_VDW]);
+        fprintf(stderr, "nri = %d, nrj = %d\n", nlist->nri, nlist->nrj);
+        nkeep = 0;
+        snew(keep, natoms_solvt);
+        for (i = 0; i < nlist->nri; i++)
+        {
+            inr = nlist->iinr[i];
+            j0  = nlist->jindex[i];
+            j1  = nlist->jindex[i+1];
+
+            for (j = j0; j < j1; j++)
+            {
+                jnr = nlist->jjnr[j];
+
+                /* Check solvent-protein and solvent-solvent */
+                is1 = inr-natoms_prot;
+                is2 = jnr-natoms_prot;
+
+                /* Check if at least one of the atoms is a solvent that is not yet
+                 * listed for removal, and if both are solvent, that they are not in the
+                 * same residue.
+                 */
+                if (is1 >= 0 && is2 < 0)
+                {
+                    mark_res(is1, keep, natoms_solvt, atoms_solvt->atom, &nkeep);
+                }
+                else if (is1 < 0 && is2 >= 0)
+                {
+                    mark_res(is2, keep, natoms_solvt, atoms_solvt->atom, &nkeep);
+                }
+            }
+        }
+        fprintf(stderr, "Keeping %d solvent atoms after proximity check\n",
+                nkeep);
+        for (i = 0; i < natoms_solvt; i++)
+        {
+            remove[i] = remove[i] || !keep[i];
+        }
+        sfree(keep);
+    }
+    /* count how many atoms and residues will be added and make space */
+    if (bInsert)
+    {
+        j     = atoms_solvt->nr;
+        jnres = atoms_solvt->nres;
+    }
+    else
+    {
+        j     = 0;
+        jnres = 0;
+        for (i = 0; ((i < atoms_solvt->nr) &&
+                     ((max_sol == 0) || (jnres < max_sol))); i++)
+        {
+            if (!remove[i])
+            {
+                j++;
+                if ((i == 0) ||
+                    (atoms_solvt->atom[i].resind != atoms_solvt->atom[i-1].resind))
+                {
+                    jnres++;
+                }
+            }
+        }
+    }
+    if (debug)
+    {
+        fprintf(debug, "Will add %d atoms in %d residues\n", j, jnres);
+    }
+    if (!bInsert)
+    {
+        /* Flag the remaing solvent atoms to be removed */
+        jjj = atoms_solvt->atom[i-1].resind;
+        for (; (i < atoms_solvt->nr); i++)
+        {
+            if (atoms_solvt->atom[i].resind > jjj)
+            {
+                remove[i] = TRUE;
+            }
+            else
+            {
+                j++;
+            }
+        }
+    }
+
+    if (bSrenew)
+    {
+        srenew(atoms->resinfo,  atoms->nres+jnres);
+        srenew(atoms->atomname, atoms->nr+j);
+        srenew(atoms->atom,     atoms->nr+j);
+        srenew(*x,              atoms->nr+j);
+        if (v)
+        {
+            srenew(*v,       atoms->nr+j);
+        }
+        srenew(*r,              atoms->nr+j);
+    }
+
+    /* add the selected atoms_solvt to atoms */
+    if (atoms->nr > 0)
+    {
+        resnr = atoms->resinfo[atoms->atom[atoms->nr-1].resind].nr;
+    }
+    else
+    {
+        resnr = 0;
+    }
+    prev    = -1;
+    nresadd = 0;
+    for (i = 0; i < atoms_solvt->nr; i++)
+    {
+        if (!remove[i])
+        {
+            if (prev == -1 ||
+                atoms_solvt->atom[i].resind != atoms_solvt->atom[prev].resind)
+            {
+                nresadd++;
+                atoms->nres++;
+                resnr++;
+                atoms->resinfo[atoms->nres-1] =
+                    atoms_solvt->resinfo[atoms_solvt->atom[i].resind];
+                atoms->resinfo[atoms->nres-1].nr = resnr;
+                /* calculate shift of the solvent molecule using the first atom */
+                copy_rvec(x_solvt[i], dx);
+                put_atoms_in_box(ePBC, box, 1, &dx);
+                rvec_dec(dx, x_solvt[i]);
+            }
+            atoms->atom[atoms->nr]     = atoms_solvt->atom[i];
+            atoms->atomname[atoms->nr] = atoms_solvt->atomname[i];
+            rvec_add(x_solvt[i], dx, (*x)[atoms->nr]);
+            if (v)
+            {
+                copy_rvec(v_solvt[i], (*v)[atoms->nr]);
+            }
+            (*r)[atoms->nr]               = r_solvt[i];
+            atoms->atom[atoms->nr].resind = atoms->nres-1;
+            atoms->nr++;
+            prev = i;
+        }
+    }
+    if (bSrenew)
+    {
+        srenew(atoms->resinfo,  atoms->nres+nresadd);
+    }
+
+    if (bVerbose)
+    {
+        fprintf(stderr, "Added %d molecules\n", nresadd);
+    }
+
+    sfree(remove);
+    done_atom(atoms_all);
+    sfree(x_all);
+    sfree(v_all);
 }