Esempio n. 1
0
void calc_triclinic_images(matrix box,rvec img[])
{
    int i;

    /* Calculate 3 adjacent images in the xy-plane */
    copy_rvec(box[0],img[0]);
    copy_rvec(box[1],img[1]);
    if (img[1][XX] < 0)
        svmul(-1,img[1],img[1]);
    rvec_sub(img[1],img[0],img[2]);

    /* Get the next 3 in the xy-plane as mirror images */
    for(i=0; i<3; i++)
        svmul(-1,img[i],img[3+i]);

    /* Calculate the first 4 out of xy-plane images */
    copy_rvec(box[2],img[6]);
    if (img[6][XX] < 0)
        svmul(-1,img[6],img[6]);
    for(i=0; i<3; i++)
        rvec_add(img[6],img[i+1],img[7+i]);

    /* Mirror the last 4 from the previous in opposite rotation */
    for(i=0; i<4; i++)
        svmul(-1,img[6 + (2+i) % 4],img[10+i]);
}
Esempio n. 2
0
static void spread_dum3FAD(rvec xi,rvec xj,rvec xk,
                           rvec fi,rvec fj,rvec fk,rvec f,real a,real b)
{
    rvec xij,xjk,xperp,Fpij,Fppp,f1,f2,f3;
    real a1,b1,c1,c2,invdij,invdij2,invdp,fproj;
    int d;

    rvec_sub(xj,xi,xij);
    rvec_sub(xk,xj,xjk);
    /* 6 flops */

    invdij = invsqrt(iprod(xij,xij));
    invdij2 = invdij * invdij;
    c1 = iprod(xij,xjk) * invdij2;
    xperp[XX] = xjk[XX] - c1*xij[XX];
    xperp[YY] = xjk[YY] - c1*xij[YY];
    xperp[ZZ] = xjk[ZZ] - c1*xij[ZZ];
    /* xperp in plane ijk, perp. to ij */
    invdp = invsqrt(iprod(xperp,xperp));
    a1 = a*invdij;
    b1 = b*invdp;
    /* 45 flops */

    /* a1, b1 and c1 are already calculated in constr_dum3FAD
       storing them somewhere will save 45 flops!     */

    fproj=iprod(xij  ,f)*invdij2;
    svmul(fproj,                     xij,  Fpij); /* proj. f on xij */
    svmul(iprod(xperp,f)*invdp*invdp,xperp,Fppp); /* proj. f on xperp */
    svmul(b1*fproj,                  xperp,f3);
    /* 23 flops */

    rvec_sub(f,Fpij,f1);  /* f1 = f - Fpij */
    rvec_sub(f1,Fppp,f2); /* f2 = f - Fpij - Fppp */
    for (d=0; (d<DIM); d++) {
        f1[d]*=a1;
        f2[d]*=b1;
    }
    /* 12 flops */

    c2=1+c1;
    fi[XX] += f[XX] - f1[XX] + c1*f2[XX] + f3[XX];
    fi[YY] += f[YY] - f1[YY] + c1*f2[YY] + f3[YY];
    fi[ZZ] += f[ZZ] - f1[ZZ] + c1*f2[ZZ] + f3[ZZ];
    fj[XX] +=         f1[XX] - c2*f2[XX] - f3[XX];
    fj[YY] +=         f1[YY] - c2*f2[YY] - f3[YY];
    fj[ZZ] +=         f1[ZZ] - c2*f2[ZZ] - f3[ZZ];
    fk[XX] +=                     f2[XX];
    fk[YY] +=                     f2[YY];
    fk[ZZ] +=                     f2[ZZ];
    /* 30 Flops */

    /* TOTAL: 113 flops */
}
Esempio n. 3
0
static void calc_axes(rvec x[],t_atom atom[],int gnx[],atom_id *index[],
		      gmx_bool bRot,t_bundle *bun)
{
  int  end,i,div,d;
  real *mtot,m;
  rvec axis[MAX_ENDS],cent;
  
  snew(mtot,bun->n);

  for(end=0; end<bun->nend; end++) {
    for(i=0; i<bun->n; i++) {
      clear_rvec(bun->end[end][i]);
      mtot[i] = 0;
    }
    div = gnx[end]/bun->n;
    for(i=0; i<gnx[end]; i++) {
      m = atom[index[end][i]].m;
      for(d=0; d<DIM; d++)
	bun->end[end][i/div][d] += m*x[index[end][i]][d];
      mtot[i/div] += m;
    }
    clear_rvec(axis[end]);
    for(i=0; i<bun->n; i++) {
      svmul(1.0/mtot[i],bun->end[end][i],bun->end[end][i]);
      rvec_inc(axis[end],bun->end[end][i]);
    }
    svmul(1.0/bun->n,axis[end],axis[end]);
  }
  sfree(mtot);

  rvec_add(axis[0],axis[1],cent);
  svmul(0.5,cent,cent);
  /* center the bundle on the origin */
  for(end=0; end<bun->nend; end++) {
    rvec_dec(axis[end],cent);
    for(i=0; i<bun->n; i++)
      rvec_dec(bun->end[end][i],cent);
  }
  if (bRot) {
    /* rotate the axis parallel to the z-axis */
    rotate_ends(bun,axis[0],YY,ZZ);
    rotate_ends(bun,axis[0],XX,ZZ);
  }
  for(i=0; i<bun->n; i++) {
    rvec_add(bun->end[0][i],bun->end[1][i],bun->mid[i]);
    svmul(0.5,bun->mid[i],bun->mid[i]);
    rvec_sub(bun->end[0][i],bun->end[1][i],bun->dir[i]);
    bun->len[i] = norm(bun->dir[i]);
    unitv(bun->dir[i],bun->dir[i]);
  }
}
Esempio n. 4
0
static void calc_mj(t_topology top, int ePBC, matrix box, gmx_bool bNoJump, int isize, int index0[], \
                    rvec fr[], rvec mj, real mass2[], real qmol[])
{

    int   i, j, k, l;
    rvec  tmp;
    rvec  center;
    rvec  mt1, mt2;
    t_pbc pbc;


    calc_box_center(ecenterRECT, box, center);

    if (!bNoJump)
    {
        set_pbc(&pbc, ePBC, box);
    }

    clear_rvec(tmp);


    for (i = 0; i < isize; i++)
    {
        clear_rvec(mt1);
        clear_rvec(mt2);
        k = top.mols.index[index0[i]];
        l = top.mols.index[index0[i+1]];
        for (j = k; j < l; j++)
        {
            svmul(mass2[j], fr[j], tmp);
            rvec_inc(mt1, tmp);
        }

        if (bNoJump)
        {
            svmul(qmol[k], mt1, mt1);
        }
        else
        {
            pbc_dx(&pbc, mt1, center, mt2);
            svmul(qmol[k], mt2, mt1);
        }

        rvec_inc(mj, mt1);

    }

}
Esempio n. 5
0
static void average_data(rvec x[],rvec xav[],real *mass,
			 int ngrps,int isize[],atom_id **index)
{
  int  g,i,ind,d;
  real m,mtot;
  rvec tmp;
  double sum[DIM];

  for(g=0; g<ngrps; g++) {
    for(d=0; d<DIM; d++)
      sum[d] = 0;
    clear_rvec(xav[g]);
    mtot = 0;
    for(i=0; i<isize[g]; i++) {
      ind = index[g][i];
      if (mass) {
	m = mass[ind];
	svmul(m,x[ind],tmp);
	for(d=0; d<DIM; d++)
	  sum[d] += tmp[d];
	mtot += m;
      } else
	for(d=0; d<DIM; d++)
	  sum[d] += x[ind][d];
    }
    if (mass) {
      for(d=0; d<DIM; d++)
	xav[g][d] = sum[d]/mtot;
    } else {
      /* mass=NULL, so these are forces: sum only (do not average) */
      for(d=0; d<DIM; d++)
	xav[g][d] = sum[d];
    }
  }
}
Esempio n. 6
0
static void calc_comg(int is,int *coi,int *index,bool bMass,t_atom *atom,
		      rvec *x,rvec *x_comg)
{
  int  c,i,d;
  rvec xc;
  real mtot,m;

  if (bMass && atom==NULL)
    gmx_fatal(FARGS,"No masses available while mass weighting was requested");

  for(c=0; c<is; c++) {
    clear_rvec(xc);
    mtot = 0;
    for(i=coi[c]; i<coi[c+1]; i++) {
      if (bMass) {
	m = atom[index[i]].m;
	for(d=0; d<DIM; d++)
	  xc[d] += m*x[index[i]][d];
	mtot += m;
      } else {
	rvec_inc(xc,x[index[i]]);
	mtot += 1.0;
      }
    }
    svmul(1/mtot,xc,x_comg[c]);
  }
}
Esempio n. 7
0
void unitcell_d(rvec x[],rvec box,real odist)
{
  rvec cc[8] = {
    { 0,   0,         0 }, /* C1 */
    { cx, cy,       -cz }, /* C2 */
    { cx, cy+cy2,     0 }, /* C3 */
    { 0,  2*cy+cy2, -cz }, /* C4 */
    { 0,   0,         1 }, /* C5 */
    { cx, cy,      1+cz }, /* C6 */
    { cx, cy+cy2,     1 }, /* C7 */
    { 0,  2*cy+cy2,1+cz }, /* C8 */
  };
  rvec hh[4] = {
    { 0,   0,         1  }, /* H relative to C */
    { cx,  cy,       -cz },
    { cx, -cy,       -cz }, 
    {-cy2,  0,       -cz }
  };
  int  i,iin,iout,j,m;
  rvec tmp,t2,dip;
  
  clear_rvec(dip);
  for(i=0; (i<8); i++) {
    iin  = i;
    iout = i;
    svmul(odist,cc[iin],x[iout]);
  }  
  box[XX] = 2*cx;
  box[YY] = 2*(cy2+cy);
  box[ZZ] = 2*(1+cz);
  for(i=0; (i<DIM); i++)
    box[i] *= odist;
    
  printf("Unitcell:  %10.5f  %10.5f  %10.5f\n",box[XX],box[YY],box[ZZ]);
}
Esempio n. 8
0
static void decrease_step_size(int nshell,t_shell s[])
{
  int i;
  
  for(i=0; i<nshell; i++)
    svmul(0.8,s[i].step,s[i].step);
}
Esempio n. 9
0
void mc_pcoupl(FILE *fplog,gmx_step_t step,
		      t_inputrec *ir,real dt,tensor pres,matrix box,
		      matrix pcoupl_mu,gmx_mc_move *mc_move,t_block *mols,rvec *x,real *massA)
{
  int    natoms,m,n,d;
  real   vnew,vfrac;
  rvec  dxcm,dx;
  real  mass;
  char   *ptr,buf[STRLEN];

     vnew = det(box) + mc_move->delta_v;
     vfrac = pow(vnew,1.0/3.0)/pow(det(box),1.0/3.0);

     pcoupl_mu[XX][XX]=vfrac;    pcoupl_mu[XX][YY] = 0;          pcoupl_mu[XX][ZZ] = 0;
     pcoupl_mu[YY][XX]=0;        pcoupl_mu[YY][YY] = vfrac;      pcoupl_mu[YY][ZZ] = 0;
     pcoupl_mu[ZZ][XX]=0;        pcoupl_mu[ZZ][YY] = 0;          pcoupl_mu[ZZ][ZZ] = vfrac;

  for (n=0; n<mols->nr; n++) {
   clear_rvec(mc_move->xcm[n]);
   mass = 0;
   for(m=mols->index[n];m<mols->index[n+1];m++) {
    mass += massA[m];
    for (d=0;d<DIM;d++)
    {
     mc_move->xcm[n][d]+=x[m][d]*massA[m];   
    }
   }
   svmul(1.0/mass,mc_move->xcm[n],mc_move->xcm[n]);
 }
}
Esempio n. 10
0
/* Determine the (weighted) sum vector from positions x */
extern double get_sum_of_positions(rvec x[], real weight[], const int nat, dvec dsumvec)
{
    int i;
    rvec x_weighted;
    double weight_sum = 0.0;


    /* Zero out the center */
    clear_dvec(dsumvec);

    /* Loop over all atoms and add their weighted position vectors */
    if (weight != NULL)
    {
        for (i=0; i<nat; i++)
        {
            weight_sum += weight[i];
            svmul(weight[i], x[i], x_weighted);
            dsumvec[XX] += x_weighted[XX];
            dsumvec[YY] += x_weighted[YY];
            dsumvec[ZZ] += x_weighted[ZZ];
        }
    }
    else
    {
        for (i=0; i<nat; i++)
        {
            dsumvec[XX] += x[i][XX];
            dsumvec[YY] += x[i][YY];
            dsumvec[ZZ] += x[i][ZZ];
        }
    }
    return weight_sum;
}
Esempio n. 11
0
/*!
 * \param[in]  top   Topology structure with masses.
 * \param[in]  f     Forces on all atoms.
 * \param[in]  block t_block structure that divides \p index into blocks.
 * \param[in]  index Indices of atoms.
 * \param[out] fout  \p block->nr Forces on COG positions.
 */
void
gmx_calc_cog_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, const int index[],
                     rvec fout[])
{
    GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top),
                       "No masses available while mass weighting was requested");
    int molb = 0;
    for (int b = 0; b < block->nr; ++b)
    {
        rvec fb;
        clear_rvec(fb);
        real mtot = 0;
        for (int i = block->index[b]; i < block->index[b+1]; ++i)
        {
            const int  ai   = index[i];
            const real mass = mtopGetAtomMass(top, ai, &molb);
            for (int d = 0; d < DIM; ++d)
            {
                fb[d] += f[ai][d] / mass;
            }
            mtot += mass;
        }
        svmul(mtot / (block->index[b+1] - block->index[b]), fb, fout[b]);
    }
}
Esempio n. 12
0
void make_refgrps(t_pull *pull,matrix box,t_mdatoms *md) 
{
  int ngrps,i,ii,j,k,m;
  static bool bFirst = TRUE;
  real dr,mass;
  real truemass;
  rvec test;

  ngrps = pull->pull.n;
  if (bFirst) {
    snew(pull->dyna.ngx,ngrps);
    snew(pull->dyna.idx,ngrps);
    snew(pull->dyna.weights,ngrps);
    for (i=0;i<ngrps;i++) {
      snew(pull->dyna.idx[i],pull->ref.ngx[0]);    /* more than nessary */
      snew(pull->dyna.weights[i],pull->ref.ngx[0]);
    }      
    bFirst = FALSE;
  }

  /* loop over all groups to make a reference group for each*/
  for (i=0;i<ngrps;i++) {
    k=0;
    truemass=0;
    pull->dyna.tmass[i] = 0;
    pull->dyna.ngx[i] = 0;

    /* loop over all atoms in the main ref group */
    for (j=0;j<pull->ref.ngx[0];j++) {
      ii = pull->ref.idx[0][j];

      /* get_distance takes pbc into account */
      dr = get_cylinder_distance(pull->ref.x0[0][j],pull->pull.x_unc[i],box);

      if (dr < pull->rc) {
	/* add to index, to sum of COM, to weight array */
	mass = md->massT[ii];
	truemass += mass;
	pull->dyna.ngx[i]++;
	pull->dyna.weights[i][k] = get_weight(dr,pull->r,pull->rc);
	pull->dyna.idx[i][k] = ii;
	for (m=0;m<DIM;m++) 
	  pull->dyna.x_unc[i][m] += mass*pull->dyna.weights[i][k]*
	    pull->ref.x0[0][j][m];
	pull->dyna.tmass[i] += mass*pull->dyna.weights[i][k];
	k++;
      }
    }

    /* normalize the new 'x_unc' */
    svmul(1/pull->dyna.tmass[i],pull->dyna.x_unc[i],pull->dyna.x_unc[i]);
    if (pull->bVerbose) 
      fprintf(stderr,"Made group %d:%8.3f%8.3f%8.3f wm:%8.3f m:%8.3f\n",
	      i,pull->dyna.x_unc[i][0],pull->dyna.x_unc[i][1],
	      pull->dyna.x_unc[i][2],pull->dyna.tmass[i],truemass);
  }
}
Esempio n. 13
0
real calc_geom(int isize, atom_id *index, rvec *x, rvec geom_center, rvec min,
               rvec max, gmx_bool bDiam)
{
    real diam2, d;
    char *grpnames;
    int ii, i, j;

    clear_rvec(geom_center);
    diam2 = 0;
    if (isize == 0)
    {
        clear_rvec(min);
        clear_rvec(max);
    }
    else
    {
        if (index)
            ii = index[0];
        else
            ii = 0;
        for (j = 0; j < DIM; j++)
            min[j] = max[j] = x[ii][j];
        for (i = 0; i < isize; i++)
        {
            if (index)
                ii = index[i];
            else
                ii = i;
            rvec_inc(geom_center, x[ii]);
            for (j = 0; j < DIM; j++)
            {
                if (x[ii][j] < min[j])
                    min[j] = x[ii][j];
                if (x[ii][j] > max[j])
                    max[j] = x[ii][j];
            }
            if (bDiam)
            {
                if (index)
                    for (j = i + 1; j < isize; j++)
                    {
                        d = distance2(x[ii], x[index[j]]);
                        diam2 = max(d,diam2);
                    }
                else
                    for (j = i + 1; j < isize; j++)
                    {
                        d = distance2(x[i], x[j]);
                        diam2 = max(d,diam2);
                    }
            }
        }
        svmul(1.0 / isize, geom_center, geom_center);
    }

    return sqrt(diam2);
}
Esempio n. 14
0
void put_atoms_in_triclinic_unitcell(int ecenter, matrix box,
                                     int natoms, rvec x[])
{
    rvec   box_center, shift_center;
    real   shm01, shm02, shm12, shift;
    int    i, m, d;

    calc_box_center(ecenter, box, box_center);

    /* The product of matrix shm with a coordinate gives the shift vector
       which is required determine the periodic cell position */
    shm01 = box[1][0]/box[1][1];
    shm02 = (box[1][1]*box[2][0] - box[2][1]*box[1][0])/(box[1][1]*box[2][2]);
    shm12 = box[2][1]/box[2][2];

    clear_rvec(shift_center);
    for (d = 0; d < DIM; d++)
    {
        rvec_inc(shift_center, box[d]);
    }
    svmul(0.5, shift_center, shift_center);
    rvec_sub(box_center, shift_center, shift_center);

    shift_center[0] = shm01*shift_center[1] + shm02*shift_center[2];
    shift_center[1] = shm12*shift_center[2];
    shift_center[2] = 0;

    for (i = 0; (i < natoms); i++)
    {
        for (m = DIM-1; m >= 0; m--)
        {
            shift = shift_center[m];
            if (m == 0)
            {
                shift += shm01*x[i][1] + shm02*x[i][2];
            }
            else if (m == 1)
            {
                shift += shm12*x[i][2];
            }
            while (x[i][m]-shift < 0)
            {
                for (d = 0; d <= m; d++)
                {
                    x[i][d] += box[m][d];
                }
            }
            while (x[i][m]-shift >= box[m][m])
            {
                for (d = 0; d <= m; d++)
                {
                    x[i][d] -= box[m][d];
                }
            }
        }
    }
}
Esempio n. 15
0
static void calc_com_pbc(int nrefat, t_topology *top, rvec x[], t_pbc *pbc,
                         atom_id index[], rvec xref, int ePBC)
{
    const real tol = 1e-4;
    gmx_bool   bChanged;
    int        m, j, ai, iter;
    real       mass, mtot;
    rvec       dx, xtest;

    /* First simple calculation */
    clear_rvec(xref);
    mtot = 0;
    for (m = 0; (m < nrefat); m++)
    {
        ai   = index[m];
        mass = top->atoms.atom[ai].m;
        for (j = 0; (j < DIM); j++)
        {
            xref[j] += mass*x[ai][j];
        }
        mtot += mass;
    }
    svmul(1/mtot, xref, xref);
    /* Now check if any atom is more than half the box from the COM */
    if (ePBC != epbcNONE)
    {
        iter = 0;
        do
        {
            bChanged = FALSE;
            for (m = 0; (m < nrefat); m++)
            {
                ai   = index[m];
                mass = top->atoms.atom[ai].m/mtot;
                pbc_dx(pbc, x[ai], xref, dx);
                rvec_add(xref, dx, xtest);
                for (j = 0; (j < DIM); j++)
                {
                    if (std::abs(xtest[j]-x[ai][j]) > tol)
                    {
                        /* Here we have used the wrong image for contributing to the COM */
                        xref[j] += mass*(xtest[j]-x[ai][j]);
                        x[ai][j] = xtest[j];
                        bChanged = TRUE;
                    }
                }
            }
            if (bChanged)
            {
                printf("COM: %8.3f  %8.3f  %8.3f  iter = %d\n", xref[XX], xref[YY], xref[ZZ], iter);
            }
            iter++;
        }
        while (bChanged);
    }
}
Esempio n. 16
0
PyObject *apply_rotation( PyObject *self, PyObject *args)
{
  PyObject *Rotation;
  PyObject *py_v;
  real phi;
  if(!PyArg_ParseTuple(args,"OOd",&Rotation,&py_v, &phi))
    return NULL;

  PyObject *rm1 = PyObject_GetAttrString(Rotation,"m1");
  PyObject *rm2 = PyObject_GetAttrString(Rotation,"m2");

  matrix m1, m2;
  PyObject2matrix(rm1, m1);
  PyObject2matrix(rm2, m2);
  rvec v, v2;

  PyObject *py_v2 = PyObject_GetAttrString(Rotation,"v2");

  Pyvec2rvec(py_v, v);
  Pyvec2rvec(py_v2, v2);

  rvec vec;
  rvec_sub(v, v2, vec );

  rvec b, d, a, c, e;
  mvmul(m1, vec, b);
  mvmul(m2, vec, d);
  real cc = cos(phi);
  svmul( cc, vec, a);
  svmul( -cc, b, c);
  svmul( sin(phi), d, e);

  clear_rvec( vec );
  rvec_add( a, b, vec);
  rvec_add( vec, c, vec );
  rvec_add( vec, e, vec );
  
  clear_rvec(v);
  rvec_add( v2, vec, v);
  return Py_BuildValue("[ddd]", v[XX], v[YY], v[ZZ] );
 }
Esempio n. 17
0
static void scale_velocities(t_state *state, real fac)
{
    int i;

    if (as_rvec_array(state->v.data()))
    {
        for (i = 0; i < state->natoms; i++)
        {
            svmul(fac, state->v[i], state->v[i]);
        }
    }
}
Esempio n. 18
0
static void scale_velocities(t_state *state, real fac)
{
    int i;

    if (state->v)
    {
        for (i = 0; i < state->natoms; i++)
        {
            svmul(fac, state->v[i], state->v[i]);
        }
    }
}
Esempio n. 19
0
//! Helper method to calculate a vector from two or three positions.
static void
calc_vec(int natoms, rvec x[], t_pbc *pbc, rvec xout, rvec cout)
{
    switch (natoms)
    {
        case 2:
            if (pbc)
            {
                pbc_dx(pbc, x[1], x[0], xout);
            }
            else
            {
                rvec_sub(x[1], x[0], xout);
            }
            svmul(0.5, xout, cout);
            rvec_add(x[0], cout, cout);
            break;
        case 3:
        {
            rvec v1, v2;
            if (pbc)
            {
                pbc_dx(pbc, x[1], x[0], v1);
                pbc_dx(pbc, x[2], x[0], v2);
            }
            else
            {
                rvec_sub(x[1], x[0], v1);
                rvec_sub(x[2], x[0], v2);
            }
            cprod(v1, v2, xout);
            rvec_add(x[0], x[1], cout);
            rvec_add(cout, x[2], cout);
            svmul(1.0/3.0, cout, cout);
            break;
        }
        default:
            GMX_RELEASE_ASSERT(false, "Incorrectly initialized number of atoms");
    }
}
Esempio n. 20
0
/*!
 * \param[in]  top    Topology structure with masses.
 * \param[in]  x      Position vectors of all atoms.
 * \param[in]  pbc    Periodic boundary conditions structure.
 * \param[in]  nrefat Number of atoms in the index.
 * \param[in]  index  Indices of atoms.
 * \param[out] xout   COM position for the indexed atoms.
 *
 * Works as gmx_calc_com(), but takes into account periodic boundary
 * conditions: If any atom is more than half the box from the COM,
 * it is wrapped around and a new COM is calculated. This is repeated
 * until no atoms violate the condition.
 *
 * Modified from src/tools/gmx_sorient.c in Gromacs distribution.
 */
void
gmx_calc_com_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc,
                 int nrefat, const int index[], rvec xout)
{
    GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top),
                       "No masses available while mass weighting was requested");
    /* First simple calculation */
    clear_rvec(xout);
    real mtot = 0;
    int  molb = 0;
    for (int m = 0; m < nrefat; ++m)
    {
        const int  ai   = index[m];
        const real mass = mtopGetAtomMass(top, ai, &molb);
        for (int j = 0; j < DIM; ++j)
        {
            xout[j] += mass * x[ai][j];
        }
        mtot += mass;
    }
    svmul(1.0/mtot, xout, xout);
    /* Now check if any atom is more than half the box from the COM */
    if (pbc)
    {
        const real tol  = 1e-4;
        bool       bChanged;
        do
        {
            bChanged = false;
            molb     = 0;
            for (int m = 0; m < nrefat; ++m)
            {
                rvec       dx, xtest;
                const int  ai   = index[m];
                const real mass = mtopGetAtomMass(top, ai, &molb) / mtot;
                pbc_dx(pbc, x[ai], xout, dx);
                rvec_add(xout, dx, xtest);
                for (int j = 0; j < DIM; ++j)
                {
                    if (fabs(xtest[j] - x[ai][j]) > tol)
                    {
                        /* Here we have used the wrong image for contributing to the COM */
                        xout[j] += mass * (xtest[j] - x[ai][j]);
                        x[ai][j] = xtest[j];
                        bChanged = true;
                    }
                }
            }
        }
        while (bChanged);
    }
}
Esempio n. 21
0
void matrix_convert(matrix box, const rvec vec, const rvec angleInDegrees)
{
    rvec angle;
    svmul(DEG2RAD, angleInDegrees, angle);
    box[XX][XX] = vec[XX];
    box[YY][XX] = vec[YY]*cos(angle[ZZ]);
    box[YY][YY] = vec[YY]*sin(angle[ZZ]);
    box[ZZ][XX] = vec[ZZ]*cos(angle[YY]);
    box[ZZ][YY] = vec[ZZ]
        *(cos(angle[XX])-cos(angle[YY])*cos(angle[ZZ]))/sin(angle[ZZ]);
    box[ZZ][ZZ] = sqrt(gmx::square(vec[ZZ])
                       -box[ZZ][XX]*box[ZZ][XX]-box[ZZ][YY]*box[ZZ][YY]);
}
Esempio n. 22
0
static void calc_ringh(rvec xattach, rvec xb, rvec xc, rvec xh)
{
    rvec tab, tac;
    real n;

    /* Add a proton on a ring to atom attach at distance 0.1 nm */
    rvec_sub(xattach, xb, tab);
    rvec_sub(xattach, xc, tac);
    rvec_add(tab, tac, xh);
    n = 0.1/norm(xh);
    svmul(n, xh, xh);
    rvec_inc(xh, xattach);
}
Esempio n. 23
0
void
gmx_calc_cog(const gmx_mtop_t * /* top */, rvec x[], int nrefat, const int index[], rvec xout)
{
    int                 m, ai;

    clear_rvec(xout);
    for (m = 0; m < nrefat; ++m)
    {
        ai = index[m];
        rvec_inc(xout, x[ai]);
    }
    svmul(1.0/nrefat, xout, xout);
}
Esempio n. 24
0
void rm_res_pbc(t_atoms *atoms, rvec *x, matrix box)
{
    int  i, start, n, d, nat;
    rvec xcg;

    start = 0;
    nat   = 0;
    clear_rvec(xcg);
    for (n = 0; n < atoms->nr; n++)
    {
        if (!is_hydrogen(*(atoms->atomname[n])))
        {
            nat++;
            rvec_inc(xcg, x[n]);
        }
        if ( (n+1 == atoms->nr) ||
             (atoms->atom[n+1].resind != atoms->atom[n].resind) )
        {
            /* if nat==0 we have only hydrogens in the solvent,
               we take last coordinate as cg */
            if (nat == 0)
            {
                nat = 1;
                copy_rvec(x[n], xcg);
            }
            svmul(1.0/nat, xcg, xcg);
            for (d = 0; d < DIM; d++)
            {
                while (xcg[d] < 0)
                {
                    for (i = start; i <= n; i++)
                    {
                        x[i][d] += box[d][d];
                    }
                    xcg[d] += box[d][d];
                }
                while (xcg[d] >= box[d][d])
                {
                    for (i = start; i <= n; i++)
                    {
                        x[i][d] -= box[d][d];
                    }
                    xcg[d] -= box[d][d];
                }
            }
            start = n+1;
            nat   = 0;
            clear_rvec(xcg);
        }
    }
}
Esempio n. 25
0
static void center_molecule(int atomCount, rvec x[])
{
    rvec center;
    clear_rvec(center);
    for (int i = 0; i < atomCount; ++i)
    {
        rvec_inc(center, x[i]);
    }
    svmul(1.0/atomCount, center, center);
    for (int i = 0; i < atomCount; ++i)
    {
        rvec_dec(x[i], center);
    }
}
Esempio n. 26
0
static void
calc_vec(int natoms, rvec x[], t_pbc *pbc, rvec xout, rvec cout)
{
    switch (natoms)
    {
        case 2:
            if (pbc)
            {
                pbc_dx(pbc, x[1], x[0], xout);
            }
            else
            {
                rvec_sub(x[1], x[0], xout);
            }
            svmul(0.5, xout, cout);
            rvec_add(x[0], cout, cout);
            break;
        case 3: {
            rvec v1, v2;
            if (pbc)
            {
                pbc_dx(pbc, x[1], x[0], v1);
                pbc_dx(pbc, x[2], x[0], v2);
            }
            else
            {
                rvec_sub(x[1], x[0], v1);
                rvec_sub(x[2], x[0], v2);
            }
            cprod(v1, v2, xout);
            rvec_add(x[0], x[1], cout);
            rvec_add(cout, x[2], cout);
            svmul(1.0/3.0, cout, cout);
            break;
        }
    }
}
Esempio n. 27
0
void
gmx_calc_cog_block(const gmx_mtop_t * /* top */, rvec x[], const t_block *block, const int index[],
                   rvec xout[])
{
    int                 b, i, ai;
    rvec                xb;

    for (b = 0; b < block->nr; ++b)
    {
        clear_rvec(xb);
        for (i = block->index[b]; i < block->index[b+1]; ++i)
        {
            ai = index[i];
            rvec_inc(xb, x[ai]);
        }
        svmul(1.0/(block->index[b+1] - block->index[b]), xb, xout[b]);
    }
}
Esempio n. 28
0
void init_resize(t_block *ins_at,rvec *r_ins,pos_ins_t *pos_ins,mem_t *mem_p,rvec *r, gmx_bool bALLOW_ASYMMETRY)
{
	int i,j,at,c,outsidesum,gctr=0;
    int idxsum=0;

    /*sanity check*/
    for (i=0;i<pos_ins->pieces;i++)
          idxsum+=pos_ins->nidx[i];
    if (idxsum!=ins_at->nr)
          gmx_fatal(FARGS,"Piecewise sum of inserted atoms not same as size of group selected to insert.");

    snew(pos_ins->geom_cent,pos_ins->pieces);
    for (i=0;i<pos_ins->pieces;i++)
    {
    	c=0;
    	outsidesum=0;
    	for(j=0;j<DIM;j++)
    		pos_ins->geom_cent[i][j]=0;

    	for(j=0;j<DIM;j++)
    		pos_ins->geom_cent[i][j]=0;
    	for (j=0;j<pos_ins->nidx[i];j++)
    	{
    		at=pos_ins->subindex[i][j];
    		copy_rvec(r[at],r_ins[gctr]);
    		if( (r_ins[gctr][ZZ]<mem_p->zmax) && (r_ins[gctr][ZZ]>mem_p->zmin) )
    		{
    			rvec_inc(pos_ins->geom_cent[i],r_ins[gctr]);
    			c++;
    		}
    		else
    			outsidesum++;
    		gctr++;
    	}
    	if (c>0)
    		svmul(1/(double)c,pos_ins->geom_cent[i],pos_ins->geom_cent[i]);
    	if (!bALLOW_ASYMMETRY)
    		pos_ins->geom_cent[i][ZZ]=mem_p->zmed;

    	fprintf(stderr,"Embedding piece %d with center of geometry: %f %f %f\n",i,pos_ins->geom_cent[i][XX],pos_ins->geom_cent[i][YY],pos_ins->geom_cent[i][ZZ]);
    }
    fprintf(stderr,"\n");
}
Esempio n. 29
0
/*!
 * \param[in]  top    Topology structure with masses.
 * \param[in]  x      Position vectors of all atoms.
 * \param[in]  nrefat Number of atoms in the index.
 * \param[in]  index  Indices of atoms.
 * \param[out] xout   COM position for the indexed atoms.
 *
 * Works exactly as gmx_calc_cog() with the exception that a center of
 * mass are calculated, and hence a topology with masses is required.
 */
void
gmx_calc_com(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], rvec xout)
{
    GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top),
                       "No masses available while mass weighting was requested");
    clear_rvec(xout);
    real mtot = 0;
    int  molb = 0;
    for (int m = 0; m < nrefat; ++m)
    {
        const int  ai   = index[m];
        const real mass = mtopGetAtomMass(top, ai, &molb);
        for (int j = 0; j < DIM; ++j)
        {
            xout[j] += mass * x[ai][j];
        }
        mtot += mass;
    }
    svmul(1.0/mtot, xout, xout);
}
Esempio n. 30
0
/* calculate the com of molecules in x and put it into xa */
static void calc_mol_com(int nmol,int *molindex,t_block *mols,t_atoms *atoms,
			 rvec *x,rvec *xa)
{
  int  m,mol,i,d;
  rvec xm;
  real mass,mtot;

  for(m=0; m<nmol; m++) {
    mol = molindex[m];
    clear_rvec(xm);
    mtot = 0;
    for(i=mols->index[mol]; i<mols->index[mol+1]; i++) {
      mass = atoms->atom[i].m;
      for(d=0; d<DIM; d++)
	xm[d] += mass*x[i][d];
      mtot += mass;
    }
    svmul(1/mtot,xm,xa[m]);
  }
}