示例#1
0
文件: orires.c 项目: Chadi-akel/cere
void print_orires_log(FILE *log,t_fcdata *fcd)
{
  int           ex,i,j,nrot;
  bool          bZero;
  matrix        S,TMP;
  t_oriresdata  *od;
  static double **M=NULL,*eig,**v;
  
  od = &(fcd->orires);

  if (M == NULL) {
    snew(M,DIM);
    for(i=0; i<DIM; i++)
      snew(M[i],DIM);
    snew(eig,DIM);
    snew(v,DIM);
    for(i=0; i<DIM; i++)
      snew(v[i],DIM);
  }
  
  for(ex=0; ex<od->nex; ex++) {
    /* Rotate the S tensor back to the reference frame */
    mmul(od->R,od->S[ex],TMP);
    mtmul(TMP,od->R,S);
    for(i=0; i<DIM; i++)
      for(j=0; j<DIM; j++)
	M[i][j] = S[i][j];
    
    jacobi(M,DIM,eig,v,&nrot);

    j=0;
    for(i=1; i<DIM; i++)
      if (sqr(eig[i]) > sqr(eig[j]))
	j=i;
    
    fprintf(log,"  Orientation experiment %d:\n",ex+1);
    fprintf(log,"    order parameter: %g\n",eig[j]);
    for(i=0; i<DIM; i++)
      fprintf(log,"    eig: %6.3f   %6.3f %6.3f %6.3f\n",
	      (fabs(eig[j])>GMX_REAL_MIN) ? eig[i]/eig[j] : 0,v[XX][i],v[YY][i],v[ZZ][i]);
    fprintf(log,"\n");
  }
}
示例#2
0
文件: orires.c 项目: aar2163/GROMACS
void diagonalize_orires_tensors(t_oriresdata *od)
{
    int           ex,i,j,nrot,ord[DIM],t;
    matrix        S,TMP;
    static double **M=NULL,*eig,**v;
    
    if (M == NULL)
    {
        snew(M,DIM);
        for(i=0; i<DIM; i++)
        {
            snew(M[i],DIM);
        }
        snew(eig,DIM);
        snew(v,DIM);
        for(i=0; i<DIM; i++)
        {
            snew(v[i],DIM);
        }
    }

    for(ex=0; ex<od->nex; ex++)
    {
        /* Rotate the S tensor back to the reference frame */
        mmul(od->R,od->S[ex],TMP);
        mtmul(TMP,od->R,S);
        for(i=0; i<DIM; i++)
        {
            for(j=0; j<DIM; j++)
            {
                M[i][j] = S[i][j];
            }
        }
        
        jacobi(M,DIM,eig,v,&nrot);
        
        for(i=0; i<DIM; i++)
        {
            ord[i] = i;
        }
        for(i=0; i<DIM; i++)
        {
            for(j=i+1; j<DIM; j++)
            {
                if (sqr(eig[ord[j]]) > sqr(eig[ord[i]]))
                {
                    t = ord[i];
                    ord[i] = ord[j];
                    ord[j] = t;
                }
            }
        }
            
        for(i=0; i<DIM; i++)
        {
            od->eig[ex*12 + i] = eig[ord[i]];
        }
        for(i=0; i<DIM; i++)
        {
            for(j=0; j<DIM; j++)
            {
                od->eig[ex*12 + 3 + 3*i + j] = v[j][ord[i]];
            }
        }
    }
}
示例#3
0
void parrinellorahman_pcoupl(FILE *fplog,gmx_step_t step,
			     t_inputrec *ir,real dt,tensor pres,
			     tensor box,tensor box_rel,tensor boxv,
			     tensor M,matrix mu,bool bFirstStep)
{
  /* This doesn't do any coordinate updating. It just
   * integrates the box vector equations from the calculated
   * acceleration due to pressure difference. We also compute
   * the tensor M which is used in update to couple the particle
   * coordinates to the box vectors.
   *
   * In Nose and Klein (Mol.Phys 50 (1983) no 5., p 1055) this is
   * given as
   *            -1    .           .     -1
   * M_nk = (h')   * (h' * h + h' h) * h
   *
   * with the dots denoting time derivatives and h is the transformation from
   * the scaled frame to the real frame, i.e. the TRANSPOSE of the box. 
   * This also goes for the pressure and M tensors - they are transposed relative
   * to ours. Our equation thus becomes:
   *
   *                  -1       .    .           -1
   * M_gmx = M_nk' = b  * (b * b' + b * b') * b'
   * 
   * where b is the gromacs box matrix.                       
   * Our box accelerations are given by
   *   ..                                    ..
   *   b = vol/W inv(box') * (P-ref_P)     (=h')
   */
  
  int    d,n;
  tensor winv;
  real   vol=box[XX][XX]*box[YY][YY]*box[ZZ][ZZ];
  real   atot,arel,change,maxchange,xy_pressure;
  tensor invbox,pdiff,t1,t2;

  real maxl;

  m_inv_ur0(box,invbox);

  if (!bFirstStep) {
    /* Note that PRESFAC does not occur here.
     * The pressure and compressibility always occur as a product,
     * therefore the pressure unit drops out.
     */
    maxl=max(box[XX][XX],box[YY][YY]);
    maxl=max(maxl,box[ZZ][ZZ]);
    for(d=0;d<DIM;d++)
      for(n=0;n<DIM;n++)
	winv[d][n]=
	  (4*M_PI*M_PI*ir->compress[d][n])/(3*ir->tau_p*ir->tau_p*maxl);
    
    m_sub(pres,ir->ref_p,pdiff);
    
    if(ir->epct==epctSURFACETENSION) {
      /* Unlike Berendsen coupling it might not be trivial to include a z
       * pressure correction here? On the other hand we don't scale the
       * box momentarily, but change accelerations, so it might not be crucial.
       */
      xy_pressure=0.5*(pres[XX][XX]+pres[YY][YY]);
      for(d=0;d<ZZ;d++)
	pdiff[d][d]=(xy_pressure-(pres[ZZ][ZZ]-ir->ref_p[d][d]/box[d][d]));
    }
    
    tmmul(invbox,pdiff,t1);
    /* Move the off-diagonal elements of the 'force' to one side to ensure
     * that we obey the box constraints.
     */
    for(d=0;d<DIM;d++) {
      for(n=0;n<d;n++) {
	t1[d][n] += t1[n][d];
	t1[n][d] = 0;
      }
    }
    
    switch (ir->epct) {
    case epctANISOTROPIC:
      for(d=0;d<DIM;d++) 
	for(n=0;n<=d;n++)
	  t1[d][n] *= winv[d][n]*vol;
      break;
    case epctISOTROPIC:
      /* calculate total volume acceleration */
      atot=box[XX][XX]*box[YY][YY]*t1[ZZ][ZZ]+
	box[XX][XX]*t1[YY][YY]*box[ZZ][ZZ]+
	t1[XX][XX]*box[YY][YY]*box[ZZ][ZZ];
      arel=atot/(3*vol);
      /* set all RELATIVE box accelerations equal, and maintain total V
       * change speed */
      for(d=0;d<DIM;d++)
	for(n=0;n<=d;n++)
	  t1[d][n] = winv[0][0]*vol*arel*box[d][n];    
      break;
    case epctSEMIISOTROPIC:
    case epctSURFACETENSION:
      /* Note the correction to pdiff above for surftens. coupling  */
      
      /* calculate total XY volume acceleration */
      atot=box[XX][XX]*t1[YY][YY]+t1[XX][XX]*box[YY][YY];
      arel=atot/(2*box[XX][XX]*box[YY][YY]);
      /* set RELATIVE XY box accelerations equal, and maintain total V
       * change speed. Dont change the third box vector accelerations */
      for(d=0;d<ZZ;d++)
	for(n=0;n<=d;n++)
	  t1[d][n] = winv[d][n]*vol*arel*box[d][n];
      for(n=0;n<DIM;n++)
	t1[ZZ][n] *= winv[d][n]*vol;
      break;
    default:
      gmx_fatal(FARGS,"Parrinello-Rahman pressure coupling type %s "
		  "not supported yet\n",EPCOUPLTYPETYPE(ir->epct));
      break;
    }
    
    maxchange=0;
    for(d=0;d<DIM;d++)
      for(n=0;n<=d;n++) {
	boxv[d][n] += dt*t1[d][n];
	/* We do NOT update the box vectors themselves here, since
	 * we need them for shifting later. It is instead done last
	 * in the update() routine.
	 */
	
	/* Calculate the change relative to diagonal elements -
	 * since it's perfectly ok for the off-diagonal ones to
	 * be zero it doesn't make sense to check the change relative
	 * to its current size.
	 */
	change=fabs(dt*boxv[d][n]/box[d][d]);
	if(change>maxchange)
	  maxchange=change;
      }
    
    if (maxchange > 0.01 && fplog) {
      char buf[22];
      fprintf(fplog,"\nStep %s  Warning: Pressure scaling more than 1%%.\n",
	      gmx_step_str(step,buf));
    }
  }
  
  preserve_box_shape(ir,box_rel,boxv);

  mtmul(boxv,box,t1);       /* t1=boxv * b' */
  mmul(invbox,t1,t2);
  mtmul(t2,invbox,M);

  /* Determine the scaling matrix mu for the coordinates */
  for(d=0;d<DIM;d++)
    for(n=0;n<=d;n++)
      t1[d][n] = box[d][n] + dt*boxv[d][n];
  preserve_box_shape(ir,box_rel,t1);
  /* t1 is the box at t+dt, determine mu as the relative change */
  mmul_ur0(invbox,t1,mu);
}
示例#4
0
void diagonalize_orires_tensors(t_oriresdata *od)
{
    int           ex, i, j, nrot, ord[DIM], t;
    matrix        S, TMP;

    if (od->M == NULL)
    {
        snew(od->M, DIM);
        for (i = 0; i < DIM; i++)
        {
            snew(od->M[i], DIM);
        }
        snew(od->eig_diag, DIM);
        snew(od->v, DIM);
        for (i = 0; i < DIM; i++)
        {
            snew(od->v[i], DIM);
        }
    }

    for (ex = 0; ex < od->nex; ex++)
    {
        /* Rotate the S tensor back to the reference frame */
        mmul(od->R, od->S[ex], TMP);
        mtmul(TMP, od->R, S);
        for (i = 0; i < DIM; i++)
        {
            for (j = 0; j < DIM; j++)
            {
                od->M[i][j] = S[i][j];
            }
        }

        jacobi(od->M, DIM, od->eig_diag, od->v, &nrot);

        for (i = 0; i < DIM; i++)
        {
            ord[i] = i;
        }
        for (i = 0; i < DIM; i++)
        {
            for (j = i+1; j < DIM; j++)
            {
                if (gmx::square(od->eig_diag[ord[j]]) > gmx::square(od->eig_diag[ord[i]]))
                {
                    t      = ord[i];
                    ord[i] = ord[j];
                    ord[j] = t;
                }
            }
        }

        for (i = 0; i < DIM; i++)
        {
            od->eig[ex*12 + i] = od->eig_diag[ord[i]];
        }
        for (i = 0; i < DIM; i++)
        {
            for (j = 0; j < DIM; j++)
            {
                od->eig[ex*12 + 3 + 3*i + j] = od->v[j][ord[i]];
            }
        }
    }
}